// Smersh // // Douglas Thrift // // $Id$ #include "Redirector.hpp" int Redirector::handle(Client* client) { ios::ToIoStream sio(&client->socket, &client->socket); Environment env; stringstream post; ostringstream log; Status code(request(sio, env, post, log)); if (code == ok) code = env.get("REQUEST_METHOD") != "POST" ? found : seeOther; response(sio, code); bool head(env.get("REQUEST_METHOD") == "HEAD"); streamsize sent(0); if (code == found || code == seeOther) { string location(redirect + '?' + query(post, env)); sio << "Location: " << location << crlf; if (!head) { string reason(this->reason(code)); ostringstream content; content << "" << code << ' ' << reason << "</tit" << "le></head><body><h1>" << reason << "</h1><p>Don't come here" << ", go <a href=\"" << location << "\">there</a>.</p><hr /><ad" << "dress>" << server(env) << "</address></body></html>\r\n"; sio << "Content-Length: " << content.str().length() << crlf << "Content-Type: text/html; charset=UTF-8\r\n\r\n"; sio.write(content.str().data(), content.str().size()); sent = content.str().size(); } else sio << "Content-Type: text/html; charset=UTF-8\r\n\r\n"; } else if (head) sio << "Content-Type: text/html; charset=UTF-8\r\n\r\n"; else sent = error(sio, code, env); ofstream fout(this->log.c_str(), ios_base::app); fout << inet_ntoa(client->ip->sin_addr) << " - - " << date(true) << ' ' << log.str() << code << ' ' << lexical_cast<string>(sent) << " \"" << env.get("HTTP_REFERER") << "\" \"" << env.get("HTTP_USER_AGENT") << "\"\n"; sio << flush; client->socket.ShutdownWrite(); delete client; return 0; } string Redirector::query(const stringstream& post, const Environment& env) { string query(env.get("REQUEST_METHOD") != "POST" ? env.get("QUERY_STRING") : post.str()); for (string::size_type index(0); index < query.length(); ++index) { if (isspace(query[index])) query.replace(index, 1, 1, '+'); } if (debug) cerr << "query = " << query << '\n'; return query; }