summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-11-13 15:56:31 -0700
committerPixel <pixel@nobis-crew.org>2011-11-13 15:56:36 -0700
commit6f213b0a8abba8d3ca85e688714c91755741f82c (patch)
tree903814c0c6fbe28122ccc10efdf016e172d5e7a2
parentab52473a09d10e9695a95dddceb9a467572ab694 (diff)
Adding the skeleton of an HTTP server; still work in progress though: it still needs coding, and won't work as it. And it needs a unit test.
-rw-r--r--Makefile2
-rw-r--r--includes/HttpServer.h23
-rw-r--r--src/HttpServer.cc76
3 files changed, 101 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 2ba6284..7bf52ba 100644
--- a/Makefile
+++ b/Makefile
@@ -127,6 +127,8 @@ BStream.cc \
Task.cc \
TaskMan.cc \
\
+HttpServer.cc \
+\
BLua.cc \
ifeq ($(SYSTEM),MINGW32)
diff --git a/includes/HttpServer.h b/includes/HttpServer.h
new file mode 100644
index 0000000..2609283
--- /dev/null
+++ b/includes/HttpServer.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <BString.h>
+#include <Exceptions.h>
+
+namespace Balau {
+
+class HttpServer {
+ public:
+ HttpServer() : m_started(false), m_listenerPtr(NULL), m_port(80) { }
+ ~HttpServer() { if (!m_started) stop(); }
+ void start();
+ void stop();
+ void setPort(int port) { Assert(!m_started); m_port = port; }
+ void setLocal(const char * local) { Assert(!m_started); m_local = local; }
+ private:
+ bool m_started;
+ void * m_listenerPtr;
+ int m_port;
+ String m_local;
+};
+
+};
diff --git a/src/HttpServer.cc b/src/HttpServer.cc
new file mode 100644
index 0000000..acfc9d2
--- /dev/null
+++ b/src/HttpServer.cc
@@ -0,0 +1,76 @@
+#include "HttpServer.h"
+#include "Socket.h"
+#include "BStream.h"
+
+static const ev_tstamp s_httpTimeout = 5;
+
+namespace Balau {
+
+class HttpWorker : public Task {
+ public:
+ HttpWorker(IO<Socket> & io, void * server) : m_socket(io), m_parent((HttpServer *) server), m_evtTimeout(s_httpTimeout) { m_name.set("HttpWorker(%s)", m_socket->getName()); }
+ private:
+ virtual void Do();
+ virtual const char * getName();
+ IO<Socket> m_socket;
+ String m_name;
+ HttpServer * m_parent;
+ Events::Timeout m_evtTimeout;
+};
+
+};
+
+void Balau::HttpWorker::Do() {
+ waitFor(&m_evtTimeout);
+ setOkayToEAgain(true);
+
+ String line;
+ IO<BStream> strm(m_socket);
+ bool gotFirst = false;
+
+ do {
+ try {
+ line = strm->readString();
+ }
+ catch (EAgain) {
+ if (m_evtTimeout.gotSignal()) {
+ // do some log
+ return;
+ }
+ yield();
+ continue;
+ }
+ if (line == "")
+ break;
+
+ if (!gotFirst) {
+ gotFirst = true;
+ // parse request method, URL and HTTP version.
+ } else {
+ // parse HTTP header.
+ }
+ } while(true);
+
+ if (!gotFirst) {
+ // do some log
+ return;
+ }
+}
+
+const char * Balau::HttpWorker::getName() {
+ return m_name.to_charp();
+}
+
+typedef Balau::Listener<Balau::HttpWorker> HttpListener;
+
+void Balau::HttpServer::start() {
+ Assert(!m_started);
+ m_listenerPtr = new HttpListener(m_port, m_local.to_charp());
+ m_started = true;
+}
+
+void Balau::HttpServer::stop() {
+ Assert(m_started);
+ reinterpret_cast<HttpListener *>(m_listenerPtr)->stop();
+ m_started = false;
+}