From e72624ab203439ffea88cd55c145cdbbc57286e4 Mon Sep 17 00:00:00 2001 From: Pixel Date: Tue, 15 Nov 2011 17:00:03 -0800 Subject: Adding a potential event to cancel a forced read/write, such as a timeout. --- src/HttpServer.cc | 91 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 17 deletions(-) (limited to 'src/HttpServer.cc') diff --git a/src/HttpServer.cc b/src/HttpServer.cc index f3b95a7..530dcf5 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -5,13 +5,14 @@ #include "Socket.h" #include "BStream.h" -static const ev_tstamp s_httpTimeout = 5; +static const ev_tstamp s_httpTimeout = 15; namespace Balau { class HttpWorker : public Task { public: HttpWorker(IO & io, void * server); + ~HttpWorker(); private: virtual void Do(); virtual const char * getName(); @@ -22,33 +23,45 @@ class HttpWorker : public Task { IO m_socket; IO m_strm; String m_name; + + uint8_t * m_postData; }; }; -Balau::HttpWorker::HttpWorker(IO & io, void * _server) : m_socket(io), m_strm(new BStream(io)) { +Balau::HttpWorker::HttpWorker(IO & io, void * _server) : m_socket(io), m_strm(new BStream(io)), m_postData(NULL) { HttpServer * server = (HttpServer *) _server; m_name.set("HttpWorker(%s)", m_socket->getName()); + // copy stuff from server, such as port number, root document, base URL, etc... +} + +Balau::HttpWorker::~HttpWorker() { + if (m_postData) { + free(m_postData); + m_postData = NULL; + } } void Balau::HttpWorker::send400() { static const char str[] = "HTTP/1.0 400 Bad Request\r\n" "Content-Type: text/html; charset=UTF-8\r\n" +"Connection: close\r\n" "\r\n" -"\r\n" -"\r\n" -" \r\n" -" Bad Request\r\n" -" \r\n" -"\r\n" -" \r\n" -" The HTTP request you've sent is invalid.\r\n" -" \r\n" -"\r\n"; - - m_socket->write(str, sizeof(str)); +"\n" +"\n" +" \n" +" Bad Request\n" +" \n" +"\n" +" \n" +" The HTTP request you've sent is invalid.\n" +" \n" +"\n"; + + setOkayToEAgain(false); + m_socket->writeString(str, sizeof(str)); Balau::Printer::elog(Balau::E_HTTPSERVER, "%s had an invalid request", m_name.to_charp()); } @@ -62,7 +75,13 @@ bool Balau::HttpWorker::handleClient() { int method = -1; String url; String HttpVersion; - std::map HttpHeaders; + typedef std::map HttpHeaders_t; + HttpHeaders_t HttpHeaders; + if (m_postData) { + free(m_postData); + m_postData = NULL; + } + bool persistent = false; // read client's request do { @@ -158,7 +177,45 @@ bool Balau::HttpWorker::handleClient() { return false; } - return true; + if (method == Http::POST) { + int lengthStr = 0; + HttpHeaders_t::iterator i = HttpHeaders.find("Content-Length"); + + if (i != HttpHeaders.end()) + lengthStr = i->second.to_int(); + + m_postData = (uint8_t *) malloc(lengthStr); + + try { + m_strm->forceRead(m_postData, lengthStr); + } + catch (EAgain) { + Assert(evtTimeout.gotSignal()); + Balau::Printer::elog(Balau::E_HTTPSERVER, "%s timed out getting request (reading POST values)", m_name.to_charp()); + return false; + } + } + + if (HttpVersion == "1.1") { + HttpHeaders_t::iterator i = HttpHeaders.find("Connection"); + + if (i != HttpHeaders.end()) { + if (i->second != "close") { + send400(); + return false; + } + } else { + persistent = true; + } + } + + // process query; everything should be here now + + + + // query process finished; wrapping up and exiting. + + return persistent; } void Balau::HttpWorker::Do() { -- cgit v1.2.3