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

Side by Side Diff: net/http/http_stream_factory_impl.cc

Issue 6684019: Reland rest of r77399. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_stream_factory_impl.h ('k') | net/http/http_stream_factory_impl_job.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_stream_factory_impl.h" 5 #include "net/http/http_stream_factory_impl.h"
6 6
7 #include "base/string_number_conversions.h"
7 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
8 #include "googleurl/src/gurl.h" 9 #include "googleurl/src/gurl.h"
9 #include "net/base/net_log.h" 10 #include "net/base/net_log.h"
10 #include "net/base/net_util.h" 11 #include "net/base/net_util.h"
11 #include "net/http/http_network_session.h" 12 #include "net/http/http_network_session.h"
12 #include "net/http/http_stream_factory_impl_job.h" 13 #include "net/http/http_stream_factory_impl_job.h"
13 #include "net/http/http_stream_factory_impl_request.h" 14 #include "net/http/http_stream_factory_impl_request.h"
14 #include "net/spdy/spdy_http_stream.h" 15 #include "net/spdy/spdy_http_stream.h"
15 16
16 namespace net { 17 namespace net {
17 18
19 namespace {
20
21 bool HasSpdyExclusion(const HostPortPair& endpoint) {
22 std::list<HostPortPair>* exclusions =
23 HttpStreamFactory::forced_spdy_exclusions();
24 if (!exclusions)
25 return false;
26
27 std::list<HostPortPair>::const_iterator it;
28 for (it = exclusions->begin(); it != exclusions->end(); it++)
29 if (it->Equals(endpoint))
30 return true;
31 return false;
32 }
33
34 GURL UpgradeUrlToHttps(const GURL& original_url) {
35 GURL::Replacements replacements;
36 // new_sheme and new_port need to be in scope here because GURL::Replacements
37 // references the memory contained by them directly.
38 const std::string new_scheme = "https";
39 const std::string new_port = base::IntToString(443);
40 replacements.SetSchemeStr(new_scheme);
41 replacements.SetPortStr(new_port);
42 return original_url.ReplaceComponents(replacements);
43 }
44
45 } // namespace
46
18 HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session) 47 HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session)
19 : session_(session) {} 48 : session_(session) {}
20 49
21 HttpStreamFactoryImpl::~HttpStreamFactoryImpl() { 50 HttpStreamFactoryImpl::~HttpStreamFactoryImpl() {
22 DCHECK(request_map_.empty()); 51 DCHECK(request_map_.empty());
23 DCHECK(spdy_session_request_map_.empty()); 52 DCHECK(spdy_session_request_map_.empty());
24 53
25 std::set<const Job*> tmp_job_set; 54 std::set<const Job*> tmp_job_set;
55 tmp_job_set.swap(orphaned_job_set_);
56 STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end());
57 DCHECK(orphaned_job_set_.empty());
58
59 tmp_job_set.clear();
26 tmp_job_set.swap(preconnect_job_set_); 60 tmp_job_set.swap(preconnect_job_set_);
27 STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end()); 61 STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end());
28 DCHECK(preconnect_job_set_.empty()); 62 DCHECK(preconnect_job_set_.empty());
29 } 63 }
30 64
31 HttpStreamRequest* HttpStreamFactoryImpl::RequestStream( 65 HttpStreamRequest* HttpStreamFactoryImpl::RequestStream(
32 const HttpRequestInfo& request_info, 66 const HttpRequestInfo& request_info,
33 const SSLConfig& ssl_config, 67 const SSLConfig& ssl_config,
34 HttpStreamRequest::Delegate* delegate, 68 HttpStreamRequest::Delegate* delegate,
35 const BoundNetLog& net_log) { 69 const BoundNetLog& net_log) {
36 Job* job = new Job(this, session_);
37 Request* request = new Request(request_info.url, this, delegate, net_log); 70 Request* request = new Request(request_info.url, this, delegate, net_log);
71
72 GURL alternate_url;
73 bool has_alternate_protocol =
74 GetAlternateProtocolRequestFor(request_info.url, &alternate_url);
75 Job* alternate_job = NULL;
76 if (has_alternate_protocol) {
77 HttpRequestInfo alternate_request_info = request_info;
78 alternate_request_info.url = alternate_url;
79 alternate_job =
80 new Job(this, session_, alternate_request_info, ssl_config, net_log);
81 request->AttachJob(alternate_job);
82 alternate_job->MarkAsAlternate(request_info.url);
83 }
84
85 Job* job = new Job(this, session_, request_info, ssl_config, net_log);
38 request->AttachJob(job); 86 request->AttachJob(job);
39 job->Start(request, request_info, ssl_config, net_log); 87 if (alternate_job) {
88 job->WaitFor(alternate_job);
89 // Make sure to wait until we call WaitFor(), before starting
90 // |alternate_job|, otherwise |alternate_job| will not notify |job|
91 // appropriately.
92 alternate_job->Start(request);
93 }
94 // Even if |alternate_job| has already finished, it won't have notified the
95 // request yet, since we defer that to the next iteration of the MessageLoop,
96 // so starting |job| is always safe.
97 job->Start(request);
40 return request; 98 return request;
41 } 99 }
42 100
43 void HttpStreamFactoryImpl::PreconnectStreams( 101 void HttpStreamFactoryImpl::PreconnectStreams(
44 int num_streams, 102 int num_streams,
45 const HttpRequestInfo& request_info, 103 const HttpRequestInfo& request_info,
46 const SSLConfig& ssl_config, 104 const SSLConfig& ssl_config,
47 const BoundNetLog& net_log) { 105 const BoundNetLog& net_log) {
48 Job* job = new Job(this, session_); 106 GURL alternate_url;
107 bool has_alternate_protocol =
108 GetAlternateProtocolRequestFor(request_info.url, &alternate_url);
109 Job* job = NULL;
110 if (has_alternate_protocol) {
111 HttpRequestInfo alternate_request_info = request_info;
112 alternate_request_info.url = alternate_url;
113 job = new Job(this, session_, alternate_request_info, ssl_config, net_log);
114 job->MarkAsAlternate(request_info.url);
115 } else {
116 job = new Job(this, session_, request_info, ssl_config, net_log);
117 }
49 preconnect_job_set_.insert(job); 118 preconnect_job_set_.insert(job);
50 job->Preconnect(num_streams, request_info, ssl_config, net_log); 119 job->Preconnect(num_streams);
51 } 120 }
52 121
53 void HttpStreamFactoryImpl::AddTLSIntolerantServer(const GURL& url) { 122 void HttpStreamFactoryImpl::AddTLSIntolerantServer(const HostPortPair& server) {
54 tls_intolerant_servers_.insert(GetHostAndPort(url)); 123 tls_intolerant_servers_.insert(server);
55 } 124 }
56 125
57 bool HttpStreamFactoryImpl::IsTLSIntolerantServer(const GURL& url) const { 126 bool HttpStreamFactoryImpl::IsTLSIntolerantServer(
58 return ContainsKey(tls_intolerant_servers_, GetHostAndPort(url)); 127 const HostPortPair& server) const {
128 return ContainsKey(tls_intolerant_servers_, server);
129 }
130
131 bool HttpStreamFactoryImpl::GetAlternateProtocolRequestFor(
132 const GURL& original_url,
133 GURL* alternate_url) const {
134 if (!spdy_enabled())
135 return false;
136
137 if (!use_alternate_protocols())
138 return false;
139
140 HostPortPair origin = HostPortPair(original_url.HostNoBrackets(),
141 original_url.EffectiveIntPort());
142
143 const HttpAlternateProtocols& alternate_protocols =
144 session_->alternate_protocols();
145 if (!alternate_protocols.HasAlternateProtocolFor(origin))
146 return false;
147
148 HttpAlternateProtocols::PortProtocolPair alternate =
149 alternate_protocols.GetAlternateProtocolFor(origin);
150 if (alternate.protocol == HttpAlternateProtocols::BROKEN)
151 return false;
152
153 DCHECK_LE(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol);
154 DCHECK_GT(HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS,
155 alternate.protocol);
156
157 if (alternate.protocol != HttpAlternateProtocols::NPN_SPDY_2)
158 return false;
159
160 origin.set_port(alternate.port);
161 if (HasSpdyExclusion(origin))
162 return false;
163
164 *alternate_url = UpgradeUrlToHttps(original_url);
165 return true;
59 } 166 }
60 167
61 void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { 168 void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) {
62 DCHECK(ContainsKey(request_map_, job)); 169 DCHECK(ContainsKey(request_map_, job));
63 DCHECK_EQ(request_map_[job], request); 170 DCHECK_EQ(request_map_[job], request);
64 DCHECK(!ContainsKey(orphaned_job_set_, job)); 171 DCHECK(!ContainsKey(orphaned_job_set_, job));
65 172
66 request_map_.erase(job); 173 request_map_.erase(job);
67 174
68 orphaned_job_set_.insert(job); 175 orphaned_job_set_.insert(job);
69 job->Orphan(request); 176 job->Orphan(request);
70 } 177 }
71 178
72 void HttpStreamFactoryImpl::OnSpdySessionReady( 179 void HttpStreamFactoryImpl::OnSpdySessionReady(
73 scoped_refptr<SpdySession> spdy_session, 180 scoped_refptr<SpdySession> spdy_session,
74 bool direct, 181 bool direct,
75 const SSLConfig& used_ssl_config, 182 const SSLConfig& used_ssl_config,
76 const ProxyInfo& used_proxy_info, 183 const ProxyInfo& used_proxy_info,
77 bool was_alternate_protocol_available,
78 bool was_npn_negotiated, 184 bool was_npn_negotiated,
79 bool using_spdy, 185 bool using_spdy,
80 const NetLog::Source& source) { 186 const NetLog::Source& source) {
81 const HostPortProxyPair& spdy_session_key = 187 const HostPortProxyPair& spdy_session_key =
82 spdy_session->host_port_proxy_pair(); 188 spdy_session->host_port_proxy_pair();
83 while (!spdy_session->IsClosed()) { 189 while (!spdy_session->IsClosed()) {
84 // Each iteration may empty out the RequestSet for |spdy_session_key_ in 190 // Each iteration may empty out the RequestSet for |spdy_session_key_ in
85 // |spdy_session_request_map_|. So each time, check for RequestSet and use 191 // |spdy_session_request_map_|. So each time, check for RequestSet and use
86 // the first one. 192 // the first one.
87 // 193 //
88 // TODO(willchan): If it's important, switch RequestSet out for a FIFO 194 // TODO(willchan): If it's important, switch RequestSet out for a FIFO
89 // pqueue (Order by priority first, then FIFO within same priority). Unclear 195 // pqueue (Order by priority first, then FIFO within same priority). Unclear
90 // that it matters here. 196 // that it matters here.
91 if (!ContainsKey(spdy_session_request_map_, spdy_session_key)) 197 if (!ContainsKey(spdy_session_request_map_, spdy_session_key))
92 break; 198 break;
93 Request* request = *spdy_session_request_map_[spdy_session_key].begin(); 199 Request* request = *spdy_session_request_map_[spdy_session_key].begin();
94 request->Complete(was_alternate_protocol_available, 200 request->Complete(was_npn_negotiated,
95 was_npn_negotiated,
96 using_spdy, 201 using_spdy,
97 source); 202 source);
98 bool use_relative_url = direct || request->url().SchemeIs("https"); 203 bool use_relative_url = direct || request->url().SchemeIs("https");
99 request->OnStreamReady(NULL, used_ssl_config, used_proxy_info, 204 request->OnStreamReady(NULL, used_ssl_config, used_proxy_info,
100 new SpdyHttpStream(spdy_session, use_relative_url)); 205 new SpdyHttpStream(spdy_session, use_relative_url));
101 } 206 }
102 // TODO(mbelshe): Alert other valid requests. 207 // TODO(mbelshe): Alert other valid requests.
103 } 208 }
104 209
105 void HttpStreamFactoryImpl::OnOrphanedJobComplete(const Job* job) { 210 void HttpStreamFactoryImpl::OnOrphanedJobComplete(const Job* job) {
106 orphaned_job_set_.erase(job); 211 orphaned_job_set_.erase(job);
107 delete job; 212 delete job;
108 } 213 }
109 214
110 void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) { 215 void HttpStreamFactoryImpl::OnPreconnectsComplete(const Job* job) {
111 preconnect_job_set_.erase(job); 216 preconnect_job_set_.erase(job);
112 delete job; 217 delete job;
113 OnPreconnectsCompleteInternal(); 218 OnPreconnectsCompleteInternal();
114 } 219 }
115 220
116 } // namespace net 221 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl.h ('k') | net/http/http_stream_factory_impl_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698