summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-11-15 17:00:03 -0800
committerPixel <pixel@nobis-crew.org>2011-11-15 17:00:03 -0800
commite72624ab203439ffea88cd55c145cdbbc57286e4 (patch)
tree5a766c74fa83441ff5ef4a744968eb6c65a7f675
parent36b12593e6ec34a88bde537a220e7a15f478638c (diff)
Adding a potential event to cancel a forced read/write, such as a timeout.
-rw-r--r--includes/Handle.h10
-rw-r--r--src/Handle.cc8
-rw-r--r--src/HttpServer.cc91
3 files changed, 88 insertions, 21 deletions
diff --git a/includes/Handle.h b/includes/Handle.h
index cfb004d..0eea93c 100644
--- a/includes/Handle.h
+++ b/includes/Handle.h
@@ -20,6 +20,12 @@ class IOBase;
template<class T>
class IO;
+namespace Events {
+
+class BaseEvent;
+
+};
+
class Handle {
public:
virtual ~Handle() { Assert(m_refCount == 0); }
@@ -42,8 +48,8 @@ class Handle {
virtual off_t wtell() throw (GeneralException);
virtual off_t getSize();
virtual time_t getMTime();
- ssize_t forceRead(void * buf, size_t count) throw (GeneralException);
- ssize_t forceWrite(const void * buf, size_t count) throw (GeneralException);
+ ssize_t forceRead(void * buf, size_t count, Events::BaseEvent * evt = NULL) throw (GeneralException);
+ ssize_t forceWrite(const void * buf, size_t count, Events::BaseEvent * evt = NULL) throw (GeneralException);
protected:
Handle() : m_refCount(0) { }
private:
diff --git a/src/Handle.cc b/src/Handle.cc
index 8fa0417..839c58a 100644
--- a/src/Handle.cc
+++ b/src/Handle.cc
@@ -83,7 +83,7 @@ ssize_t Balau::Handle::write(const void * buf, size_t count) throw (GeneralExcep
return -1;
}
-ssize_t Balau::Handle::forceRead(void * _buf, size_t count) throw (GeneralException) {
+ssize_t Balau::Handle::forceRead(void * _buf, size_t count, Events::BaseEvent * evt) throw (GeneralException) {
ssize_t total;
uint8_t * buf = (uint8_t *) _buf;
if (!canRead())
@@ -95,6 +95,8 @@ ssize_t Balau::Handle::forceRead(void * _buf, size_t count) throw (GeneralExcept
r = read(buf, count);
}
catch (EAgain e) {
+ if (evt && evt->gotSignal())
+ return total;
Task::yield(e.getEvent());
continue;
}
@@ -108,7 +110,7 @@ ssize_t Balau::Handle::forceRead(void * _buf, size_t count) throw (GeneralExcept
return total;
}
-ssize_t Balau::Handle::forceWrite(const void * _buf, size_t count) throw (GeneralException) {
+ssize_t Balau::Handle::forceWrite(const void * _buf, size_t count, Events::BaseEvent * evt) throw (GeneralException) {
ssize_t total;
const uint8_t * buf = (const uint8_t *) _buf;
if (!canWrite())
@@ -120,6 +122,8 @@ ssize_t Balau::Handle::forceWrite(const void * _buf, size_t count) throw (Genera
r = write(buf, count);
}
catch (EAgain e) {
+ if (evt && evt->gotSignal())
+ return total;
Task::yield(e.getEvent());
continue;
}
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<Socket> & io, void * server);
+ ~HttpWorker();
private:
virtual void Do();
virtual const char * getName();
@@ -22,33 +23,45 @@ class HttpWorker : public Task {
IO<Socket> m_socket;
IO<BStream> m_strm;
String m_name;
+
+ uint8_t * m_postData;
};
};
-Balau::HttpWorker::HttpWorker(IO<Socket> & io, void * _server) : m_socket(io), m_strm(new BStream(io)) {
+Balau::HttpWorker::HttpWorker(IO<Socket> & 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"
-"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\r\n"
-"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n"
-"<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n"
-" <head>\r\n"
-" <title>Bad Request</title>\r\n"
-" </head>\r\n"
-"\r\n"
-" <body>\r\n"
-" The HTTP request you've sent is invalid.\r\n"
-" </body>\r\n"
-"</html>\r\n";
-
- m_socket->write(str, sizeof(str));
+"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
+"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
+"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
+" <head>\n"
+" <title>Bad Request</title>\n"
+" </head>\n"
+"\n"
+" <body>\n"
+" The HTTP request you've sent is invalid.\n"
+" </body>\n"
+"</html>\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<String, String> HttpHeaders;
+ typedef std::map<String, String> 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() {