Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: net/tools/quic/spdy_balsa_utils.cc

Issue 2477703002: Remove now unused Balsa code. (Closed)
Patch Set: Rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/tools/quic/spdy_balsa_utils.h ('k') | net/tools/quic/spdy_balsa_utils_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/tools/quic/spdy_balsa_utils.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "net/base/linked_hash_map.h"
15 #include "net/quic/core/quic_flags.h"
16 #include "net/quic/core/spdy_utils.h"
17 #include "net/spdy/spdy_frame_builder.h"
18 #include "net/spdy/spdy_framer.h"
19 #include "net/spdy/spdy_protocol.h"
20 #include "net/tools/balsa/balsa_headers.h"
21 #include "url/gurl.h"
22
23 using base::StringPiece;
24 using base::StringPieceHash;
25 using std::make_pair;
26 using std::pair;
27 using std::string;
28
29 namespace net {
30 namespace {
31
32 const char kV4Host[] = ":authority";
33
34 const char kV3Host[] = ":host";
35 const char kV3Path[] = ":path";
36 const char kV3Scheme[] = ":scheme";
37 const char kV3Method[] = ":method";
38 const char kV3Status[] = ":status";
39 const char kV3Version[] = ":version";
40
41 void PopulateSpdyHeaderBlock(const BalsaHeaders& headers,
42 SpdyHeaderBlock* block,
43 bool allow_empty_values) {
44 using HeaderValuesMap =
45 linked_hash_map<StringPiece, std::vector<StringPiece>, StringPieceHash>;
46 std::deque<string> names;
47 HeaderValuesMap header_values_map;
48 // First, gather references to all values for each name.
49 for (BalsaHeaders::const_header_lines_iterator hi =
50 headers.header_lines_begin();
51 hi != headers.header_lines_end(); ++hi) {
52 if ((hi->second.length() == 0) && !allow_empty_values) {
53 DVLOG(1) << "Dropping empty header " << hi->first.as_string()
54 << " from headers";
55 continue;
56 }
57 const string name = base::ToLowerASCII(hi->first.as_string());
58 names.push_back(name);
59 header_values_map[name].push_back(hi->second);
60 }
61 // Then, write joined representations to the header block.
62 for (const auto& header : header_values_map) {
63 if (header.second.size() == 1) {
64 // Avoid string allocation for the single value case.
65 (*block)[header.first] = header.second[0];
66 } else {
67 StringPiece separator("\0", 1);
68 auto it = header.second.begin();
69 string value = it->as_string();
70 ++it;
71 for (; it != header.second.end(); ++it) {
72 separator.AppendToString(&value);
73 value.append(it->data(), it->size());
74 }
75 (*block)[header.first] = value;
76 }
77 }
78 }
79
80 void PopulateHttp2RequestHeaderBlock(const BalsaHeaders& headers,
81 const string& scheme,
82 const string& host_and_port,
83 const string& path,
84 SpdyHeaderBlock* block) {
85 PopulateSpdyHeaderBlock(headers, block, true);
86 StringPiece host_header = headers.GetHeader("Host");
87 if (!host_header.empty()) {
88 DCHECK(host_and_port.empty() || host_header == host_and_port);
89 block->insert(make_pair(kV4Host, host_header));
90 // PopulateSpdyHeaderBlock already added the "host" header,
91 // which is invalid for HTTP2.
92 block->erase("host");
93 } else {
94 block->insert(make_pair(kV4Host, host_and_port));
95 }
96 block->insert(make_pair(kV3Path, path));
97 block->insert(make_pair(kV3Scheme, scheme));
98
99 if (!headers.request_method().empty()) {
100 block->insert(make_pair(kV3Method, headers.request_method()));
101 }
102 }
103
104 void PopulateSpdyResponseHeaderBlock(SpdyMajorVersion version,
105 const BalsaHeaders& headers,
106 SpdyHeaderBlock* block) {
107 if (version <= SPDY3) {
108 string status = headers.response_code().as_string();
109 status.append(" ");
110 status.append(headers.response_reason_phrase().as_string());
111 (*block)[kV3Status] = status;
112 (*block)[kV3Version] = headers.response_version();
113 } else {
114 (*block)[kV3Status] = headers.response_code();
115 }
116
117 PopulateSpdyHeaderBlock(headers, block, true);
118 }
119
120 bool IsSpecialSpdyHeader(SpdyHeaderBlock::const_iterator header,
121 BalsaHeaders* headers) {
122 return header->first.empty() || /* header->second.empty() || */
123 header->first[0] == ':';
124 }
125
126 // The reason phrase should match regexp [\d\d\d [^\r\n]+]. If not, we will
127 // fail to parse it.
128 bool ParseReasonAndStatus(StringPiece status_and_reason,
129 BalsaHeaders* headers) {
130 int status;
131 if (!base::StringToInt(status_and_reason, &status)) {
132 return false;
133 }
134 headers->SetResponseCode(status_and_reason);
135 headers->SetResponseCode(status_and_reason);
136 headers->set_parsed_response_code(status);
137 return true;
138 }
139
140 // static
141 void SpdyHeadersToResponseHeaders(const SpdyHeaderBlock& header_block,
142 BalsaHeaders* request_headers) {
143 typedef SpdyHeaderBlock::const_iterator BlockIt;
144
145 BlockIt status_it = header_block.find(kV3Status);
146 BlockIt end_it = header_block.end();
147 if (status_it == end_it) {
148 return;
149 }
150
151 if (!ParseReasonAndStatus(status_it->second, request_headers)) {
152 return;
153 }
154
155 for (BlockIt it = header_block.begin(); it != header_block.end(); ++it) {
156 if (!IsSpecialSpdyHeader(it, request_headers)) {
157 if (it->second.empty()) {
158 request_headers->AppendHeader(it->first, it->second);
159 } else {
160 DVLOG(2) << "Splitting value: [" << it->second << "]"
161 << " for key: " << it->first;
162 for (string value :
163 base::SplitString(it->second, base::StringPiece("\0", 1),
164 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
165 DVLOG(2) << "AppendHeader(" << it->first << ", " << value << ")";
166 request_headers->AppendHeader(it->first, StringPiece(value));
167 }
168 }
169 }
170 }
171 }
172
173 // static
174 void SpdyHeadersToRequestHeaders(const SpdyHeaderBlock& header_block,
175 BalsaHeaders* request_headers) {
176 typedef SpdyHeaderBlock::const_iterator BlockIt;
177
178 BlockIt authority_it = header_block.find(kV4Host);
179 BlockIt host_it = header_block.find(kV3Host);
180 BlockIt method_it = header_block.find(kV3Method);
181 BlockIt path_it = header_block.find(kV3Path);
182 BlockIt scheme_it = header_block.find(kV3Scheme);
183 BlockIt end_it = header_block.end();
184
185 string method;
186 if (method_it == end_it) {
187 method = "GET";
188 } else {
189 method = method_it->second.as_string();
190 }
191 string uri;
192 if (scheme_it == end_it) {
193 uri += "https";
194 } else {
195 uri += scheme_it->second.as_string();
196 }
197 uri += "://";
198
199 if (authority_it != end_it) {
200 uri += authority_it->second.as_string();
201 request_headers->AppendHeader("host", authority_it->second);
202 } else if (host_it != end_it) {
203 uri += host_it->second.as_string();
204 request_headers->AppendHeader("host", host_it->second);
205 }
206
207 if (path_it == end_it) {
208 uri += "/";
209 } else {
210 uri += path_it->second.as_string();
211 }
212 request_headers->SetRequestFirstlineFromStringPieces(
213 method, uri, net::kHttp2VersionString);
214
215 for (BlockIt it = header_block.begin(); it != header_block.end(); ++it) {
216 if (!IsSpecialSpdyHeader(it, request_headers)) {
217 if (it->second.empty()) {
218 request_headers->AppendHeader(it->first, it->second);
219 } else {
220 DVLOG(2) << "Splitting value: [" << it->second << "]"
221 << " for key: " << it->first;
222 for (string value :
223 base::SplitString(it->second, base::StringPiece("\0", 1),
224 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
225 DVLOG(2) << "AppendHeader(" << it->first << ", " << value << ")";
226 request_headers->AppendHeader(it->first, StringPiece(value));
227 }
228 }
229 }
230 }
231 }
232
233 // static
234 void SpdyHeadersToBalsaHeaders(const SpdyHeaderBlock& block,
235 BalsaHeaders* headers,
236 bool isResponse) {
237 if (isResponse) {
238 SpdyHeadersToResponseHeaders(block, headers);
239 return;
240 }
241 SpdyHeadersToRequestHeaders(block, headers);
242 }
243
244 } // namespace
245
246 // static
247 SpdyHeaderBlock SpdyBalsaUtils::RequestHeadersToSpdyHeaders(
248 const BalsaHeaders& request_headers) {
249 string scheme;
250 string host_and_port;
251 string path;
252
253 string url = request_headers.request_uri().as_string();
254 if (url.empty() || url[0] == '/') {
255 path = url;
256 } else {
257 std::unique_ptr<GURL> request_uri(new GURL(url));
258 if (request_headers.request_method() == "CONNECT") {
259 path = url;
260 } else {
261 path = request_uri->path();
262 if (!request_uri->query().empty()) {
263 path = path + "?" + request_uri->query();
264 }
265 host_and_port = request_uri->host();
266 scheme = request_uri->scheme();
267 }
268 }
269
270 if (scheme.empty()) {
271 if (request_headers.HasHeader("Scheme")) {
272 request_headers.GetAllOfHeaderAsString("Scheme", &scheme);
273 } else {
274 // Requests must contain a :scheme header, and unless another scheme is
275 // detected, https is assumed.
276 scheme = "https";
277 }
278 }
279
280 SpdyHeaderBlock block;
281 PopulateHttp2RequestHeaderBlock(request_headers, scheme, host_and_port, path,
282 &block);
283
284 // If a "Scheme" header existed in request_headers, it would have been
285 // propagated to |block|.
286 block.erase("scheme");
287 return block;
288 }
289
290 // static
291 SpdyHeaderBlock SpdyBalsaUtils::ResponseHeadersToSpdyHeaders(
292 const BalsaHeaders& response_headers) {
293 SpdyHeaderBlock block;
294 PopulateSpdyResponseHeaderBlock(HTTP2, response_headers, &block);
295 return block;
296 }
297
298 // static
299 string SpdyBalsaUtils::SerializeResponseHeaders(
300 const BalsaHeaders& response_headers) {
301 SpdyHeaderBlock block = ResponseHeadersToSpdyHeaders(response_headers);
302
303 return net::SpdyUtils::SerializeUncompressedHeaders(block);
304 }
305
306 // static
307 void SpdyBalsaUtils::SpdyHeadersToResponseHeaders(const SpdyHeaderBlock& block,
308 BalsaHeaders* headers) {
309 SpdyHeadersToBalsaHeaders(block, headers, true);
310 }
311
312 // static
313 void SpdyBalsaUtils::SpdyHeadersToRequestHeaders(const SpdyHeaderBlock& block,
314 BalsaHeaders* headers) {
315 SpdyHeadersToBalsaHeaders(block, headers, false);
316 }
317
318 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/spdy_balsa_utils.h ('k') | net/tools/quic/spdy_balsa_utils_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698