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