HttpHandler.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. WANT_CLOSE,
  26. } state;
  27. // errno
  28. int error;
  29. // flags
  30. unsigned ssl: 1;
  31. unsigned keepalive: 1;
  32. unsigned proxy: 1;
  33. unsigned upgrade: 1;
  34. // peeraddr
  35. char ip[64];
  36. int port;
  37. // for log
  38. long pid;
  39. long tid;
  40. // for http
  41. hio_t *io;
  42. HttpService *service;
  43. HttpRequestPtr req;
  44. HttpResponsePtr resp;
  45. HttpResponseWriterPtr writer;
  46. HttpParserPtr parser;
  47. HttpContextPtr ctx;
  48. http_handler* api_handler;
  49. // for GetSendData
  50. std::string header;
  51. // std::string body;
  52. // for websocket
  53. WebSocketService* ws_service;
  54. WebSocketChannelPtr ws_channel;
  55. WebSocketParserPtr ws_parser;
  56. uint64_t last_send_ping_time;
  57. uint64_t last_recv_pong_time;
  58. // for sendfile
  59. FileCache *files;
  60. file_cache_ptr fc; // cache small file
  61. struct LargeFile : public HFile {
  62. HBuf buf;
  63. uint64_t timer;
  64. } *file; // for large file
  65. HttpHandler(hio_t* io = NULL);
  66. ~HttpHandler();
  67. bool Init(int http_version = 1);
  68. void Reset();
  69. void Close();
  70. /* @workflow:
  71. * HttpServer::on_recv -> HttpHandler::FeedRecvData -> Init -> HttpParser::InitRequest -> HttpRequest::http_cb ->
  72. * onHeadersComplete -> proxy ? proxyConnect -> hio_setup_upstream :
  73. * onMessageComplete -> upgrade ? SwitchHTTP2 / SwitchWebSocket : HandleHttpRequest -> HttpParser::SubmitResponse ->
  74. * SendHttpResponse -> while(GetSendData) hio_write ->
  75. * keepalive ? Reset : Close -> hio_close
  76. *
  77. * @return
  78. * == len: ok
  79. * == 0: WANT_CLOSE
  80. * < 0: error
  81. */
  82. int FeedRecvData(const char* data, size_t len);
  83. /* @workflow:
  84. * preprocessor -> middleware -> processor -> postprocessor
  85. *
  86. * @return status_code
  87. * == 0: HANDLE_CONTINUE
  88. * != 0: HANDLE_END
  89. */
  90. int HandleHttpRequest();
  91. int GetSendData(char** data, size_t* len);
  92. int SendHttpResponse();
  93. int SendHttpStatusResponse(http_status status_code);
  94. // HTTP2
  95. bool SwitchHTTP2();
  96. // websocket
  97. bool SwitchWebSocket();
  98. void WebSocketOnOpen() {
  99. ws_channel->status = hv::SocketChannel::CONNECTED;
  100. if (ws_service && ws_service->onopen) {
  101. ws_service->onopen(ws_channel, req);
  102. }
  103. }
  104. void WebSocketOnClose() {
  105. ws_channel->status = hv::SocketChannel::DISCONNECTED;
  106. if (ws_service && ws_service->onclose) {
  107. ws_service->onclose(ws_channel);
  108. }
  109. }
  110. private:
  111. const HttpContextPtr& getHttpContext();
  112. // http_cb
  113. void onHeadersComplete();
  114. void onMessageComplete();
  115. // default handlers
  116. int defaultRequestHandler();
  117. int defaultStaticHandler();
  118. int defaultLargeFileHandler();
  119. int defaultErrorHandler();
  120. int customHttpHandler(const http_handler& handler);
  121. int invokeHttpHandler(const http_handler* handler);
  122. // sendfile
  123. int openFile(const char* filepath);
  124. int sendFile();
  125. void closeFile();
  126. bool isFileOpened();
  127. // proxy
  128. int proxyConnect(const std::string& url);
  129. static void onProxyConnect(hio_t* upstream_io);
  130. static void onProxyClose(hio_t* upstream_io);
  131. };
  132. #endif // HV_HTTP_HANDLER_H_