summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-11-18 22:52:12 -0800
committerPixel <pixel@nobis-crew.org>2011-11-18 22:52:12 -0800
commit0f0db0ee56b69d580fe66528a379fb08d714bf4d (patch)
treebf55d752c095838644e50b9bd762538cd9eaa447
parent52f7b28073501242dacd6409bb649fc2182cc777 (diff)
Starting to re-organize the HTTP code a bit. Sharing code between the server and a potential client makes sense. Also packing requests and responses into structures / classes is probably a good idea.
-rw-r--r--includes/Http.h18
-rw-r--r--includes/HttpServer.h12
-rw-r--r--src/HttpServer.cc32
-rw-r--r--tests/test-Http.cc4
4 files changed, 45 insertions, 21 deletions
diff --git a/includes/Http.h b/includes/Http.h
index cbb118f..cd7973f 100644
--- a/includes/Http.h
+++ b/includes/Http.h
@@ -1,9 +1,27 @@
#pragma once
+#include <map>
+#include <BString.h>
+#include <Handle.h>
+
namespace Balau {
namespace Http {
+typedef std::map<String, String> StringMap;
+typedef std::map<String, IO<Handle> > FileList;
+
+class Request {
+ public:
+ int method;
+ String host;
+ String uri;
+ StringMap variables;
+ StringMap headers;
+ FileList files;
+ bool persistent;
+};
+
enum {
GET,
POST,
diff --git a/includes/HttpServer.h b/includes/HttpServer.h
index c2e8992..f78a816 100644
--- a/includes/HttpServer.h
+++ b/includes/HttpServer.h
@@ -9,6 +9,7 @@
#include <Exceptions.h>
#include <Threads.h>
#include <Handle.h>
+#include <Http.h>
namespace Balau {
@@ -17,19 +18,16 @@ class HttpWorker;
class HttpServer {
public:
- typedef std::map<String, String> StringMap;
- typedef std::map<String, IO<Handle> > FileList;
-
class Action {
public:
Action(Regex & regex, Regex & host = Regexes::any) : m_regex(regex), m_host(host), m_refCount(0) { }
~Action() { Assert(m_refCount == 0); }
- typedef std::pair<Regex::Captures, Regex::Captures> ActionMatches;
- ActionMatches matches(const char * uri, const char * host);
+ typedef std::pair<Regex::Captures, Regex::Captures> ActionMatch;
+ ActionMatch matches(const char * uri, const char * host);
void unref() { if (Atomic::Decrement(&m_refCount) == 0) delete this; }
void ref() { Atomic::Increment(&m_refCount); }
void registerMe(HttpServer * server) { server->registerAction(this); }
- virtual bool Do(HttpServer * server, ActionMatches & m, IO<Handle> out, StringMap & vars, StringMap & headers, FileList & files) = 0;
+ virtual bool Do(HttpServer * server, Http::Request & req, ActionMatch & match, IO<Handle> out) = 0;
private:
Regex m_regex, m_host;
volatile int m_refCount;
@@ -43,7 +41,7 @@ class HttpServer {
void setLocal(const char * local) { Assert(!m_started); m_local = local; }
void registerAction(Action * action);
void flushAllActions();
- typedef std::pair<Action *, Action::ActionMatches> ActionFound;
+ typedef std::pair<Action *, Action::ActionMatch> ActionFound;
ActionFound findAction(const char * uri, const char * host);
private:
bool m_started;
diff --git a/src/HttpServer.cc b/src/HttpServer.cc
index 6afb074..d99e1ea 100644
--- a/src/HttpServer.cc
+++ b/src/HttpServer.cc
@@ -20,7 +20,7 @@ class HttpWorker : public Task {
void send400();
void send404();
String httpUnescape(const char * in);
- void readVariables(HttpServer::StringMap & variables, char * str);
+ void readVariables(Http::StringMap & variables, char * str);
IO<Handle> m_socket;
IO<BStream> m_strm;
@@ -70,7 +70,7 @@ Balau::String Balau::HttpWorker::httpUnescape(const char * in) {
return r;
}
-void Balau::HttpWorker::readVariables(HttpServer::StringMap & variables, char * str) {
+void Balau::HttpWorker::readVariables(Http::StringMap & variables, char * str) {
char * ampPos;
do {
ampPos = strchr(str, '&');
@@ -146,9 +146,9 @@ bool Balau::HttpWorker::handleClient() {
String host;
String uri;
String httpVersion;
- HttpServer::StringMap httpHeaders;
- HttpServer::StringMap variables;
- HttpServer::FileList files;
+ Http::StringMap httpHeaders;
+ Http::StringMap variables;
+ Http::FileList files;
bool persistent = false;
// read client's request
@@ -251,7 +251,7 @@ bool Balau::HttpWorker::handleClient() {
}
if (httpVersion == "1.1") {
- HttpServer::StringMap::iterator i = httpHeaders.find("Connection");
+ Http::StringMap::iterator i = httpHeaders.find("Connection");
if (i != httpHeaders.end()) {
if (i->second == "close") {
@@ -270,7 +270,7 @@ bool Balau::HttpWorker::handleClient() {
if (method == Http::POST) {
int length = 0;
- HttpServer::StringMap::iterator i;
+ Http::StringMap::iterator i;
bool multipart = false;
String boundary;
@@ -289,7 +289,7 @@ bool Balau::HttpWorker::handleClient() {
send400();
return false;
}
- HttpServer::StringMap t;
+ Http::StringMap t;
char * b = i->second.extract(sizeof(multipartStr) + 1).do_trim().strdup();
readVariables(t, b);
free(b);
@@ -351,7 +351,7 @@ bool Balau::HttpWorker::handleClient() {
}
}
- HttpServer::StringMap::iterator hostIter = httpHeaders.find("host");
+ Http::StringMap::iterator hostIter = httpHeaders.find("host");
if (hostIter != httpHeaders.end()) {
if (host != "") {
@@ -367,7 +367,15 @@ bool Balau::HttpWorker::handleClient() {
HttpServer::ActionFound f = m_server->findAction(uri.to_charp(), host.to_charp());
if (f.first) {
- if (!f.first->Do(m_server, f.second, m_socket, variables, httpHeaders, files)) {
+ Http::Request req;
+ req.method = method;
+ req.host = host;
+ req.uri = uri;
+ req.variables = variables;
+ req.headers = httpHeaders;
+ req.files = files;
+ req.persistent = persistent;
+ if (!f.first->Do(m_server, req, f.second, m_socket)) {
persistent = false;
}
} else {
@@ -421,8 +429,8 @@ void Balau::HttpServer::flushAllActions() {
m_actionsLock.leave();
}
-Balau::HttpServer::Action::ActionMatches Balau::HttpServer::Action::matches(const char * uri, const char * host) {
- ActionMatches r;
+Balau::HttpServer::Action::ActionMatch Balau::HttpServer::Action::matches(const char * uri, const char * host) {
+ ActionMatch r;
r.second = m_host.match(host);
if (r.second.empty())
diff --git a/tests/test-Http.cc b/tests/test-Http.cc
index 496d7e6..de3c6f3 100644
--- a/tests/test-Http.cc
+++ b/tests/test-Http.cc
@@ -10,10 +10,10 @@ using namespace Balau;
class TestAction : public HttpServer::Action {
public:
TestAction() : Action(Regexes::any) { }
- virtual bool Do(HttpServer * server, HttpServer::Action::ActionMatches & m, IO<Handle> out, HttpServer::StringMap & vars, HttpServer::StringMap & headers, HttpServer::FileList & files);
+ virtual bool Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out);
};
-bool TestAction::Do(HttpServer * server, HttpServer::Action::ActionMatches & m, IO<Handle> out, HttpServer::StringMap & vars, HttpServer::StringMap & headers, HttpServer::FileList & files) {
+bool TestAction::Do(HttpServer * server, Http::Request & req, HttpServer::Action::ActionMatch & match, IO<Handle> out) {
static const char str[] =
"HTTP/1.1 200 Found\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"