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