1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
#pragma once
#include <map>
#include <list>
#include <Atomic.h>
#include <BString.h>
#include <BRegex.h>
#include <Exceptions.h>
#include <Threads.h>
#include <Handle.h>
#include <Http.h>
namespace Balau {
class HttpWorker;
class HttpServer {
public:
class Action {
public:
Action(const Regex & regex, const 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> 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, Http::Request & req, ActionMatch & match, IO<Handle> out) throw (GeneralException) = 0;
private:
const Regex m_regex, m_host;
volatile int m_refCount;
};
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; }
void registerAction(Action * action);
void flushAllActions();
typedef std::pair<Action *, Action::ActionMatch> ActionFound;
ActionFound findAction(const char * uri, const char * host);
private:
bool m_started;
void * m_listenerPtr;
int m_port;
String m_local;
typedef std::list<Action *> ActionList;
ActionList m_actions;
Lock m_actionsLock;
friend class HttpWorker;
};
};
|