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

Side by Side Diff: net/spdy/spdy_test_util_common.cc

Issue 2832973003: Split net/spdy into core and chromium subdirectories. (Closed)
Patch Set: Fix some more build rules. Created 3 years, 8 months 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/spdy/spdy_test_util_common.h ('k') | net/spdy/spdy_test_utils.h » ('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) 2013 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/spdy/spdy_test_util_common.h"
6
7 #include <stdint.h>
8
9 #include <cstddef>
10 #include <utility>
11
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_split.h"
17 #include "net/base/host_port_pair.h"
18 #include "net/cert/ct_policy_enforcer.h"
19 #include "net/cert/ct_policy_status.h"
20 #include "net/cert/do_nothing_ct_verifier.h"
21 #include "net/cert/mock_cert_verifier.h"
22 #include "net/cert/signed_certificate_timestamp_and_status.h"
23 #include "net/http/http_cache.h"
24 #include "net/http/http_network_session.h"
25 #include "net/http/http_network_transaction.h"
26 #include "net/http/http_server_properties_impl.h"
27 #include "net/log/net_log_with_source.h"
28 #include "net/socket/client_socket_handle.h"
29 #include "net/socket/next_proto.h"
30 #include "net/socket/socket_test_util.h"
31 #include "net/socket/ssl_client_socket.h"
32 #include "net/socket/transport_client_socket_pool.h"
33 #include "net/spdy/buffered_spdy_framer.h"
34 #include "net/spdy/spdy_alt_svc_wire_format.h"
35 #include "net/spdy/spdy_framer.h"
36 #include "net/spdy/spdy_http_utils.h"
37 #include "net/spdy/spdy_session.h"
38 #include "net/spdy/spdy_session_pool.h"
39 #include "net/spdy/spdy_stream.h"
40 #include "net/test/gtest_util.h"
41 #include "net/url_request/url_request_job_factory_impl.h"
42 #include "testing/gmock/include/gmock/gmock.h"
43
44 using net::test::IsOk;
45
46 namespace net {
47
48 namespace {
49
50 // Parses a URL into the scheme, host, and path components required for a
51 // SPDY request.
52 void ParseUrl(SpdyStringPiece url,
53 SpdyString* scheme,
54 SpdyString* host,
55 SpdyString* path) {
56 GURL gurl(url);
57 path->assign(gurl.PathForRequest());
58 scheme->assign(gurl.scheme());
59 host->assign(gurl.host());
60 if (gurl.has_port()) {
61 host->append(":");
62 host->append(gurl.port());
63 }
64 }
65
66 } // namespace
67
68 // Chop a frame into an array of MockWrites.
69 // |frame| is the frame to chop.
70 // |num_chunks| is the number of chunks to create.
71 MockWrite* ChopWriteFrame(const SpdySerializedFrame& frame, int num_chunks) {
72 MockWrite* chunks = new MockWrite[num_chunks];
73 int chunk_size = frame.size() / num_chunks;
74 for (int index = 0; index < num_chunks; index++) {
75 const char* ptr = frame.data() + (index * chunk_size);
76 if (index == num_chunks - 1)
77 chunk_size +=
78 frame.size() % chunk_size; // The last chunk takes the remainder.
79 chunks[index] = MockWrite(ASYNC, ptr, chunk_size);
80 }
81 return chunks;
82 }
83
84 // Adds headers and values to a map.
85 // |extra_headers| is an array of { name, value } pairs, arranged as strings
86 // where the even entries are the header names, and the odd entries are the
87 // header values.
88 // |headers| gets filled in from |extra_headers|.
89 void AppendToHeaderBlock(const char* const extra_headers[],
90 int extra_header_count,
91 SpdyHeaderBlock* headers) {
92 SpdyString this_header;
93 SpdyString this_value;
94
95 if (!extra_header_count)
96 return;
97
98 // Sanity check: Non-NULL header list.
99 DCHECK(NULL != extra_headers) << "NULL header value pair list";
100 // Sanity check: Non-NULL header map.
101 DCHECK(NULL != headers) << "NULL header map";
102 // Copy in the headers.
103 for (int i = 0; i < extra_header_count; i++) {
104 // Sanity check: Non-empty header.
105 DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
106 this_header = extra_headers[i * 2];
107 SpdyString::size_type header_len = this_header.length();
108 if (!header_len)
109 continue;
110 this_value = extra_headers[1 + (i * 2)];
111 SpdyString new_value;
112 if (headers->find(this_header) != headers->end()) {
113 // More than one entry in the header.
114 // Don't add the header again, just the append to the value,
115 // separated by a NULL character.
116
117 // Adjust the value.
118 new_value = (*headers)[this_header].as_string();
119 // Put in a NULL separator.
120 new_value.append(1, '\0');
121 // Append the new value.
122 new_value += this_value;
123 } else {
124 // Not a duplicate, just write the value.
125 new_value = this_value;
126 }
127 (*headers)[this_header] = new_value;
128 }
129 }
130
131 // Create a MockWrite from the given SpdySerializedFrame.
132 MockWrite CreateMockWrite(const SpdySerializedFrame& req) {
133 return MockWrite(ASYNC, req.data(), req.size());
134 }
135
136 // Create a MockWrite from the given SpdySerializedFrame and sequence number.
137 MockWrite CreateMockWrite(const SpdySerializedFrame& req, int seq) {
138 return CreateMockWrite(req, seq, ASYNC);
139 }
140
141 // Create a MockWrite from the given SpdySerializedFrame and sequence number.
142 MockWrite CreateMockWrite(const SpdySerializedFrame& req,
143 int seq,
144 IoMode mode) {
145 return MockWrite(mode, req.data(), req.size(), seq);
146 }
147
148 // Create a MockRead from the given SpdySerializedFrame.
149 MockRead CreateMockRead(const SpdySerializedFrame& resp) {
150 return MockRead(ASYNC, resp.data(), resp.size());
151 }
152
153 // Create a MockRead from the given SpdySerializedFrame and sequence number.
154 MockRead CreateMockRead(const SpdySerializedFrame& resp, int seq) {
155 return CreateMockRead(resp, seq, ASYNC);
156 }
157
158 // Create a MockRead from the given SpdySerializedFrame and sequence number.
159 MockRead CreateMockRead(const SpdySerializedFrame& resp, int seq, IoMode mode) {
160 return MockRead(mode, resp.data(), resp.size(), seq);
161 }
162
163 // Combines the given SpdyFrames into the given char array and returns
164 // the total length.
165 int CombineFrames(const SpdySerializedFrame** frames,
166 int num_frames,
167 char* buf,
168 int buf_len) {
169 int total_len = 0;
170 for (int i = 0; i < num_frames; ++i) {
171 total_len += frames[i]->size();
172 }
173 DCHECK_LE(total_len, buf_len);
174 char* ptr = buf;
175 for (int i = 0; i < num_frames; ++i) {
176 int len = frames[i]->size();
177 memcpy(ptr, frames[i]->data(), len);
178 ptr += len;
179 }
180 return total_len;
181 }
182
183 namespace {
184
185 class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
186 public:
187 PriorityGetter() : priority_(0) {}
188 ~PriorityGetter() override {}
189
190 SpdyPriority priority() const {
191 return priority_;
192 }
193
194 void OnError(SpdyFramer::SpdyFramerError spdy_framer_error) override {}
195 void OnStreamError(SpdyStreamId stream_id,
196 const SpdyString& description) override {}
197 void OnHeaders(SpdyStreamId stream_id,
198 bool has_priority,
199 int weight,
200 SpdyStreamId parent_stream_id,
201 bool exclusive,
202 bool fin,
203 SpdyHeaderBlock headers) override {
204 if (has_priority) {
205 priority_ = Http2WeightToSpdy3Priority(weight);
206 }
207 }
208 void OnDataFrameHeader(SpdyStreamId stream_id,
209 size_t length,
210 bool fin) override {}
211 void OnStreamFrameData(SpdyStreamId stream_id,
212 const char* data,
213 size_t len) override {}
214 void OnStreamEnd(SpdyStreamId stream_id) override {}
215 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {}
216 void OnSettings() override {}
217 void OnSetting(SpdySettingsIds id, uint32_t value) override {}
218 void OnPing(SpdyPingId unique_id, bool is_ack) override {}
219 void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {}
220 void OnGoAway(SpdyStreamId last_accepted_stream_id,
221 SpdyErrorCode error_code,
222 SpdyStringPiece debug_data) override {}
223 void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {}
224 void OnPushPromise(SpdyStreamId stream_id,
225 SpdyStreamId promised_stream_id,
226 SpdyHeaderBlock headers) override {}
227 void OnAltSvc(SpdyStreamId stream_id,
228 SpdyStringPiece origin,
229 const SpdyAltSvcWireFormat::AlternativeServiceVector&
230 altsvc_vector) override {}
231 bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override {
232 return false;
233 }
234
235 private:
236 SpdyPriority priority_;
237 };
238
239 } // namespace
240
241 bool GetSpdyPriority(const SpdySerializedFrame& frame, SpdyPriority* priority) {
242 BufferedSpdyFramer framer;
243 PriorityGetter priority_getter;
244 framer.set_visitor(&priority_getter);
245 size_t frame_size = frame.size();
246 if (framer.ProcessInput(frame.data(), frame_size) != frame_size) {
247 return false;
248 }
249 *priority = priority_getter.priority();
250 return true;
251 }
252
253 base::WeakPtr<SpdyStream> CreateStreamSynchronously(
254 SpdyStreamType type,
255 const base::WeakPtr<SpdySession>& session,
256 const GURL& url,
257 RequestPriority priority,
258 const NetLogWithSource& net_log) {
259 SpdyStreamRequest stream_request;
260 int rv = stream_request.StartRequest(type, session, url, priority, net_log,
261 CompletionCallback());
262 return
263 (rv == OK) ? stream_request.ReleaseStream() : base::WeakPtr<SpdyStream>();
264 }
265
266 StreamReleaserCallback::StreamReleaserCallback() {}
267
268 StreamReleaserCallback::~StreamReleaserCallback() {}
269
270 CompletionCallback StreamReleaserCallback::MakeCallback(
271 SpdyStreamRequest* request) {
272 return base::Bind(&StreamReleaserCallback::OnComplete,
273 base::Unretained(this),
274 request);
275 }
276
277 void StreamReleaserCallback::OnComplete(
278 SpdyStreamRequest* request, int result) {
279 if (result == OK)
280 request->ReleaseStream()->Cancel();
281 SetResult(result);
282 }
283
284 MockECSignatureCreator::MockECSignatureCreator(crypto::ECPrivateKey* key)
285 : key_(key) {
286 }
287
288 bool MockECSignatureCreator::Sign(const uint8_t* data,
289 int data_len,
290 std::vector<uint8_t>* signature) {
291 std::vector<uint8_t> private_key;
292 if (!key_->ExportPrivateKey(&private_key))
293 return false;
294 SpdyString head = "fakesignature";
295 SpdyString tail = "/fakesignature";
296
297 signature->clear();
298 signature->insert(signature->end(), head.begin(), head.end());
299 signature->insert(signature->end(), private_key.begin(), private_key.end());
300 signature->insert(signature->end(), '-');
301 signature->insert(signature->end(), data, data + data_len);
302 signature->insert(signature->end(), tail.begin(), tail.end());
303 return true;
304 }
305
306 bool MockECSignatureCreator::DecodeSignature(
307 const std::vector<uint8_t>& signature,
308 std::vector<uint8_t>* out_raw_sig) {
309 *out_raw_sig = signature;
310 return true;
311 }
312
313 MockECSignatureCreatorFactory::MockECSignatureCreatorFactory() {
314 crypto::ECSignatureCreator::SetFactoryForTesting(this);
315 }
316
317 MockECSignatureCreatorFactory::~MockECSignatureCreatorFactory() {
318 crypto::ECSignatureCreator::SetFactoryForTesting(nullptr);
319 }
320
321 std::unique_ptr<crypto::ECSignatureCreator>
322 MockECSignatureCreatorFactory::Create(crypto::ECPrivateKey* key) {
323 return base::MakeUnique<MockECSignatureCreator>(key);
324 }
325
326 SpdySessionDependencies::SpdySessionDependencies()
327 : SpdySessionDependencies(ProxyService::CreateDirect()) {}
328
329 SpdySessionDependencies::SpdySessionDependencies(
330 std::unique_ptr<ProxyService> proxy_service)
331 : host_resolver(new MockCachingHostResolver),
332 cert_verifier(new MockCertVerifier),
333 channel_id_service(nullptr),
334 transport_security_state(new TransportSecurityState),
335 cert_transparency_verifier(new DoNothingCTVerifier),
336 ct_policy_enforcer(new CTPolicyEnforcer),
337 proxy_service(std::move(proxy_service)),
338 ssl_config_service(new SSLConfigServiceDefaults),
339 socket_factory(new MockClientSocketFactory),
340 http_auth_handler_factory(
341 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
342 http_server_properties(new HttpServerPropertiesImpl),
343 enable_ip_pooling(true),
344 enable_ping(false),
345 enable_user_alternate_protocol_ports(false),
346 enable_quic(false),
347 enable_server_push_cancellation(false),
348 session_max_recv_window_size(kDefaultInitialWindowSize),
349 time_func(&base::TimeTicks::Now),
350 enable_http2_alternative_service(false),
351 net_log(nullptr),
352 http_09_on_non_default_ports_enabled(false),
353 restrict_to_one_preconnect_for_proxies(false),
354 quic_do_not_mark_as_broken_on_network_change(false) {
355 // Note: The CancelledTransaction test does cleanup by running all
356 // tasks in the message loop (RunAllPending). Unfortunately, that
357 // doesn't clean up tasks on the host resolver thread; and
358 // TCPConnectJob is currently not cancellable. Using synchronous
359 // lookups allows the test to shutdown cleanly. Until we have
360 // cancellable TCPConnectJobs, use synchronous lookups.
361 host_resolver->set_synchronous_mode(true);
362 http2_settings[SETTINGS_INITIAL_WINDOW_SIZE] = kDefaultInitialWindowSize;
363 }
364
365 SpdySessionDependencies::~SpdySessionDependencies() {}
366
367 // static
368 std::unique_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession(
369 SpdySessionDependencies* session_deps) {
370 return SpdyCreateSessionWithSocketFactory(session_deps,
371 session_deps->socket_factory.get());
372 }
373
374 // static
375 std::unique_ptr<HttpNetworkSession>
376 SpdySessionDependencies::SpdyCreateSessionWithSocketFactory(
377 SpdySessionDependencies* session_deps,
378 ClientSocketFactory* factory) {
379 HttpNetworkSession::Params params = CreateSessionParams(session_deps);
380 params.client_socket_factory = factory;
381 std::unique_ptr<HttpNetworkSession> http_session(
382 new HttpNetworkSession(params));
383 SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool());
384 pool_peer.SetEnableSendingInitialData(false);
385 return http_session;
386 }
387
388 // static
389 HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams(
390 SpdySessionDependencies* session_deps) {
391 HttpNetworkSession::Params params;
392 params.host_resolver = session_deps->host_resolver.get();
393 params.cert_verifier = session_deps->cert_verifier.get();
394 params.channel_id_service = session_deps->channel_id_service.get();
395 params.transport_security_state =
396 session_deps->transport_security_state.get();
397 params.cert_transparency_verifier =
398 session_deps->cert_transparency_verifier.get();
399 params.ct_policy_enforcer = session_deps->ct_policy_enforcer.get();
400 params.proxy_service = session_deps->proxy_service.get();
401 params.ssl_config_service = session_deps->ssl_config_service.get();
402 params.http_auth_handler_factory =
403 session_deps->http_auth_handler_factory.get();
404 params.http_server_properties = session_deps->http_server_properties.get();
405 params.enable_spdy_ping_based_connection_checking = session_deps->enable_ping;
406 params.enable_user_alternate_protocol_ports =
407 session_deps->enable_user_alternate_protocol_ports;
408 params.enable_quic = session_deps->enable_quic;
409 params.enable_server_push_cancellation =
410 session_deps->enable_server_push_cancellation;
411 params.spdy_session_max_recv_window_size =
412 session_deps->session_max_recv_window_size;
413 params.http2_settings = session_deps->http2_settings;
414 params.time_func = session_deps->time_func;
415 params.proxy_delegate = session_deps->proxy_delegate.get();
416 params.enable_http2_alternative_service =
417 session_deps->enable_http2_alternative_service;
418 params.net_log = session_deps->net_log;
419 params.http_09_on_non_default_ports_enabled =
420 session_deps->http_09_on_non_default_ports_enabled;
421 params.restrict_to_one_preconnect_for_proxies =
422 session_deps->restrict_to_one_preconnect_for_proxies;
423 params.quic_do_not_mark_as_broken_on_network_change =
424 session_deps->quic_do_not_mark_as_broken_on_network_change;
425 return params;
426 }
427
428 class AllowAnyCertCTPolicyEnforcer : public CTPolicyEnforcer {
429 public:
430 AllowAnyCertCTPolicyEnforcer() {}
431 ~AllowAnyCertCTPolicyEnforcer() override = default;
432
433 ct::CertPolicyCompliance DoesConformToCertPolicy(
434 X509Certificate* cert,
435 const SCTList& verified_scts,
436 const NetLogWithSource& net_log) override {
437 return ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS;
438 }
439
440 ct::EVPolicyCompliance DoesConformToCTEVPolicy(
441 X509Certificate* cert,
442 const ct::EVCertsWhitelist* ev_whitelist,
443 const SCTList& verified_scts,
444 const NetLogWithSource& net_log) override {
445 return ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS;
446 }
447 };
448
449 SpdyURLRequestContext::SpdyURLRequestContext() : storage_(this) {
450 storage_.set_host_resolver(
451 std::unique_ptr<HostResolver>(new MockHostResolver));
452 storage_.set_cert_verifier(base::WrapUnique(new MockCertVerifier));
453 storage_.set_transport_security_state(
454 base::WrapUnique(new TransportSecurityState));
455 storage_.set_proxy_service(ProxyService::CreateDirect());
456 storage_.set_ct_policy_enforcer(
457 base::WrapUnique(new AllowAnyCertCTPolicyEnforcer()));
458 storage_.set_cert_transparency_verifier(
459 base::WrapUnique(new DoNothingCTVerifier()));
460 storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
461 storage_.set_http_auth_handler_factory(
462 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
463 storage_.set_http_server_properties(
464 std::unique_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
465 storage_.set_job_factory(base::MakeUnique<URLRequestJobFactoryImpl>());
466 HttpNetworkSession::Params params;
467 params.client_socket_factory = &socket_factory_;
468 params.host_resolver = host_resolver();
469 params.cert_verifier = cert_verifier();
470 params.transport_security_state = transport_security_state();
471 params.proxy_service = proxy_service();
472 params.ct_policy_enforcer = ct_policy_enforcer();
473 params.cert_transparency_verifier = cert_transparency_verifier();
474 params.ssl_config_service = ssl_config_service();
475 params.http_auth_handler_factory = http_auth_handler_factory();
476 params.enable_spdy_ping_based_connection_checking = false;
477 params.http_server_properties = http_server_properties();
478 storage_.set_http_network_session(
479 base::MakeUnique<HttpNetworkSession>(params));
480 SpdySessionPoolPeer pool_peer(
481 storage_.http_network_session()->spdy_session_pool());
482 pool_peer.SetEnableSendingInitialData(false);
483 storage_.set_http_transaction_factory(base::MakeUnique<HttpCache>(
484 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
485 false));
486 }
487
488 SpdyURLRequestContext::~SpdyURLRequestContext() {
489 AssertNoURLRequests();
490 }
491
492 bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key) {
493 return static_cast<bool>(pool->FindAvailableSession(
494 key, GURL(),
495 /* enable_ip_based_pooling = */ true, NetLogWithSource()));
496 }
497
498 namespace {
499
500 base::WeakPtr<SpdySession> CreateSpdySessionHelper(
501 HttpNetworkSession* http_session,
502 const SpdySessionKey& key,
503 const NetLogWithSource& net_log,
504 Error expected_status,
505 bool is_secure,
506 bool enable_ip_based_pooling) {
507 EXPECT_FALSE(http_session->spdy_session_pool()->FindAvailableSession(
508 key, GURL(), enable_ip_based_pooling, NetLogWithSource()));
509
510 scoped_refptr<TransportSocketParams> transport_params(
511 new TransportSocketParams(
512 key.host_port_pair(), false, OnHostResolutionCallback(),
513 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
514
515 std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
516 TestCompletionCallback callback;
517
518 int rv = ERR_UNEXPECTED;
519 if (is_secure) {
520 SSLConfig ssl_config;
521 scoped_refptr<SSLSocketParams> ssl_params(
522 new SSLSocketParams(transport_params,
523 NULL,
524 NULL,
525 key.host_port_pair(),
526 ssl_config,
527 key.privacy_mode(),
528 0,
529 false));
530 rv = connection->Init(
531 key.host_port_pair().ToString(), ssl_params, MEDIUM,
532 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
533 http_session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL),
534 net_log);
535 } else {
536 rv = connection->Init(key.host_port_pair().ToString(), transport_params,
537 MEDIUM, ClientSocketPool::RespectLimits::ENABLED,
538 callback.callback(),
539 http_session->GetTransportSocketPool(
540 HttpNetworkSession::NORMAL_SOCKET_POOL),
541 net_log);
542 }
543
544 if (rv == ERR_IO_PENDING)
545 rv = callback.WaitForResult();
546
547 EXPECT_THAT(rv, IsOk());
548
549 base::WeakPtr<SpdySession> spdy_session =
550 http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
551 key, std::move(connection), net_log, is_secure);
552 // Failure is reported asynchronously.
553 EXPECT_TRUE(spdy_session);
554 EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
555 return spdy_session;
556 }
557
558 } // namespace
559
560 base::WeakPtr<SpdySession> CreateInsecureSpdySession(
561 HttpNetworkSession* http_session,
562 const SpdySessionKey& key,
563 const NetLogWithSource& net_log) {
564 return CreateSpdySessionHelper(http_session, key, net_log, OK,
565 /* is_secure = */ false,
566 /* enable_ip_based_pooling = */ true);
567 }
568
569 base::WeakPtr<SpdySession> TryCreateSpdySessionExpectingFailure(
570 HttpNetworkSession* http_session,
571 const SpdySessionKey& key,
572 Error expected_error,
573 const NetLogWithSource& net_log) {
574 DCHECK_LT(expected_error, ERR_IO_PENDING);
575 return CreateSpdySessionHelper(http_session, key, net_log, expected_error,
576 /* is_secure = */ true,
577 /* enable_ip_based_pooling = */ true);
578 }
579
580 base::WeakPtr<SpdySession> CreateSecureSpdySession(
581 HttpNetworkSession* http_session,
582 const SpdySessionKey& key,
583 const NetLogWithSource& net_log) {
584 return CreateSpdySessionHelper(http_session, key, net_log, OK,
585 /* is_secure = */ true,
586 /* enable_ip_based_pooling = */ true);
587 }
588
589 base::WeakPtr<SpdySession> CreateSecureSpdySessionWithIpBasedPoolingDisabled(
590 HttpNetworkSession* http_session,
591 const SpdySessionKey& key,
592 const NetLogWithSource& net_log) {
593 return CreateSpdySessionHelper(http_session, key, net_log, OK,
594 /* is_secure = */ true,
595 /* enable_ip_based_pooling = */ false);
596 }
597
598 namespace {
599
600 // A ClientSocket used for CreateFakeSpdySession() below.
601 class FakeSpdySessionClientSocket : public MockClientSocket {
602 public:
603 explicit FakeSpdySessionClientSocket(int read_result)
604 : MockClientSocket(NetLogWithSource()), read_result_(read_result) {}
605
606 ~FakeSpdySessionClientSocket() override {}
607
608 int Read(IOBuffer* buf,
609 int buf_len,
610 const CompletionCallback& callback) override {
611 return read_result_;
612 }
613
614 int Write(IOBuffer* buf,
615 int buf_len,
616 const CompletionCallback& callback) override {
617 return ERR_IO_PENDING;
618 }
619
620 // Return kProtoUnknown to use the pool's default protocol.
621 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
622
623 // The functions below are not expected to be called.
624
625 int Connect(const CompletionCallback& callback) override {
626 ADD_FAILURE();
627 return ERR_UNEXPECTED;
628 }
629
630 bool WasEverUsed() const override {
631 ADD_FAILURE();
632 return false;
633 }
634
635 bool WasAlpnNegotiated() const override {
636 ADD_FAILURE();
637 return false;
638 }
639
640 bool GetSSLInfo(SSLInfo* ssl_info) override {
641 ADD_FAILURE();
642 return false;
643 }
644
645 int64_t GetTotalReceivedBytes() const override {
646 NOTIMPLEMENTED();
647 return 0;
648 }
649
650 private:
651 int read_result_;
652 };
653
654 base::WeakPtr<SpdySession> CreateFakeSpdySessionHelper(
655 SpdySessionPool* pool,
656 const SpdySessionKey& key,
657 Error expected_status) {
658 EXPECT_NE(expected_status, ERR_IO_PENDING);
659 EXPECT_FALSE(HasSpdySession(pool, key));
660 std::unique_ptr<ClientSocketHandle> handle(new ClientSocketHandle());
661 handle->SetSocket(
662 std::unique_ptr<StreamSocket>(new FakeSpdySessionClientSocket(
663 expected_status == OK ? ERR_IO_PENDING : expected_status)));
664 base::WeakPtr<SpdySession> spdy_session =
665 pool->CreateAvailableSessionFromSocket(
666 key, std::move(handle), NetLogWithSource(), true /* is_secure */);
667 // Failure is reported asynchronously.
668 EXPECT_TRUE(spdy_session);
669 EXPECT_TRUE(HasSpdySession(pool, key));
670 return spdy_session;
671 }
672
673 } // namespace
674
675 base::WeakPtr<SpdySession> CreateFakeSpdySession(SpdySessionPool* pool,
676 const SpdySessionKey& key) {
677 return CreateFakeSpdySessionHelper(pool, key, OK);
678 }
679
680 base::WeakPtr<SpdySession> TryCreateFakeSpdySessionExpectingFailure(
681 SpdySessionPool* pool,
682 const SpdySessionKey& key,
683 Error expected_error) {
684 DCHECK_LT(expected_error, ERR_IO_PENDING);
685 return CreateFakeSpdySessionHelper(pool, key, expected_error);
686 }
687
688 SpdySessionPoolPeer::SpdySessionPoolPeer(SpdySessionPool* pool) : pool_(pool) {
689 }
690
691 void SpdySessionPoolPeer::RemoveAliases(const SpdySessionKey& key) {
692 pool_->RemoveAliases(key);
693 }
694
695 void SpdySessionPoolPeer::SetEnableSendingInitialData(bool enabled) {
696 pool_->enable_sending_initial_data_ = enabled;
697 }
698
699 SpdyTestUtil::SpdyTestUtil()
700 : headerless_spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
701 request_spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
702 response_spdy_framer_(SpdyFramer::ENABLE_COMPRESSION),
703 default_url_(GURL(kDefaultUrl)) {}
704
705 SpdyTestUtil::~SpdyTestUtil() {}
706
707 void SpdyTestUtil::AddUrlToHeaderBlock(SpdyStringPiece url,
708 SpdyHeaderBlock* headers) const {
709 SpdyString scheme, host, path;
710 ParseUrl(url, &scheme, &host, &path);
711 (*headers)[GetHostKey()] = host;
712 (*headers)[GetSchemeKey()] = scheme;
713 (*headers)[GetPathKey()] = path;
714 }
715
716 // static
717 SpdyHeaderBlock SpdyTestUtil::ConstructGetHeaderBlock(SpdyStringPiece url) {
718 return ConstructHeaderBlock("GET", url, NULL);
719 }
720
721 // static
722 SpdyHeaderBlock SpdyTestUtil::ConstructGetHeaderBlockForProxy(
723 SpdyStringPiece url) {
724 return ConstructGetHeaderBlock(url);
725 }
726
727 // static
728 SpdyHeaderBlock SpdyTestUtil::ConstructHeadHeaderBlock(SpdyStringPiece url,
729 int64_t content_length) {
730 return ConstructHeaderBlock("HEAD", url, nullptr);
731 }
732
733 // static
734 SpdyHeaderBlock SpdyTestUtil::ConstructPostHeaderBlock(SpdyStringPiece url,
735 int64_t content_length) {
736 return ConstructHeaderBlock("POST", url, &content_length);
737 }
738
739 // static
740 SpdyHeaderBlock SpdyTestUtil::ConstructPutHeaderBlock(SpdyStringPiece url,
741 int64_t content_length) {
742 return ConstructHeaderBlock("PUT", url, &content_length);
743 }
744
745 SpdyString SpdyTestUtil::ConstructSpdyReplyString(
746 const SpdyHeaderBlock& headers) const {
747 SpdyString reply_string;
748 for (SpdyHeaderBlock::const_iterator it = headers.begin();
749 it != headers.end(); ++it) {
750 SpdyString key = it->first.as_string();
751 // Remove leading colon from pseudo headers.
752 if (key[0] == ':')
753 key = key.substr(1);
754 for (const SpdyString& value :
755 base::SplitString(it->second, SpdyStringPiece("\0", 1),
756 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
757 reply_string += key + ": " + value + "\n";
758 }
759 }
760 return reply_string;
761 }
762
763 // TODO(jgraettinger): Eliminate uses of this method in tests (prefer
764 // SpdySettingsIR).
765 SpdySerializedFrame SpdyTestUtil::ConstructSpdySettings(
766 const SettingsMap& settings) {
767 SpdySettingsIR settings_ir;
768 for (SettingsMap::const_iterator it = settings.begin(); it != settings.end();
769 ++it) {
770 settings_ir.AddSetting(it->first, it->second);
771 }
772 return SpdySerializedFrame(
773 headerless_spdy_framer_.SerializeFrame(settings_ir));
774 }
775
776 SpdySerializedFrame SpdyTestUtil::ConstructSpdySettingsAck() {
777 SpdySettingsIR settings_ir;
778 settings_ir.set_is_ack(true);
779 return SpdySerializedFrame(
780 headerless_spdy_framer_.SerializeFrame(settings_ir));
781 }
782
783 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPing(uint32_t ping_id,
784 bool is_ack) {
785 SpdyPingIR ping_ir(ping_id);
786 ping_ir.set_is_ack(is_ack);
787 return SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(ping_ir));
788 }
789
790 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGoAway() {
791 return ConstructSpdyGoAway(0);
792 }
793
794 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGoAway(
795 SpdyStreamId last_good_stream_id) {
796 SpdyGoAwayIR go_ir(last_good_stream_id, ERROR_CODE_NO_ERROR, "go away");
797 return SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(go_ir));
798 }
799
800 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGoAway(
801 SpdyStreamId last_good_stream_id,
802 SpdyErrorCode error_code,
803 const SpdyString& desc) {
804 SpdyGoAwayIR go_ir(last_good_stream_id, error_code, desc);
805 return SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(go_ir));
806 }
807
808 SpdySerializedFrame SpdyTestUtil::ConstructSpdyWindowUpdate(
809 const SpdyStreamId stream_id,
810 uint32_t delta_window_size) {
811 SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
812 return SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(update_ir));
813 }
814
815 // TODO(jgraettinger): Eliminate uses of this method in tests (prefer
816 // SpdyRstStreamIR).
817 SpdySerializedFrame SpdyTestUtil::ConstructSpdyRstStream(
818 SpdyStreamId stream_id,
819 SpdyErrorCode error_code) {
820 SpdyRstStreamIR rst_ir(stream_id, error_code);
821 return SpdySerializedFrame(
822 headerless_spdy_framer_.SerializeRstStream(rst_ir));
823 }
824
825 // TODO(jgraettinger): Eliminate uses of this method in tests (prefer
826 // SpdyPriorityIR).
827 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPriority(
828 SpdyStreamId stream_id,
829 SpdyStreamId parent_stream_id,
830 RequestPriority request_priority,
831 bool exclusive) {
832 int weight = Spdy3PriorityToHttp2Weight(
833 ConvertRequestPriorityToSpdyPriority(request_priority));
834 SpdyPriorityIR ir(stream_id, parent_stream_id, weight, exclusive);
835 return SpdySerializedFrame(headerless_spdy_framer_.SerializePriority(ir));
836 }
837
838 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGet(
839 const char* const url,
840 SpdyStreamId stream_id,
841 RequestPriority request_priority) {
842 SpdyHeaderBlock block(ConstructGetHeaderBlock(url));
843 return ConstructSpdyHeaders(stream_id, std::move(block), request_priority,
844 true);
845 }
846
847 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGet(
848 const char* const extra_headers[],
849 int extra_header_count,
850 int stream_id,
851 RequestPriority request_priority,
852 bool direct) {
853 SpdyHeaderBlock block;
854 block[GetMethodKey()] = "GET";
855 AddUrlToHeaderBlock(default_url_.spec(), &block);
856 AppendToHeaderBlock(extra_headers, extra_header_count, &block);
857 return ConstructSpdyHeaders(stream_id, std::move(block), request_priority,
858 true);
859 }
860
861 SpdySerializedFrame SpdyTestUtil::ConstructSpdyConnect(
862 const char* const extra_headers[],
863 int extra_header_count,
864 int stream_id,
865 RequestPriority priority,
866 const HostPortPair& host_port_pair) {
867 SpdyHeaderBlock block;
868 block[GetMethodKey()] = "CONNECT";
869 block[GetHostKey()] = host_port_pair.ToString();
870 AppendToHeaderBlock(extra_headers, extra_header_count, &block);
871 return ConstructSpdyHeaders(stream_id, std::move(block), priority, false);
872 }
873
874 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPush(
875 const char* const extra_headers[],
876 int extra_header_count,
877 int stream_id,
878 int associated_stream_id,
879 const char* url) {
880 SpdyHeaderBlock push_promise_header_block;
881 AddUrlToHeaderBlock(url, &push_promise_header_block);
882 SpdyPushPromiseIR push_promise(associated_stream_id, stream_id,
883 std::move(push_promise_header_block));
884 SpdySerializedFrame push_promise_frame(
885 response_spdy_framer_.SerializeFrame(push_promise));
886
887 SpdyHeaderBlock headers_header_block;
888 headers_header_block[GetStatusKey()] = "200";
889 headers_header_block["hello"] = "bye";
890 AppendToHeaderBlock(extra_headers, extra_header_count, &headers_header_block);
891 SpdyHeadersIR headers(stream_id, std::move(headers_header_block));
892 SpdySerializedFrame headers_frame(
893 response_spdy_framer_.SerializeFrame(headers));
894
895 int joint_data_size = push_promise_frame.size() + headers_frame.size();
896 std::unique_ptr<char[]> data(new char[joint_data_size]);
897 const SpdySerializedFrame* frames[2] = {
898 &push_promise_frame, &headers_frame,
899 };
900 int combined_size =
901 CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
902 DCHECK_EQ(combined_size, joint_data_size);
903 return SpdySerializedFrame(data.release(), joint_data_size, true);
904 }
905
906 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPush(
907 const char* const extra_headers[],
908 int extra_header_count,
909 int stream_id,
910 int associated_stream_id,
911 const char* url,
912 const char* status,
913 const char* location) {
914 SpdyHeaderBlock push_promise_header_block;
915 AddUrlToHeaderBlock(url, &push_promise_header_block);
916 SpdyPushPromiseIR push_promise(associated_stream_id, stream_id,
917 std::move(push_promise_header_block));
918 SpdySerializedFrame push_promise_frame(
919 response_spdy_framer_.SerializeFrame(push_promise));
920
921 SpdyHeaderBlock headers_header_block;
922 headers_header_block["hello"] = "bye";
923 headers_header_block[GetStatusKey()] = status;
924 headers_header_block["location"] = location;
925 AppendToHeaderBlock(extra_headers, extra_header_count, &headers_header_block);
926 SpdyHeadersIR headers(stream_id, std::move(headers_header_block));
927 SpdySerializedFrame headers_frame(
928 response_spdy_framer_.SerializeFrame(headers));
929
930 int joint_data_size = push_promise_frame.size() + headers_frame.size();
931 std::unique_ptr<char[]> data(new char[joint_data_size]);
932 const SpdySerializedFrame* frames[2] = {
933 &push_promise_frame, &headers_frame,
934 };
935 int combined_size =
936 CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
937 DCHECK_EQ(combined_size, joint_data_size);
938 return SpdySerializedFrame(data.release(), joint_data_size, true);
939 }
940
941 SpdySerializedFrame SpdyTestUtil::ConstructInitialSpdyPushFrame(
942 SpdyHeaderBlock headers,
943 int stream_id,
944 int associated_stream_id) {
945 SpdyPushPromiseIR push_promise(associated_stream_id, stream_id,
946 std::move(headers));
947 return SpdySerializedFrame(
948 response_spdy_framer_.SerializeFrame(push_promise));
949 }
950
951 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPushHeaders(
952 int stream_id,
953 const char* const extra_headers[],
954 int extra_header_count) {
955 SpdyHeaderBlock header_block;
956 header_block[GetStatusKey()] = "200";
957 AppendToHeaderBlock(extra_headers, extra_header_count, &header_block);
958 SpdyHeadersIR headers(stream_id, std::move(header_block));
959 return SpdySerializedFrame(response_spdy_framer_.SerializeFrame(headers));
960 }
961
962 SpdySerializedFrame SpdyTestUtil::ConstructSpdyResponseHeaders(
963 int stream_id,
964 SpdyHeaderBlock headers,
965 bool fin) {
966 SpdyHeadersIR spdy_headers(stream_id, std::move(headers));
967 spdy_headers.set_fin(fin);
968 return SpdySerializedFrame(
969 response_spdy_framer_.SerializeFrame(spdy_headers));
970 }
971
972 SpdySerializedFrame SpdyTestUtil::ConstructSpdyHeaders(int stream_id,
973 SpdyHeaderBlock block,
974 RequestPriority priority,
975 bool fin) {
976 // Get the stream id of the next highest priority request
977 // (most recent request of the same priority, or last request of
978 // an earlier priority).
979 // Note that this is a duplicate of the logic in Http2PriorityDependencies
980 // (slightly transformed as this is based on RequestPriority and that logic
981 // on SpdyPriority, but only slightly transformed) and hence tests using
982 // this function do not effectively test that logic.
983 // That logic is tested by the Http2PriorityDependencies unit tests.
984 int parent_stream_id = 0;
985 for (int q = priority; q <= HIGHEST; ++q) {
986 if (!priority_to_stream_id_list_[q].empty()) {
987 parent_stream_id = priority_to_stream_id_list_[q].back();
988 break;
989 }
990 }
991
992 priority_to_stream_id_list_[priority].push_back(stream_id);
993
994 SpdyHeadersIR headers(stream_id, std::move(block));
995 headers.set_has_priority(true);
996 headers.set_weight(Spdy3PriorityToHttp2Weight(
997 ConvertRequestPriorityToSpdyPriority(priority)));
998 headers.set_parent_stream_id(parent_stream_id);
999 headers.set_exclusive(true);
1000 headers.set_fin(fin);
1001 return SpdySerializedFrame(request_spdy_framer_.SerializeFrame(headers));
1002 }
1003
1004 SpdySerializedFrame SpdyTestUtil::ConstructSpdyReply(int stream_id,
1005 SpdyHeaderBlock headers) {
1006 SpdyHeadersIR reply(stream_id, std::move(headers));
1007 return SpdySerializedFrame(response_spdy_framer_.SerializeFrame(reply));
1008 }
1009
1010 SpdySerializedFrame SpdyTestUtil::ConstructSpdyReplyError(
1011 const char* const status,
1012 const char* const* const extra_headers,
1013 int extra_header_count,
1014 int stream_id) {
1015 SpdyHeaderBlock block;
1016 block[GetStatusKey()] = status;
1017 block["hello"] = "bye";
1018 AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1019
1020 return ConstructSpdyReply(stream_id, std::move(block));
1021 }
1022
1023 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGetReplyRedirect(int stream_id) {
1024 static const char* const kExtraHeaders[] = {
1025 "location", "http://www.foo.com/index.php",
1026 };
1027 return ConstructSpdyReplyError("301", kExtraHeaders,
1028 arraysize(kExtraHeaders) / 2, stream_id);
1029 }
1030
1031 SpdySerializedFrame SpdyTestUtil::ConstructSpdyReplyError(int stream_id) {
1032 return ConstructSpdyReplyError("500", NULL, 0, 1);
1033 }
1034
1035 SpdySerializedFrame SpdyTestUtil::ConstructSpdyGetReply(
1036 const char* const extra_headers[],
1037 int extra_header_count,
1038 int stream_id) {
1039 SpdyHeaderBlock block;
1040 block[GetStatusKey()] = "200";
1041 block["hello"] = "bye";
1042 AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1043
1044 return ConstructSpdyReply(stream_id, std::move(block));
1045 }
1046
1047 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPost(
1048 const char* url,
1049 SpdyStreamId stream_id,
1050 int64_t content_length,
1051 RequestPriority priority,
1052 const char* const extra_headers[],
1053 int extra_header_count) {
1054 SpdyHeaderBlock block(ConstructPostHeaderBlock(url, content_length));
1055 AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1056 return ConstructSpdyHeaders(stream_id, std::move(block), priority, false);
1057 }
1058
1059 SpdySerializedFrame SpdyTestUtil::ConstructChunkedSpdyPost(
1060 const char* const extra_headers[],
1061 int extra_header_count) {
1062 SpdyHeaderBlock block;
1063 block[GetMethodKey()] = "POST";
1064 AddUrlToHeaderBlock(default_url_.spec(), &block);
1065 AppendToHeaderBlock(extra_headers, extra_header_count, &block);
1066 return ConstructSpdyHeaders(1, std::move(block), LOWEST, false);
1067 }
1068
1069 SpdySerializedFrame SpdyTestUtil::ConstructSpdyPostReply(
1070 const char* const extra_headers[],
1071 int extra_header_count) {
1072 // TODO(jgraettinger): Remove this method.
1073 return ConstructSpdyGetReply(extra_headers, extra_header_count, 1);
1074 }
1075
1076 SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id,
1077 bool fin) {
1078 SpdyDataIR data_ir(stream_id, SpdyStringPiece(kUploadData, kUploadDataSize));
1079 data_ir.set_fin(fin);
1080 return SpdySerializedFrame(headerless_spdy_framer_.SerializeData(data_ir));
1081 }
1082
1083 SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id,
1084 const char* data,
1085 uint32_t len,
1086 bool fin) {
1087 SpdyDataIR data_ir(stream_id, SpdyStringPiece(data, len));
1088 data_ir.set_fin(fin);
1089 return SpdySerializedFrame(headerless_spdy_framer_.SerializeData(data_ir));
1090 }
1091
1092 SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id,
1093 const char* data,
1094 uint32_t len,
1095 bool fin,
1096 int padding_length) {
1097 SpdyDataIR data_ir(stream_id, SpdyStringPiece(data, len));
1098 data_ir.set_fin(fin);
1099 data_ir.set_padding_len(padding_length);
1100 return SpdySerializedFrame(headerless_spdy_framer_.SerializeData(data_ir));
1101 }
1102
1103 SpdySerializedFrame SpdyTestUtil::ConstructWrappedSpdyFrame(
1104 const SpdySerializedFrame& frame,
1105 int stream_id) {
1106 return ConstructSpdyDataFrame(stream_id, frame.data(), frame.size(), false);
1107 }
1108
1109 SpdySerializedFrame SpdyTestUtil::SerializeFrame(const SpdyFrameIR& frame_ir) {
1110 return headerless_spdy_framer_.SerializeFrame(frame_ir);
1111 }
1112
1113 void SpdyTestUtil::UpdateWithStreamDestruction(int stream_id) {
1114 for (auto priority_it = priority_to_stream_id_list_.begin();
1115 priority_it != priority_to_stream_id_list_.end(); ++priority_it) {
1116 for (auto stream_it = priority_it->second.begin();
1117 stream_it != priority_it->second.end(); ++stream_it) {
1118 if (*stream_it == stream_id) {
1119 priority_it->second.erase(stream_it);
1120 return;
1121 }
1122 }
1123 }
1124 NOTREACHED();
1125 }
1126
1127 // static
1128 const char* SpdyTestUtil::GetMethodKey() {
1129 return ":method";
1130 }
1131
1132 // static
1133 const char* SpdyTestUtil::GetStatusKey() {
1134 return ":status";
1135 }
1136
1137 // static
1138 const char* SpdyTestUtil::GetHostKey() {
1139 return ":authority";
1140 }
1141
1142 // static
1143 const char* SpdyTestUtil::GetSchemeKey() {
1144 return ":scheme";
1145 }
1146
1147 // static
1148 const char* SpdyTestUtil::GetPathKey() {
1149 return ":path";
1150 }
1151
1152 // static
1153 SpdyHeaderBlock SpdyTestUtil::ConstructHeaderBlock(SpdyStringPiece method,
1154 SpdyStringPiece url,
1155 int64_t* content_length) {
1156 SpdyString scheme, host, path;
1157 ParseUrl(url, &scheme, &host, &path);
1158 SpdyHeaderBlock headers;
1159 headers[GetMethodKey()] = method.as_string();
1160 headers[GetHostKey()] = host.c_str();
1161 headers[GetSchemeKey()] = scheme.c_str();
1162 headers[GetPathKey()] = path.c_str();
1163 if (content_length) {
1164 SpdyString length_str = base::Int64ToString(*content_length);
1165 headers["content-length"] = length_str;
1166 }
1167 return headers;
1168 }
1169
1170 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_test_util_common.h ('k') | net/spdy/spdy_test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698