--- Smersh/Daemon.cpp 2004/06/26 08:26:41 177
+++ Smersh/Daemon.cpp 2004/09/12 03:59:56 241
@@ -4,22 +4,19 @@
//
// $Id$
-#include
-
#include "Daemon.hpp"
string Daemon::crlf("\r\n");
-void Daemon::serve(int port, bool fork, Daemon* self)
+void Daemon::serve(bool fork, Daemon* self)
{
api::TcpSocket server;
- server.Create();
server.SetAddress(api::InternetAddress(api::InternetAddress::Any, port));
if (fork)
{
- switch (::fork())
+ switch (pid_t pid = ::fork())
{
case -1:
cerr << program << ": fork()\n";
@@ -28,6 +25,7 @@ void Daemon::serve(int port, bool fork,
case 0:
break;
default:
+ cout << pid << '\n';
return;
}
}
@@ -36,10 +34,7 @@ void Daemon::serve(int port, bool fork,
while (true)
{
- api::TcpSocket* client(new api::TcpSocket());
-
- server.Accept(*client);
-
+ Client* client (new Client(server));
api::Thread thread(etl::BindAll(&Daemon::handle, self, client));
}
}
@@ -48,7 +43,7 @@ Daemon::Status Daemon::request(istream&
ostream& log)
{
string line;
- Matcher request("^([A-Z]+) .*?(\\?.+)? HTTP/(\\d+)\\.(\\d+)$");
+ Matcher request("^([A-Z]+) (.*?)(\\?.+)? HTTP/(\\d+)\\.(\\d+)$");
getline(sin, line);
@@ -59,41 +54,104 @@ Daemon::Status Daemon::request(istream&
if (line == request)
{
- if (lexical_cast(request[3]) > 1) return version;
+ if (lexical_cast(request[4]) > 1) return version;
Matcher method("^GET|HEAD|POST$");
if (request[1] != method) return notImplemented;
env.set("REQUEST_METHOD", method);
+ env.set("REQUEST_URI", request[2] + request[3]);
- if (!request[2].empty()) env.set("QUERY_STRING", request[2].substr(1));
+ if (!request[3].empty()) env.set("QUERY_STRING", request[3].substr(1));
headers(sin, env);
+ if (env.get("HTTP_HOST").empty()) return bad;
if (method[0] == "POST") return message(sin, env, post);
return ok;
}
- return notFound;
+ return bad;
}
void Daemon::response(ostream& sout, Status status)
{
sout << "HTTP/1.1 " << status << ' ' << reason(status) << crlf << "Date: "
- << date() << crlf << "Server: Smersh/0.9" << crlf
+ << date() << crlf << "Server: " << server() << crlf
<< "Connection: close" << crlf;
}
-streamsize Daemon::error(ostream& sout, Status status)
+string Daemon::reason(Status status)
+{
+ ostringstream sout;
+
+ switch (status)
+ {
+ case ok:
+ sout << "OK";
+ break;
+ case found:
+ sout << "Found";
+ break;
+ case seeOther:
+ sout << "See Other";
+ break;
+ case bad:
+ sout << "Bad Request";
+ break;
+ case notFound:
+ sout << "Not Found";
+ break;
+ case lengthRequired:
+ sout << "Length Required";
+ break;
+ case mediaType:
+ sout << "Unsupported Media Type";
+ break;
+ case serverError:
+ sout << "Internal Server Error";
+ break;
+ case notImplemented:
+ sout << "Not Implemented";
+ break;
+ case version:
+ sout << "HTTP Version not supported";
+ }
+
+ return sout.str();
+}
+
+string Daemon::server()
+{
+ utsname system;
+
+ uname(&system);
+
+ return string("Smersh/0.9 (") + system.sysname + ')';
+}
+
+string Daemon::server(const Environment& env)
+{
+ ostringstream server;
+ string port(env.get("SERVER_PORT"));
+
+ server << this->server() << " Server at " << env.get("SERVER_NAME") << " Po"
+ << "rt " << (port.empty() ? lexical_cast(this->port) : port);
+
+ return server.str();
+}
+
+streamsize Daemon::error(ostream& sout, Status status, const Environment& env)
{
string reason(this->reason(status));
ostringstream error;
error << "" << status << ' ' << reason << "" << reason << "
Mistakes were made, deal with t"
- << "hem.
Smersh/0.9\n";
+ << "hem.
" << server(env) << "