diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | includes/HttpServer.h | 23 | ||||
-rw-r--r-- | src/HttpServer.cc | 76 |
3 files changed, 101 insertions, 0 deletions
@@ -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; +} |