You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

httpserver.h 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright (c) 2015-2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #ifndef STARWELS_HTTPSERVER_H
  5. #define STARWELS_HTTPSERVER_H
  6. #include <string>
  7. #include <stdint.h>
  8. #include <functional>
  9. static const int DEFAULT_HTTP_THREADS=4;
  10. static const int DEFAULT_HTTP_WORKQUEUE=16;
  11. static const int DEFAULT_HTTP_SERVER_TIMEOUT=30;
  12. struct evhttp_request;
  13. struct event_base;
  14. class CService;
  15. class HTTPRequest;
  16. /** Initialize HTTP server.
  17. * Call this before RegisterHTTPHandler or EventBase().
  18. */
  19. bool InitHTTPServer();
  20. /** Start HTTP server.
  21. * This is separate from InitHTTPServer to give users race-condition-free time
  22. * to register their handlers between InitHTTPServer and StartHTTPServer.
  23. */
  24. bool StartHTTPServer();
  25. /** Interrupt HTTP server threads */
  26. void InterruptHTTPServer();
  27. /** Stop HTTP server */
  28. void StopHTTPServer();
  29. /** Change logging level for libevent. Removes BCLog::LIBEVENT from logCategories if
  30. * libevent doesn't support debug logging.*/
  31. bool UpdateHTTPServerLogging(bool enable);
  32. /** Handler for requests to a certain HTTP path */
  33. typedef std::function<bool(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
  34. /** Register handler for prefix.
  35. * If multiple handlers match a prefix, the first-registered one will
  36. * be invoked.
  37. */
  38. void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler);
  39. /** Unregister handler for prefix */
  40. void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch);
  41. /** Return evhttp event base. This can be used by submodules to
  42. * queue timers or custom events.
  43. */
  44. struct event_base* EventBase();
  45. /** In-flight HTTP request.
  46. * Thin C++ wrapper around evhttp_request.
  47. */
  48. class HTTPRequest
  49. {
  50. private:
  51. struct evhttp_request* req;
  52. bool replySent;
  53. public:
  54. HTTPRequest(struct evhttp_request* req);
  55. ~HTTPRequest();
  56. enum RequestMethod {
  57. UNKNOWN,
  58. GET,
  59. POST,
  60. HEAD,
  61. PUT
  62. };
  63. /** Get requested URI.
  64. */
  65. std::string GetURI();
  66. /** Get CService (address:ip) for the origin of the http request.
  67. */
  68. CService GetPeer();
  69. /** Get request method.
  70. */
  71. RequestMethod GetRequestMethod();
  72. /**
  73. * Get the request header specified by hdr, or an empty string.
  74. * Return a pair (isPresent,string).
  75. */
  76. std::pair<bool, std::string> GetHeader(const std::string& hdr);
  77. /**
  78. * Read request body.
  79. *
  80. * @note As this consumes the underlying buffer, call this only once.
  81. * Repeated calls will return an empty string.
  82. */
  83. std::string ReadBody();
  84. /**
  85. * Write output header.
  86. *
  87. * @note call this before calling WriteErrorReply or Reply.
  88. */
  89. void WriteHeader(const std::string& hdr, const std::string& value);
  90. /**
  91. * Write HTTP reply.
  92. * nStatus is the HTTP status code to send.
  93. * strReply is the body of the reply. Keep it empty to send a standard message.
  94. *
  95. * @note Can be called only once. As this will give the request back to the
  96. * main thread, do not call any other HTTPRequest methods after calling this.
  97. */
  98. void WriteReply(int nStatus, const std::string& strReply = "");
  99. };
  100. /** Event handler closure.
  101. */
  102. class HTTPClosure
  103. {
  104. public:
  105. virtual void operator()() = 0;
  106. virtual ~HTTPClosure() {}
  107. };
  108. /** Event class. This can be used either as a cross-thread trigger or as a timer.
  109. */
  110. class HTTPEvent
  111. {
  112. public:
  113. /** Create a new event.
  114. * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called)
  115. * handler is the handler to call when the event is triggered.
  116. */
  117. HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function<void(void)>& handler);
  118. ~HTTPEvent();
  119. /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after
  120. * the given time has elapsed.
  121. */
  122. void trigger(struct timeval* tv);
  123. bool deleteWhenTriggered;
  124. std::function<void(void)> handler;
  125. private:
  126. struct event* ev;
  127. };
  128. std::string urlDecode(const std::string &urlEncoded);
  129. #endif // STARWELS_HTTPSERVER_H