1
0

Http1Parser.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "Http1Parser.h"
  2. #define MAX_CONTENT_LENGTH (1 << 24) // 16M
  3. static int on_url(http_parser* parser, const char *at, size_t length);
  4. static int on_status(http_parser* parser, const char *at, size_t length);
  5. static int on_header_field(http_parser* parser, const char *at, size_t length);
  6. static int on_header_value(http_parser* parser, const char *at, size_t length);
  7. static int on_body(http_parser* parser, const char *at, size_t length);
  8. static int on_message_begin(http_parser* parser);
  9. static int on_headers_complete(http_parser* parser);
  10. static int on_message_complete(http_parser* parser);
  11. static int on_chunk_header(http_parser* parser);
  12. static int on_chunk_complete(http_parser* parser);
  13. http_parser_settings Http1Parser::cbs = {
  14. on_message_begin,
  15. on_url,
  16. on_status,
  17. on_header_field,
  18. on_header_value,
  19. on_headers_complete,
  20. on_body,
  21. on_message_complete,
  22. on_chunk_header,
  23. on_chunk_complete
  24. };
  25. Http1Parser::Http1Parser(http_session_type type) {
  26. http_parser_init(&parser, HTTP_BOTH);
  27. parser.data = this;
  28. flags = 0;
  29. state = HP_START_REQ_OR_RES;
  30. submited = NULL;
  31. parsed = NULL;
  32. }
  33. Http1Parser::~Http1Parser() {
  34. }
  35. int on_url(http_parser* parser, const char *at, size_t length) {
  36. printd("on_url:%.*s\n", (int)length, at);
  37. Http1Parser* hp = (Http1Parser*)parser->data;
  38. hp->state = HP_URL;
  39. hp->url.append(at, length);
  40. return 0;
  41. }
  42. int on_status(http_parser* parser, const char *at, size_t length) {
  43. printd("on_status:%d %.*s\n", (int)parser->status_code, (int)length, at);
  44. Http1Parser* hp = (Http1Parser*)parser->data;
  45. hp->state = HP_STATUS;
  46. return 0;
  47. }
  48. int on_header_field(http_parser* parser, const char *at, size_t length) {
  49. printd("on_header_field:%.*s\n", (int)length, at);
  50. Http1Parser* hp = (Http1Parser*)parser->data;
  51. if (hp->state != HP_HEADER_FIELD) {
  52. hp->handle_header();
  53. }
  54. hp->state = HP_HEADER_FIELD;
  55. hp->header_field.append(at, length);
  56. return 0;
  57. }
  58. int on_header_value(http_parser* parser, const char *at, size_t length) {
  59. printd("on_header_value:%.*s\n", (int)length, at);
  60. Http1Parser* hp = (Http1Parser*)parser->data;
  61. hp->state = HP_HEADER_VALUE;
  62. hp->header_value.append(at, length);
  63. return 0;
  64. }
  65. int on_body(http_parser* parser, const char *at, size_t length) {
  66. printd("on_body:%d\n", (int)length);
  67. // printd("on_body:%.*s\n", (int)length, at);
  68. Http1Parser* hp = (Http1Parser*)parser->data;
  69. hp->state = HP_BODY;
  70. if (hp->invokeHttpCb(at, length) != 0) {
  71. hp->parsed->body.append(at, length);
  72. }
  73. return 0;
  74. }
  75. int on_message_begin(http_parser* parser) {
  76. printd("on_message_begin\n");
  77. Http1Parser* hp = (Http1Parser*)parser->data;
  78. hp->state = HP_MESSAGE_BEGIN;
  79. hp->invokeHttpCb();
  80. return 0;
  81. }
  82. int on_headers_complete(http_parser* parser) {
  83. printd("on_headers_complete\n");
  84. Http1Parser* hp = (Http1Parser*)parser->data;
  85. hp->handle_header();
  86. bool skip_body = false;
  87. hp->parsed->http_major = parser->http_major;
  88. hp->parsed->http_minor = parser->http_minor;
  89. if (hp->parsed->type == HTTP_REQUEST) {
  90. HttpRequest* req = (HttpRequest*)hp->parsed;
  91. req->method = (http_method)parser->method;
  92. req->url = hp->url;
  93. }
  94. else if (hp->parsed->type == HTTP_RESPONSE) {
  95. HttpResponse* res = (HttpResponse*)hp->parsed;
  96. res->status_code = (http_status)parser->status_code;
  97. // response to HEAD
  98. if (hp->flags & F_SKIPBODY) {
  99. skip_body = true;
  100. }
  101. }
  102. auto iter = hp->parsed->headers.find("content-type");
  103. if (iter != hp->parsed->headers.end()) {
  104. hp->parsed->content_type = http_content_type_enum(iter->second.c_str());
  105. }
  106. iter = hp->parsed->headers.find("content-length");
  107. if (iter != hp->parsed->headers.end()) {
  108. size_t content_length = atoll(iter->second.c_str());
  109. hp->parsed->content_length = content_length;
  110. size_t reserve_length = MIN(content_length + 1, MAX_CONTENT_LENGTH);
  111. if ((!skip_body) && reserve_length > hp->parsed->body.capacity()) {
  112. hp->parsed->body.reserve(reserve_length);
  113. }
  114. }
  115. hp->state = HP_HEADERS_COMPLETE;
  116. hp->invokeHttpCb();
  117. return skip_body ? 1 : 0;
  118. }
  119. int on_message_complete(http_parser* parser) {
  120. printd("on_message_complete\n");
  121. Http1Parser* hp = (Http1Parser*)parser->data;
  122. hp->state = HP_MESSAGE_COMPLETE;
  123. hp->invokeHttpCb();
  124. return 0;
  125. }
  126. int on_chunk_header(http_parser* parser) {
  127. printd("on_chunk_header:%llu\n", parser->content_length);
  128. Http1Parser* hp = (Http1Parser*)parser->data;
  129. int chunk_size = parser->content_length;
  130. int reserve_size = MIN(chunk_size + 1, MAX_CONTENT_LENGTH);
  131. if (reserve_size > hp->parsed->body.capacity()) {
  132. hp->parsed->body.reserve(reserve_size);
  133. }
  134. hp->state = HP_CHUNK_HEADER;
  135. hp->invokeHttpCb(NULL, chunk_size);
  136. return 0;
  137. }
  138. int on_chunk_complete(http_parser* parser) {
  139. printd("on_chunk_complete\n");
  140. Http1Parser* hp = (Http1Parser*)parser->data;
  141. hp->state = HP_CHUNK_COMPLETE;
  142. hp->invokeHttpCb();
  143. return 0;
  144. }