1 |
// Smersh |
2 |
// |
3 |
// Douglas Thrift |
4 |
// |
5 |
// $Id$ |
6 |
|
7 |
#include "Redirector.hpp" |
8 |
|
9 |
int Redirector::handle(Client* client) |
10 |
{ |
11 |
ios::ToIoStream sio(&client->socket, &client->socket); |
12 |
Environment env; |
13 |
stringstream post; |
14 |
ostringstream log; |
15 |
Status code(request(sio, env, post, log)); |
16 |
|
17 |
if (code == ok) code = env.get("REQUEST_METHOD") != "POST" ? found : |
18 |
seeOther; |
19 |
|
20 |
response(sio, code); |
21 |
|
22 |
bool head(env.get("REQUEST_METHOD") == "HEAD"); |
23 |
streamsize sent(0); |
24 |
|
25 |
if (code == found || code == seeOther) |
26 |
{ |
27 |
string location(redirect + '?' + query(post, env)); |
28 |
|
29 |
sio << "Location: " << location << crlf; |
30 |
|
31 |
if (!head) |
32 |
{ |
33 |
string reason(this->reason(code)); |
34 |
ostringstream content; |
35 |
|
36 |
content << "<html><head><title>" << code << ' ' << reason << "</tit" |
37 |
<< "le></head><body><h1>" << reason << "</h1><p>Don't come here" |
38 |
<< ", go <a href=\"" << location << "\">there</a>.</p><hr /><ad" |
39 |
<< "dress>" << server(env) << "</address></body></html>\r\n"; |
40 |
sio << "Content-Length: " << content.str().length() << crlf |
41 |
<< "Content-Type: text/html; charset=UTF-8\r\n\r\n"; |
42 |
|
43 |
sio.write(content.str().data(), content.str().size()); |
44 |
|
45 |
sent = content.str().size(); |
46 |
} |
47 |
else sio << "Content-Type: text/html; charset=UTF-8\r\n\r\n"; |
48 |
} |
49 |
else if (head) sio << "Content-Type: text/html; charset=UTF-8\r\n\r\n"; |
50 |
else sent = error(sio, code, env); |
51 |
|
52 |
ofstream fout(this->log.c_str(), ios_base::app); |
53 |
|
54 |
fout << inet_ntoa(client->ip->sin_addr) << " - - " << date(true) << ' ' |
55 |
<< log.str() << code << ' ' << lexical_cast<string>(sent) << " \"" |
56 |
<< env.get("HTTP_REFERER") << "\" \"" << env.get("HTTP_USER_AGENT") |
57 |
<< "\"\n"; |
58 |
sio << flush; |
59 |
|
60 |
client->socket.ShutdownWrite(); |
61 |
|
62 |
delete client; |
63 |
|
64 |
return 0; |
65 |
} |
66 |
|
67 |
string Redirector::query(const stringstream& post, const Environment& env) |
68 |
{ |
69 |
string query(env.get("REQUEST_METHOD") != "POST" ? env.get("QUERY_STRING") : |
70 |
post.str()); |
71 |
|
72 |
for (string::size_type index(0); index < query.length(); ++index) |
73 |
{ |
74 |
if (isspace(query[index])) query.replace(index, 1, 1, '+'); |
75 |
} |
76 |
|
77 |
if (Smersh::debug) cerr << "query = " << query << '\n'; |
78 |
|
79 |
return query; |
80 |
} |