1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file |
3 | // distributed with this work for additional information |
4 | // regarding copyright ownership. The ASF licenses this file |
5 | // to you under the Apache License, Version 2.0 (the |
6 | // "License"); you may not use this file except in compliance |
7 | // with the License. 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, |
12 | // software distributed under the License is distributed on an |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | // KIND, either express or implied. See the License for the |
15 | // specific language governing permissions and limitations |
16 | // under the License. |
17 | |
18 | |
19 | #ifndef BRPC_HTTP_HEADER_H |
20 | #define |
21 | |
22 | #include "butil/strings/string_piece.h" // StringPiece |
23 | #include "butil/containers/case_ignored_flat_map.h" |
24 | #include "brpc/uri.h" // URI |
25 | #include "brpc/http_method.h" // HttpMethod |
26 | #include "brpc/http_status_code.h" |
27 | #include "brpc/http2.h" |
28 | |
29 | // To rpc developers: DON'T put impl. details here, use opaque pointers instead. |
30 | |
31 | |
32 | namespace brpc { |
33 | class InputMessageBase; |
34 | namespace policy { |
35 | void ProcessHttpRequest(InputMessageBase *msg); |
36 | class H2StreamContext; |
37 | } |
38 | |
39 | // Non-body part of a HTTP message. |
40 | class { |
41 | public: |
42 | typedef butil::CaseIgnoredFlatMap<std::string> ; |
43 | typedef HeaderMap::const_iterator ; |
44 | |
45 | (); |
46 | |
47 | // Exchange internal fields with another HttpHeader. |
48 | void (HttpHeader &rhs); |
49 | |
50 | // Reset internal fields as if they're just default-constructed. |
51 | void (); |
52 | |
53 | // Get http version, 1.1 by default. |
54 | int () const { return _version.first; } |
55 | int () const { return _version.second; } |
56 | // Change the http version |
57 | void (int http_major, int http_minor) |
58 | { _version = std::make_pair(http_major, http_minor); } |
59 | |
60 | // True if version of http is earlier than 1.1 |
61 | bool () const |
62 | { return (major_version() * 10000 + minor_version()) <= 10000; } |
63 | |
64 | // True if the message is from HTTP2. |
65 | bool () const { return major_version() == 2; } |
66 | |
67 | // Get/set "Content-Type". Notice that you can't get "Content-Type" |
68 | // via GetHeader(). |
69 | // possible values: "text/plain", "application/json" ... |
70 | const std::string& () const { return _content_type; } |
71 | void (const std::string& type) { _content_type = type; } |
72 | void (const char* type) { _content_type = type; } |
73 | std::string& () { return _content_type; } |
74 | |
75 | // Get value of a header which is case-insensitive according to: |
76 | // https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 |
77 | // Namely, GetHeader("log-id"), GetHeader("Log-Id"), GetHeader("LOG-ID") |
78 | // point to the same value. |
79 | // Return pointer to the value, NULL on not found. |
80 | // NOTE: Not work for "Content-Type", call content_type() instead. |
81 | const std::string* (const char* key) const |
82 | { return _headers.seek(key); } |
83 | const std::string* (const std::string& key) const |
84 | { return _headers.seek(key); } |
85 | |
86 | // Set value of a header. |
87 | // NOTE: Not work for "Content-Type", call set_content_type() instead. |
88 | void (const std::string& key, const std::string& value) |
89 | { GetOrAddHeader(key) = value; } |
90 | |
91 | // Remove a header. |
92 | void (const char* key) { _headers.erase(key); } |
93 | void (const std::string& key) { _headers.erase(key); } |
94 | |
95 | // Append value to a header. If the header already exists, separate |
96 | // old value and new value with comma(,) according to: |
97 | // https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 |
98 | void (const std::string& key, const butil::StringPiece& value); |
99 | |
100 | // Get header iterators which are invalidated after calling AppendHeader() |
101 | HeaderIterator () const { return _headers.begin(); } |
102 | HeaderIterator () const { return _headers.end(); } |
103 | // #headers |
104 | size_t () const { return _headers.size(); } |
105 | |
106 | // Get the URI object, check src/brpc/uri.h for details. |
107 | const URI& () const { return _uri; } |
108 | URI& () { return _uri; } |
109 | |
110 | // Get/set http method. |
111 | HttpMethod () const { return _method; } |
112 | void (const HttpMethod method) { _method = method; } |
113 | |
114 | // Get/set status-code and reason-phrase. Notice that the const char* |
115 | // returned by reason_phrase() will be invalidated after next call to |
116 | // set_status_code(). |
117 | int () const { return _status_code; } |
118 | const char* () const; |
119 | void (int status_code); |
120 | |
121 | // The URL path removed with matched prefix. |
122 | // NOTE: always normalized and NOT started with /. |
123 | // |
124 | // Accessing HttpService.Echo |
125 | // [URL] [unresolved_path] |
126 | // "/HttpService/Echo" "" |
127 | // "/HttpService/Echo/Foo" "Foo" |
128 | // "/HttpService/Echo/Foo/Bar" "Foo/Bar" |
129 | // "/HttpService//Echo///Foo//" "Foo" |
130 | // |
131 | // Accessing FileService.default_method: |
132 | // [URL] [unresolved_path] |
133 | // "/FileService" "" |
134 | // "/FileService/123.txt" "123.txt" |
135 | // "/FileService/mydir/123.txt" "mydir/123.txt" |
136 | // "/FileService//mydir///123.txt//" "mydir/123.txt" |
137 | const std::string& () const { return _unresolved_path; } |
138 | |
139 | private: |
140 | friend class HttpMessage; |
141 | friend class HttpMessageSerializer; |
142 | friend class policy::H2StreamContext; |
143 | friend void policy::ProcessHttpRequest(InputMessageBase *msg); |
144 | |
145 | std::string& (const std::string& key) { |
146 | if (!_headers.initialized()) { |
147 | _headers.init(29); |
148 | } |
149 | return _headers[key]; |
150 | } |
151 | |
152 | HeaderMap ; |
153 | URI ; |
154 | int ; |
155 | HttpMethod ; |
156 | std::string ; |
157 | std::string ; |
158 | std::pair<int, int> ; |
159 | }; |
160 | |
161 | const HttpHeader& (); |
162 | |
163 | } // namespace brpc |
164 | |
165 | |
166 | #endif //BRPC_HTTP_HEADER_H |
167 | |