00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __libutilxx__sella__server__HTTP_H__
00010 #define __libutilxx__sella__server__HTTP_H__
00011
00012 #include "../../common.h"
00013 #include "ServerException.h"
00014 #include "HTTPConnection.h"
00015 #include "../util/Log.h"
00016 #include "../util/ThreadPool.h"
00017 #include "../net/IPAddressPort.h"
00018 #include "../net/SocketMux.h"
00019 #include "../net/SocketTrigger.h"
00020
00021 #include <set>
00022 #include <mutex>
00023 #include <memory>
00024 #include <queue>
00025 #include <vector>
00026 #include <functional>
00027 #include <unordered_set>
00028
00029 namespace sella {
00030 namespace server {
00031 class HTTP;
00032 }
00033
00034 namespace util {
00035 class ThreadPool;
00036 }
00037 }
00038
00039 class sella::server::HTTP {
00040 public:
00041 typedef std::shared_ptr<HTTP> shared;
00042 typedef HTTP *ptr;
00043
00044 typedef std::function<bool(HTTPConnection::shared)> acl_callback;
00045 typedef std::function<bool(HTTPConnection::shared)> request_callback;
00046 typedef std::function<bool(HTTPConnection::shared)> authentication_callback;
00047 typedef std::function<bool(HTTPConnection::shared, int, const std::string&)> error_callback;
00048
00049 public:
00050 static const sella::net::IPAddressPort::vector ListenersDefault;
00051 static const size_t RequestBodyLimitDefault = 25 * 102400;
00052 static const size_t ConnectionLimitDefault = 256;
00053 static const size_t DelaySecondsDefault = 7200;
00054 static const std::string RootDefault;
00055 static const std::vector<std::string> DirectoryIndexesDefault;
00056 static const std::string BannerDefault;
00057 static const std::set<HTTPRequest::Method> AllowDefault;
00058
00059 public:
00060 static const size_t MaximumWorkersDefault = 0;
00061 static const size_t MinimumWorkersDefault = 2;
00062 static const size_t SpareWorkersDefault = 2;
00063
00064 public:
00065 HTTP() throw (ServerException);
00066 HTTP(sella::util::Log::shared log) throw (ServerException);
00067 virtual ~HTTP() throw ();
00068
00069
00070 virtual bool receive(void) throw (ServerException);
00071 virtual bool receive(timeval *tv) throw (ServerException);
00072
00073
00074 virtual bool run(size_t workers = MaximumWorkersDefault) throw (ServerException);
00075 virtual void start(size_t workers = MaximumWorkersDefault) throw (ServerException);
00076 virtual void start(size_t maximumWorkers, size_t minimumWorkers, size_t spareWorkers = SpareWorkersDefault) throw (ServerException);
00077 virtual void start(sella::util::ThreadPool::shared pool) throw (ServerException);
00078 virtual bool stop(void) throw ();
00079
00080 void setListeners(const sella::net::IPAddressPort::vector &listeners) throw ();
00081 void setListeners(const std::string &listeners) throw ();
00082 void setRequestBodyLimit(size_t requestBodyLimit) throw ();
00083 void setConnectionLimit(size_t connectionLimit) throw ();
00084 void setRoot(const std::string &root) throw (ServerException);
00085 void setDirectoryIndex(const std::vector<std::string> &indexes) throw ();
00086 void addDirectoryIndex(const std::string &index) throw ();
00087 void setBanner(const std::string &banner) throw ();
00088 void setCustomHeaders(const std::vector<std::string> &headers) throw ();
00089 void setAllow(HTTPRequest::Method method) throw ();
00090 void setACLCallback(const acl_callback &callback) throw ();
00091 void setAuthenticationCallback(const authentication_callback &callback) throw ();
00092 void setRequestCallback(const request_callback &callback) throw ();
00093 void setErrorCallback(const error_callback &callback) throw ();
00094
00095 sella::net::IPAddressPort::vector getListeners(void) const throw ();
00096 std::string getListenersString(void) const throw ();
00097 size_t getRequestBodyLimit(void) const throw ();
00098 size_t getConnectionLimit(void) const throw ();
00099 const std::string& getRoot(void) const throw ();
00100 const std::vector<std::string>& getDirectoryIndexes(void) const throw ();
00101 const std::string& getBanner(void) const throw ();
00102 const std::vector<std::string>& getCustomHeaders(void) const throw ();
00103 std::set<HTTPRequest::Method> getAllow(void) const throw ();
00104 void clearAllow(HTTPRequest::Method method) throw ();
00105
00106 bool isRunning(void) const throw ();
00107
00108 public:
00109 virtual void clear(void);
00110 virtual void print(void);
00111
00112 static const HTTP::shared shared_ptr() throw (ServerException);
00113 static const HTTP::shared shared_ptr(sella::util::Log::shared log) throw (ServerException);
00114
00115 protected:
00116 void startup(void) throw (ServerException);
00117 void shutdown(void) throw ();
00118 int select(timeval *tv) throw (ServerException);
00119 HTTPConnection::shared accept(const sella::net::Socket::shared &socket) throw (ServerException);
00120 void process(HTTPConnection::shared &connection) throw ();
00121 void server(void) throw ();
00122 void worker(HTTPConnection::shared &connection) throw ();
00123
00124 private:
00125 sella::util::Log::shared libutilxx__log;
00126 sella::util::ThreadPool::shared pool;
00127 sella::net::SocketMux mux;
00128 std::unordered_set<int> servers;
00129 std::queue<HTTPConnection::shared> pending;
00130 bool running;
00131 std::mutex mutex;
00132 std::thread manager;
00133 sella::net::SocketTrigger trigger;
00134
00135 sella::net::IPAddressPort::vector listeners;
00136 size_t requestBodyLimit;
00137 size_t connectionLimit;
00138 std::string root;
00139 std::vector<std::string> indexes;
00140 std::string banner;
00141 std::vector<std::string> headers;
00142 std::set<HTTPRequest::Method> allow;
00143
00144 acl_callback aclCallback;
00145 authentication_callback authCallback;
00146 request_callback reqCallback;
00147 error_callback errorCallback;
00148 };
00149
00150 #endif
00151
00152
00153
00154