00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef ULXR_HTTP_SERVER_H
00031 #define ULXR_HTTP_SERVER_H
00032
00033 #ifndef ULXR_OMIT_TCP_STUFF
00034
00035 #include <ulxmlrpcpp/ulxmlrpcpp.h>
00036
00037 #include <vector>
00038 #include <map>
00039 #include <cstdio>
00040
00041
00042 namespace ulxr {
00043
00044
00045 class HttpProtocol;
00046 class Dispatcher;
00047 class Exception;
00048 class MethodHandler;
00049 class CachedResource;
00050
00056 class ULXR_API_DECL0 HttpServer
00057 {
00058 public:
00059
00060 class ThreadData;
00061
00066 HttpServer (HttpProtocol* prot, bool wbxml = false);
00067
00068 #ifdef ULXR_MULTITHREADED
00069
00075 HttpServer (HttpProtocol* prot, unsigned num, bool wbxml = false);
00076
00077 #endif
00078
00081 virtual ~HttpServer ();
00082
00091 std::size_t runPicoHttpd();
00092
00096 void setHttpRoot(const CppString &root);
00097
00106 virtual void addRealm(const CppString &path, const CppString &realm);
00107
00114 virtual CppString getRealm(const CppString &path) const;
00115
00128 void addHttpHandler(const CppString &name,
00129 MethodHandler *handler);
00130
00135
00136
00137
00138
00142 void addResource(CachedResource *cache);
00143
00147 CachedResource * getResource(const CppString& name);
00148
00152 void setRpcDispatcher(Dispatcher *disp);
00153
00159 void requestTermination();
00160
00166 void addAuthentication(const CppString &user,
00167 const CppString &pass,
00168 const CppString &realm);
00169
00170 #ifdef ULXR_MULTITHREADED
00171
00175 unsigned numThreads() const;
00176
00181 void terminateAllThreads(unsigned time = 0);
00182
00187 void shutdownAllThreads(unsigned time = 0);
00188
00193 void waitAsync(bool term, bool stat = false);
00194
00195 #endif // ULXR_MULTITHREADED
00196
00197 protected:
00198
00199 #ifdef ULXR_MULTITHREADED
00200
00203 void printStatistics() const;
00204
00205 #endif // ULXR_MULTITHREADED
00206
00210 virtual void forwardThreadedError(const Exception &ex) const;
00211
00218 virtual void executeHttpMethod(HttpProtocol *prot,
00219 Cpp8BitString &conn_pending_data,
00220 const CppString& name,
00221 const CppString& resource);
00222
00230 virtual void executeUnknownHttpMethod(HttpProtocol *prot,
00231 Cpp8BitString &conn_pending_data,
00232 const CppString& name,
00233 const CppString& resource);
00234
00239 virtual void executeHttpGET(HttpProtocol *prot,
00240 const CppString& resource);
00241
00247 virtual void executeHttpPUT(HttpProtocol *prot,
00248 Cpp8BitString &conn_pending_data,
00249 const CppString& resource);
00250
00258 virtual void executeHttpPOST(HttpProtocol *prot,
00259 Cpp8BitString &conn_pending_data,
00260 const CppString& resource);
00261
00266 virtual void executeHttpRPC(HttpProtocol *prot,
00267 Cpp8BitString &conn_pending_data);
00268
00273 virtual void executeHttpDELETE(HttpProtocol *prot,
00274 const CppString& resource);
00275
00281 void performHttpTransaction(HttpProtocol *prot);
00282
00290 virtual void interpreteHttpHeader(HttpProtocol *prot,
00291 CppString &head_resource,
00292 CppString &head_method,
00293 CppString &head_version);
00294
00299 CppString stripResource(const CppString &resource);
00300
00305 virtual void checkValidPath(const CppString &resource);
00306
00311 CppString createLocalName(const CppString &resource);
00312
00317 virtual CppString guessMimeType(const CppString &name) const;
00318
00319 private:
00320
00323 virtual void beforeHttpTransaction();
00324
00327 virtual void afterHttpTransaction();
00328
00334 std::size_t runPicoHttpd(HttpProtocol *prot, ThreadData *td = 0);
00335
00336 #ifdef ULXR_MULTITHREADED
00337
00341 static void *startThread(ThreadData *td);
00342
00345 void releaseThreads();
00346
00350 unsigned dispatchAsync();
00351
00352 #endif // ULXR_MULTITHREADED
00353
00356 void releaseHandlers(std::vector<MethodHandler*> &handlers);
00357
00360 void init();
00361
00362 private:
00363
00364 CppString rpc_resource_root;
00365 CppString http_root_dir;
00366 bool pico_shall_run;
00367 bool wbxml_mode;
00368
00369 Dispatcher *rpc_dispatcher;
00370 HttpProtocol *base_protocol;
00371 #ifdef ULXR_MULTITHREADED
00372 std::vector<ThreadData*> threads;
00373 #endif
00374
00375 std::vector<MethodHandler*> getHandlers;
00376 std::vector<MethodHandler*> putHandlers;
00377 std::vector<MethodHandler*> postHandlers;
00378 std::vector<MethodHandler*> deleteHandlers;
00379
00380 std::vector<CachedResource*> resources;
00381
00382 std::map<CppString, CppString> realmXrefs;
00383
00384 private:
00385
00386
00387 HttpServer(const HttpServer&);
00388 HttpServer& operator=(const HttpServer&);
00389 };
00390
00391
00392 namespace hidden {
00393
00394
00397 class ULXR_API_DECL0 MethodHandlerWrapperBase
00398 {
00399 public:
00400
00401
00404 virtual ~MethodHandlerWrapperBase()
00405 {}
00406
00415 virtual bool handle(HttpProtocol *prot,
00416 const CppString &method,
00417 const CppString &resource,
00418 const Cpp8BitString &conn_data) const = 0;
00419 };
00420
00421
00424 template <class T>
00425 class MethodHandlerWrapper : public MethodHandlerWrapperBase
00426 {
00427 public:
00428
00437 typedef bool (T::*PMF)(HttpProtocol *prot,
00438 const CppString &method,
00439 const CppString &resource,
00440 const Cpp8BitString &conn_data);
00441
00444 virtual ~MethodHandlerWrapper()
00445 {
00446 }
00447
00456 virtual bool handle(HttpProtocol *prot,
00457 const CppString &method,
00458 const CppString &resource,
00459 const Cpp8BitString &conn_data) const
00460 {
00461 return (obj->*adr) (prot, method, resource, conn_data);
00462 }
00463
00464 public:
00465
00470 MethodHandlerWrapper(T *o, PMF a)
00471 : obj(o), adr(a)
00472 {
00473 }
00474
00475 private:
00476 T *obj;
00477 PMF adr ;
00478 };
00479
00488 typedef bool (*StaticMethodHandler)(HttpProtocol *prot,
00489 const CppString &method,
00490 const CppString &resource,
00491 const Cpp8BitString &conn_data);
00492
00493 typedef MethodHandlerWrapperBase *DynamicMethodHandler;
00494
00495
00496 }
00497
00498
00501 class ULXR_API_DECL0 MethodHandler
00502 {
00503 public:
00507 MethodHandler(hidden::StaticMethodHandler handler);
00508
00512 MethodHandler(hidden::DynamicMethodHandler handler);
00513
00516 virtual ~MethodHandler();
00517
00526 bool handle(HttpProtocol *prot,
00527 const CppString &method,
00528 const CppString &resource,
00529 const Cpp8BitString &conn_data);
00530
00531 private:
00532
00533 hidden::StaticMethodHandler static_handler;
00534 hidden::DynamicMethodHandler dynamic_handler;
00535
00536
00537 const MethodHandler& operator= (const MethodHandler&);
00538 MethodHandler (const MethodHandler&);
00539 };
00540
00541
00542 #ifndef _MSC_VER
00543
00549 template <class T>
00550 inline MethodHandler*
00551 make_methodhandler(T &w, typename hidden::MethodHandlerWrapper<T>::PMF pmf)
00552 {
00553 return new MethodHandler(new hidden::MethodHandlerWrapper<T> (&w, pmf));
00554 }
00555
00556 #else // work around m$vc bug
00557
00558 template <class T, class U>
00559 inline MethodHandler*
00560 make_methodhandler(T &w, U pmf)
00561 {
00562 return new MethodHandler(new hidden::MethodHandlerWrapper<T> (&w, pmf));
00563 }
00564
00565 #endif
00566
00571 inline ULXR_API_IMPL(MethodHandler*)
00572 make_methodhandler(hidden::StaticMethodHandler ptr)
00573 {
00574 return new MethodHandler(ptr);
00575 }
00576
00577
00578 }
00579
00580
00581 #endif // ULXR_OMIT_TCP_STUFF
00582
00583
00584 #endif // ULXR_HTTP_SERVER_H