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