HttpHandler.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #ifndef HV_HTTP_HANDLER_H_
  2. #define HV_HTTP_HANDLER_H_
  3. #include "HttpService.h"
  4. #include "HttpParser.h"
  5. #include "FileCache.h"
  6. #include "WebSocketServer.h"
  7. #include "WebSocketParser.h"
  8. class HttpHandler {
  9. public:
  10. enum ProtocolType {
  11. UNKNOWN,
  12. HTTP_V1,
  13. HTTP_V2,
  14. WEBSOCKET,
  15. } protocol;
  16. enum State {
  17. WANT_RECV,
  18. HANDLE_BEGIN,
  19. HANDLE_CONTINUE,
  20. HANDLE_END,
  21. WANT_SEND,
  22. SEND_HEADER,
  23. SEND_BODY,
  24. SEND_DONE,
  25. } state;
  26. // peeraddr
  27. bool ssl;
  28. char ip[64];
  29. int port;
  30. // for http
  31. HttpService *service;
  32. FileCache *files;
  33. HttpRequestPtr req;
  34. HttpResponsePtr resp;
  35. HttpResponseWriterPtr writer;
  36. HttpParserPtr parser;
  37. // for GetSendData
  38. file_cache_ptr fc;
  39. std::string header;
  40. // std::string body;
  41. // for websocket
  42. WebSocketChannelPtr ws_channel;
  43. WebSocketParserPtr ws_parser;
  44. uint64_t last_send_ping_time;
  45. uint64_t last_recv_pong_time;
  46. WebSocketService* ws_service;
  47. HttpHandler();
  48. ~HttpHandler();
  49. bool Init(int http_version = 1, hio_t* io = NULL) {
  50. parser.reset(HttpParser::New(HTTP_SERVER, (enum http_version)http_version));
  51. if (parser == NULL) {
  52. return false;
  53. }
  54. req.reset(new HttpRequest);
  55. resp.reset(new HttpResponse);
  56. if (http_version == 2) {
  57. protocol = HTTP_V2;
  58. resp->http_major = req->http_major = 2;
  59. resp->http_minor = req->http_minor = 0;
  60. }
  61. else if(http_version == 1) {
  62. protocol = HTTP_V1;
  63. }
  64. parser->InitRequest(req.get());
  65. if (io) {
  66. // shared resp object with HttpResponseWriter
  67. writer.reset(new hv::HttpResponseWriter(io, resp));
  68. writer->status = hv::SocketChannel::CONNECTED;
  69. writer->onwrite = std::bind(&HttpHandler::onWrite, this, std::placeholders::_1);
  70. }
  71. return true;
  72. }
  73. bool SwitchHTTP2() {
  74. parser.reset(HttpParser::New(HTTP_SERVER, ::HTTP_V2));
  75. if (parser == NULL) {
  76. return false;
  77. }
  78. protocol = HTTP_V2;
  79. resp->http_major = req->http_major = 2;
  80. resp->http_minor = req->http_minor = 0;
  81. parser->InitRequest(req.get());
  82. return true;
  83. }
  84. void Reset() {
  85. state = WANT_RECV;
  86. req->Reset();
  87. resp->Reset();
  88. parser->InitRequest(req.get());
  89. if (writer) {
  90. writer->Begin();
  91. }
  92. resetFlush();
  93. }
  94. int FeedRecvData(const char* data, size_t len);
  95. // @workflow: preprocessor -> api -> web -> postprocessor
  96. // @result: HttpRequest -> HttpResponse/file_cache_t
  97. int HandleHttpRequest();
  98. int GetSendData(char** data, size_t* len);
  99. // websocket
  100. bool SwitchWebSocket(hio_t* io, ws_session_type type = WS_SERVER);
  101. void WebSocketOnOpen() {
  102. ws_channel->status = hv::SocketChannel::CONNECTED;
  103. if (ws_service && ws_service->onopen) {
  104. ws_service->onopen(ws_channel, req->url);
  105. }
  106. }
  107. void WebSocketOnClose() {
  108. ws_channel->status = hv::SocketChannel::DISCONNECTED;
  109. if (ws_service && ws_service->onclose) {
  110. ws_service->onclose(ws_channel);
  111. }
  112. }
  113. private:
  114. HFile file; ///< file cache body
  115. uint64_t flush_timer;
  116. bool flushing_;
  117. int last_flush_size;
  118. uint64_t last_flush_time;
  119. void flushFile();
  120. void resetFlush();
  121. void onWrite(hv::Buffer* buf);
  122. int defaultRequestHandler();
  123. int defaultStaticHandler();
  124. int defaultErrorHandler();
  125. int customHttpHandler(const http_handler& handler);
  126. int invokeHttpHandler(const http_handler* handler);
  127. };
  128. #endif // HV_HTTP_HANDLER_H_