parser.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <grpc/support/port_platform.h>
  19. #include "src/core/lib/http/parser.h"
  20. #include <stdbool.h>
  21. #include <string.h>
  22. #include <grpc/support/alloc.h>
  23. #include <grpc/support/log.h>
  24. #include "src/core/lib/gpr/useful.h"
  25. grpc_core::TraceFlag grpc_http1_trace(false, "http1");
  26. static char* buf2str(void* buffer, size_t length) {
  27. char* out = static_cast<char*>(gpr_malloc(length + 1));
  28. memcpy(out, buffer, length);
  29. out[length] = 0;
  30. return out;
  31. }
  32. static grpc_error* handle_response_line(grpc_http_parser* parser) {
  33. uint8_t* beg = parser->cur_line;
  34. uint8_t* cur = beg;
  35. uint8_t* end = beg + parser->cur_line_length;
  36. if (cur == end || *cur++ != 'H') {
  37. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
  38. }
  39. if (cur == end || *cur++ != 'T') {
  40. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
  41. }
  42. if (cur == end || *cur++ != 'T') {
  43. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
  44. }
  45. if (cur == end || *cur++ != 'P') {
  46. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
  47. }
  48. if (cur == end || *cur++ != '/') {
  49. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
  50. }
  51. if (cur == end || *cur++ != '1') {
  52. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '1'");
  53. }
  54. if (cur == end || *cur++ != '.') {
  55. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '.'");
  56. }
  57. if (cur == end || *cur < '0' || *cur++ > '1') {
  58. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  59. "Expected HTTP/1.0 or HTTP/1.1");
  60. }
  61. if (cur == end || *cur++ != ' ') {
  62. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
  63. }
  64. if (cur == end || *cur < '1' || *cur++ > '9') {
  65. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
  66. }
  67. if (cur == end || *cur < '0' || *cur++ > '9') {
  68. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
  69. }
  70. if (cur == end || *cur < '0' || *cur++ > '9') {
  71. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
  72. }
  73. parser->http.response->status =
  74. (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0');
  75. if (cur == end || *cur++ != ' ') {
  76. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
  77. }
  78. /* we don't really care about the status code message */
  79. return GRPC_ERROR_NONE;
  80. }
  81. static grpc_error* handle_request_line(grpc_http_parser* parser) {
  82. uint8_t* beg = parser->cur_line;
  83. uint8_t* cur = beg;
  84. uint8_t* end = beg + parser->cur_line_length;
  85. uint8_t vers_major = 0;
  86. uint8_t vers_minor = 0;
  87. while (cur != end && *cur++ != ' ') {
  88. }
  89. if (cur == end) {
  90. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  91. "No method on HTTP request line");
  92. }
  93. parser->http.request->method =
  94. buf2str(beg, static_cast<size_t>(cur - beg - 1));
  95. beg = cur;
  96. while (cur != end && *cur++ != ' ') {
  97. }
  98. if (cur == end) {
  99. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No path on HTTP request line");
  100. }
  101. parser->http.request->path = buf2str(beg, static_cast<size_t>(cur - beg - 1));
  102. if (cur == end || *cur++ != 'H') {
  103. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
  104. }
  105. if (cur == end || *cur++ != 'T') {
  106. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
  107. }
  108. if (cur == end || *cur++ != 'T') {
  109. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
  110. }
  111. if (cur == end || *cur++ != 'P') {
  112. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
  113. }
  114. if (cur == end || *cur++ != '/') {
  115. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
  116. }
  117. vers_major = static_cast<uint8_t>(*cur++ - '1' + 1);
  118. ++cur;
  119. if (cur == end) {
  120. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  121. "End of line in HTTP version string");
  122. }
  123. vers_minor = static_cast<uint8_t>(*cur++ - '1' + 1);
  124. if (vers_major == 1) {
  125. if (vers_minor == 0) {
  126. parser->http.request->version = GRPC_HTTP_HTTP10;
  127. } else if (vers_minor == 1) {
  128. parser->http.request->version = GRPC_HTTP_HTTP11;
  129. } else {
  130. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  131. "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
  132. }
  133. } else if (vers_major == 2) {
  134. if (vers_minor == 0) {
  135. parser->http.request->version = GRPC_HTTP_HTTP20;
  136. } else {
  137. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  138. "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
  139. }
  140. } else {
  141. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  142. "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
  143. }
  144. return GRPC_ERROR_NONE;
  145. }
  146. static grpc_error* handle_first_line(grpc_http_parser* parser) {
  147. switch (parser->type) {
  148. case GRPC_HTTP_REQUEST:
  149. return handle_request_line(parser);
  150. case GRPC_HTTP_RESPONSE:
  151. return handle_response_line(parser);
  152. }
  153. GPR_UNREACHABLE_CODE(
  154. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
  155. }
  156. static grpc_error* add_header(grpc_http_parser* parser) {
  157. uint8_t* beg = parser->cur_line;
  158. uint8_t* cur = beg;
  159. uint8_t* end = beg + parser->cur_line_length;
  160. size_t* hdr_count = nullptr;
  161. grpc_http_header** hdrs = nullptr;
  162. grpc_http_header hdr = {nullptr, nullptr};
  163. grpc_error* error = GRPC_ERROR_NONE;
  164. GPR_ASSERT(cur != end);
  165. if (*cur == ' ' || *cur == '\t') {
  166. error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  167. "Continued header lines not supported yet");
  168. goto done;
  169. }
  170. while (cur != end && *cur != ':') {
  171. cur++;
  172. }
  173. if (cur == end) {
  174. error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  175. "Didn't find ':' in header string");
  176. goto done;
  177. }
  178. GPR_ASSERT(cur >= beg);
  179. hdr.key = buf2str(beg, static_cast<size_t>(cur - beg));
  180. cur++; /* skip : */
  181. while (cur != end && (*cur == ' ' || *cur == '\t')) {
  182. cur++;
  183. }
  184. GPR_ASSERT((size_t)(end - cur) >= parser->cur_line_end_length);
  185. hdr.value = buf2str(
  186. cur, static_cast<size_t>(end - cur) - parser->cur_line_end_length);
  187. switch (parser->type) {
  188. case GRPC_HTTP_RESPONSE:
  189. hdr_count = &parser->http.response->hdr_count;
  190. hdrs = &parser->http.response->hdrs;
  191. break;
  192. case GRPC_HTTP_REQUEST:
  193. hdr_count = &parser->http.request->hdr_count;
  194. hdrs = &parser->http.request->hdrs;
  195. break;
  196. }
  197. if (*hdr_count == parser->hdr_capacity) {
  198. parser->hdr_capacity =
  199. GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2);
  200. *hdrs = static_cast<grpc_http_header*>(
  201. gpr_realloc(*hdrs, parser->hdr_capacity * sizeof(**hdrs)));
  202. }
  203. (*hdrs)[(*hdr_count)++] = hdr;
  204. done:
  205. if (error != GRPC_ERROR_NONE) {
  206. gpr_free(hdr.key);
  207. gpr_free(hdr.value);
  208. }
  209. return error;
  210. }
  211. static grpc_error* finish_line(grpc_http_parser* parser,
  212. bool* found_body_start) {
  213. grpc_error* err;
  214. switch (parser->state) {
  215. case GRPC_HTTP_FIRST_LINE:
  216. err = handle_first_line(parser);
  217. if (err != GRPC_ERROR_NONE) return err;
  218. parser->state = GRPC_HTTP_HEADERS;
  219. break;
  220. case GRPC_HTTP_HEADERS:
  221. if (parser->cur_line_length == parser->cur_line_end_length) {
  222. parser->state = GRPC_HTTP_BODY;
  223. *found_body_start = true;
  224. break;
  225. }
  226. err = add_header(parser);
  227. if (err != GRPC_ERROR_NONE) {
  228. return err;
  229. }
  230. break;
  231. case GRPC_HTTP_BODY:
  232. GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  233. "Should never reach here"));
  234. }
  235. parser->cur_line_length = 0;
  236. return GRPC_ERROR_NONE;
  237. }
  238. static grpc_error* addbyte_body(grpc_http_parser* parser, uint8_t byte) {
  239. size_t* body_length = nullptr;
  240. char** body = nullptr;
  241. if (parser->type == GRPC_HTTP_RESPONSE) {
  242. body_length = &parser->http.response->body_length;
  243. body = &parser->http.response->body;
  244. } else if (parser->type == GRPC_HTTP_REQUEST) {
  245. body_length = &parser->http.request->body_length;
  246. body = &parser->http.request->body;
  247. } else {
  248. GPR_UNREACHABLE_CODE(
  249. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
  250. }
  251. if (*body_length == parser->body_capacity) {
  252. parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2);
  253. *body = static_cast<char*>(gpr_realloc(*body, parser->body_capacity));
  254. }
  255. (*body)[*body_length] = static_cast<char>(byte);
  256. (*body_length)++;
  257. return GRPC_ERROR_NONE;
  258. }
  259. static bool check_line(grpc_http_parser* parser) {
  260. if (parser->cur_line_length >= 2 &&
  261. parser->cur_line[parser->cur_line_length - 2] == '\r' &&
  262. parser->cur_line[parser->cur_line_length - 1] == '\n') {
  263. return true;
  264. }
  265. // HTTP request with \n\r line termiantors.
  266. else if (parser->cur_line_length >= 2 &&
  267. parser->cur_line[parser->cur_line_length - 2] == '\n' &&
  268. parser->cur_line[parser->cur_line_length - 1] == '\r') {
  269. return true;
  270. }
  271. // HTTP request with only \n line terminators.
  272. else if (parser->cur_line_length >= 1 &&
  273. parser->cur_line[parser->cur_line_length - 1] == '\n') {
  274. parser->cur_line_end_length = 1;
  275. return true;
  276. }
  277. return false;
  278. }
  279. static grpc_error* addbyte(grpc_http_parser* parser, uint8_t byte,
  280. bool* found_body_start) {
  281. switch (parser->state) {
  282. case GRPC_HTTP_FIRST_LINE:
  283. case GRPC_HTTP_HEADERS:
  284. if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) {
  285. if (GRPC_TRACE_FLAG_ENABLED(grpc_http1_trace)) {
  286. gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
  287. GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
  288. }
  289. return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
  290. "HTTP header max line length exceeded");
  291. }
  292. parser->cur_line[parser->cur_line_length] = byte;
  293. parser->cur_line_length++;
  294. if (check_line(parser)) {
  295. return finish_line(parser, found_body_start);
  296. }
  297. return GRPC_ERROR_NONE;
  298. case GRPC_HTTP_BODY:
  299. return addbyte_body(parser, byte);
  300. }
  301. GPR_UNREACHABLE_CODE(return GRPC_ERROR_NONE);
  302. }
  303. void grpc_http_parser_init(grpc_http_parser* parser, grpc_http_type type,
  304. void* request_or_response) {
  305. memset(parser, 0, sizeof(*parser));
  306. parser->state = GRPC_HTTP_FIRST_LINE;
  307. parser->type = type;
  308. parser->http.request_or_response = request_or_response;
  309. parser->cur_line_end_length = 2;
  310. }
  311. void grpc_http_parser_destroy(grpc_http_parser* /*parser*/) {}
  312. void grpc_http_request_destroy(grpc_http_request* request) {
  313. size_t i;
  314. gpr_free(request->body);
  315. for (i = 0; i < request->hdr_count; i++) {
  316. gpr_free(request->hdrs[i].key);
  317. gpr_free(request->hdrs[i].value);
  318. }
  319. gpr_free(request->hdrs);
  320. gpr_free(request->method);
  321. gpr_free(request->path);
  322. }
  323. void grpc_http_response_destroy(grpc_http_response* response) {
  324. size_t i;
  325. gpr_free(response->body);
  326. for (i = 0; i < response->hdr_count; i++) {
  327. gpr_free(response->hdrs[i].key);
  328. gpr_free(response->hdrs[i].value);
  329. }
  330. gpr_free(response->hdrs);
  331. }
  332. grpc_error* grpc_http_parser_parse(grpc_http_parser* parser,
  333. const grpc_slice& slice,
  334. size_t* start_of_body) {
  335. for (size_t i = 0; i < GRPC_SLICE_LENGTH(slice); i++) {
  336. bool found_body_start = false;
  337. grpc_error* err =
  338. addbyte(parser, GRPC_SLICE_START_PTR(slice)[i], &found_body_start);
  339. if (err != GRPC_ERROR_NONE) return err;
  340. if (found_body_start && start_of_body != nullptr) *start_of_body = i + 1;
  341. }
  342. return GRPC_ERROR_NONE;
  343. }
  344. grpc_error* grpc_http_parser_eof(grpc_http_parser* parser) {
  345. if (parser->state != GRPC_HTTP_BODY) {
  346. return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Did not finish headers");
  347. }
  348. return GRPC_ERROR_NONE;
  349. }