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 
19 #ifndef GRPC_SRC_CORE_LIB_HTTP_PARSER_H
20 #define GRPC_SRC_CORE_LIB_HTTP_PARSER_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <stddef.h>
25 #include <stdint.h>
26 
27 #include <grpc/slice.h>
28 
29 #include "src/core/lib/debug/trace.h"
30 #include "src/core/lib/iomgr/error.h"
31 
32 // Maximum length of a header string of the form 'Key: Value\r\n'
33 #define GRPC_HTTP_PARSER_MAX_HEADER_LENGTH 4096
34 
35 // A single header to be passed in a request
36 typedef struct grpc_http_header {
37   char* key;
38   char* value;
39 } grpc_http_header;
40 
41 typedef enum {
42   GRPC_HTTP_FIRST_LINE,
43   GRPC_HTTP_HEADERS,
44   GRPC_HTTP_BODY,
45   GRPC_HTTP_TRAILERS,
46   GRPC_HTTP_END,
47 } grpc_http_parser_state;
48 
49 typedef enum {
50   GRPC_HTTP_CHUNKED_PLAIN,
51   GRPC_HTTP_CHUNKED_LENGTH,
52   GRPC_HTTP_CHUNKED_IGNORE_ALL_UNTIL_LF,
53   GRPC_HTTP_CHUNKED_BODY,
54   GRPC_HTTP_CHUNKED_CONSUME_LF,
55 } grpc_http_parser_chunked_state;
56 
57 typedef enum {
58   GRPC_HTTP_HTTP10,
59   GRPC_HTTP_HTTP11,
60   GRPC_HTTP_HTTP20,
61 } grpc_http_version;
62 
63 typedef enum {
64   GRPC_HTTP_RESPONSE,
65   GRPC_HTTP_REQUEST,
66 } grpc_http_type;
67 
68 // A request
69 typedef struct grpc_http_request {
70   // Method of the request (e.g. GET, POST)
71   char* method;
72   // The path of the resource to fetch (only used for parsed requests)
73   char* path;
74   // HTTP version to use
75   grpc_http_version version;
76   // Headers attached to the request
77   size_t hdr_count;
78   grpc_http_header* hdrs;
79   // Body: length and contents; contents are NOT null-terminated
80   size_t body_length;
81   char* body;
82 } grpc_http_request;
83 
84 // A response
85 typedef struct grpc_http_response {
86   // HTTP status code
87   int status = 0;
88   // Headers: count and key/values
89   size_t hdr_count = 0;
90   grpc_http_header* hdrs = nullptr;
91   // Body: length and contents; contents are NOT null-terminated
92   size_t body_length = 0;
93   // State of the chunked parser. Only valid for the response.
94   grpc_http_parser_chunked_state chunked_state = GRPC_HTTP_CHUNKED_PLAIN;
95   size_t chunk_length = 0;
96   char* body = nullptr;
97 } grpc_http_response;
98 
99 struct grpc_http_parser {
100   grpc_http_parser_state state;
101   grpc_http_type type;
102 
103   union {
104     grpc_http_response* response;
105     grpc_http_request* request;
106     void* request_or_response;
107   } http;
108   size_t body_capacity;
109   size_t hdr_capacity;
110 
111   uint8_t cur_line[GRPC_HTTP_PARSER_MAX_HEADER_LENGTH];
112   size_t cur_line_length;
113   size_t cur_line_end_length;
114 };
115 void grpc_http_parser_init(grpc_http_parser* parser, grpc_http_type type,
116                            void* request_or_response);
117 void grpc_http_parser_destroy(grpc_http_parser* parser);
118 
119 // Sets \a start_of_body to the offset in \a slice of the start of the body.
120 grpc_error_handle grpc_http_parser_parse(grpc_http_parser* parser,
121                                          const grpc_slice& slice,
122                                          size_t* start_of_body);
123 grpc_error_handle grpc_http_parser_eof(grpc_http_parser* parser);
124 
125 void grpc_http_request_destroy(grpc_http_request* request);
126 void grpc_http_response_destroy(grpc_http_response* response);
127 
128 extern grpc_core::TraceFlag grpc_http1_trace;
129 
130 #endif  // GRPC_SRC_CORE_LIB_HTTP_PARSER_H
131