1
0

Http1Parser.cpp 5.5 KB

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