Http1Parser.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #ifndef HV_HTTP1_PARSER_H_
  2. #define HV_HTTP1_PARSER_H_
  3. #include "HttpParser.h"
  4. #include "http_parser.h"
  5. enum http_parser_state {
  6. HP_START_REQ_OR_RES,
  7. HP_MESSAGE_BEGIN,
  8. HP_URL,
  9. HP_STATUS,
  10. HP_HEADER_FIELD,
  11. HP_HEADER_VALUE,
  12. HP_HEADERS_COMPLETE,
  13. HP_CHUNK_HEADER,
  14. HP_BODY,
  15. HP_CHUNK_COMPLETE,
  16. HP_MESSAGE_COMPLETE
  17. };
  18. class Http1Parser : public HttpParser {
  19. public:
  20. static http_parser_settings* cbs;
  21. http_parser parser;
  22. int flags;
  23. http_parser_state state;
  24. HttpMessage* submited;
  25. HttpMessage* parsed;
  26. // tmp
  27. std::string url; // for on_url
  28. std::string header_field; // for on_header_field
  29. std::string header_value; // for on_header_value
  30. std::string sendbuf; // for GetSendData
  31. Http1Parser(http_session_type type = HTTP_CLIENT);
  32. virtual ~Http1Parser();
  33. void handle_header() {
  34. if (header_field.size() != 0 && header_value.size() != 0) {
  35. if (stricmp(header_field.c_str(), "Set-CooKie") == 0 ||
  36. stricmp(header_field.c_str(), "Cookie") == 0) {
  37. HttpCookie cookie;
  38. if (cookie.parse(header_value)) {
  39. parsed->cookies.emplace_back(cookie);
  40. }
  41. }
  42. parsed->headers[header_field] = header_value;
  43. header_field.clear();
  44. header_value.clear();
  45. }
  46. }
  47. virtual int GetSendData(char** data, size_t* len) {
  48. if (!submited) {
  49. *data = NULL;
  50. *len = 0;
  51. return 0;
  52. }
  53. sendbuf = submited->Dump(true, true);
  54. submited = NULL;
  55. *data = (char*)sendbuf.data();
  56. *len = sendbuf.size();
  57. return sendbuf.size();
  58. }
  59. virtual int FeedRecvData(const char* data, size_t len) {
  60. return http_parser_execute(&parser, cbs, data, len);
  61. }
  62. virtual int GetState() {
  63. return (int)state;
  64. }
  65. virtual bool WantRecv() {
  66. return state != HP_MESSAGE_COMPLETE;
  67. }
  68. virtual bool WantSend() {
  69. return state == HP_MESSAGE_COMPLETE;
  70. }
  71. virtual bool IsComplete() {
  72. return state == HP_MESSAGE_COMPLETE;
  73. }
  74. virtual int GetError() {
  75. return parser.http_errno;
  76. }
  77. virtual const char* StrError(int error) {
  78. return http_errno_description((enum http_errno)error);
  79. }
  80. // client
  81. // SubmitRequest -> while(GetSendData) {send} -> InitResponse -> do {recv -> FeedRecvData} while(WantRecv)
  82. virtual int SubmitRequest(HttpRequest* req) {
  83. submited = req;
  84. if (req) {
  85. if (req->method == HTTP_HEAD) {
  86. flags |= F_SKIPBODY;
  87. } else {
  88. flags &= ~F_SKIPBODY;
  89. }
  90. }
  91. return 0;
  92. }
  93. virtual int InitResponse(HttpResponse* res) {
  94. res->Reset();
  95. parsed = res;
  96. http_parser_init(&parser, HTTP_RESPONSE);
  97. url.clear();
  98. header_field.clear();
  99. header_value.clear();
  100. return 0;
  101. }
  102. // server
  103. // InitRequest -> do {recv -> FeedRecvData} while(WantRecv) -> SubmitResponse -> while(GetSendData) {send}
  104. virtual int InitRequest(HttpRequest* req) {
  105. req->Reset();
  106. parsed = req;
  107. http_parser_init(&parser, HTTP_REQUEST);
  108. state = HP_START_REQ_OR_RES;
  109. url.clear();
  110. header_field.clear();
  111. header_value.clear();
  112. return 0;
  113. }
  114. virtual int SubmitResponse(HttpResponse* res) {
  115. submited = res;
  116. return 0;
  117. }
  118. };
  119. #endif // HV_HTTP1_PARSER_H_