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

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

Issue 8841: Pass a user agent string to WinHttpOpen to set the user... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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_transaction_winhttp.h" 5 #include "net/http/http_transaction_winhttp.h"
6 6
7 #include <winhttp.h> 7 #include <winhttp.h>
8 8
9 #include "base/lock.h" 9 #include "base/lock.h"
10 #include "base/memory_debug.h" 10 #include "base/memory_debug.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 165
166 class HttpTransactionWinHttp::Session 166 class HttpTransactionWinHttp::Session
167 : public base::RefCounted<HttpTransactionWinHttp::Session> { 167 : public base::RefCounted<HttpTransactionWinHttp::Session> {
168 public: 168 public:
169 enum { 169 enum {
170 // By default WinHTTP enables only SSL3 and TLS1. 170 // By default WinHTTP enables only SSL3 and TLS1.
171 SECURE_PROTOCOLS_SSL3_TLS1 = WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | 171 SECURE_PROTOCOLS_SSL3_TLS1 = WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 |
172 WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 172 WINHTTP_FLAG_SECURE_PROTOCOL_TLS1
173 }; 173 };
174 174
175 Session() 175 Session();
176 : internet_(NULL),
177 internet_no_tls_(NULL),
178 message_loop_(NULL),
179 handle_closing_event_(NULL),
180 quit_event_(NULL),
181 session_callback_ref_count_(0),
182 quitting_(false),
183 rev_checking_enabled_(false),
184 secure_protocols_(SECURE_PROTOCOLS_SSL3_TLS1) {
185 }
186 176
187 bool Init(); 177 // Opens the primary WinHttp session handle.
178 bool Init(const std::string& user_agent);
188 179
189 // Opens the alternative WinHttp session handle for TLS-intolerant servers. 180 // Opens the alternative WinHttp session handle for TLS-intolerant servers.
190 bool InitNoTLS(); 181 bool InitNoTLS(const std::string& user_agent);
191 182
192 void AddRefBySessionCallback(); 183 void AddRefBySessionCallback();
193 184
194 void ReleaseBySessionCallback(); 185 void ReleaseBySessionCallback();
195 186
196 // The primary WinHttp session handle. 187 // The primary WinHttp session handle.
197 HINTERNET internet() { return internet_; } 188 HINTERNET internet() { return internet_; }
198 189
199 // An alternative WinHttp session handle. It is not opened until we have 190 // An alternative WinHttp session handle. It is not opened until we have
200 // encountered a TLS-intolerant server and used for those servers only. 191 // encountered a TLS-intolerant server and used for those servers only.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 224 }
234 225
235 private: 226 private:
236 friend class base::RefCounted<HttpTransactionWinHttp::Session>; 227 friend class base::RefCounted<HttpTransactionWinHttp::Session>;
237 228
238 ~Session(); 229 ~Session();
239 230
240 // Called by the destructor only. 231 // Called by the destructor only.
241 void WaitUntilCallbacksAllDone(); 232 void WaitUntilCallbacksAllDone();
242 233
243 HINTERNET OpenWinHttpSession(); 234 HINTERNET OpenWinHttpSession(const std::string& user_agent);
244 235
245 // Get the SSL configuration settings and apply them to the session handle. 236 // Get the SSL configuration settings and save them in rev_checking_enabled_
246 void ConfigureSSL(); 237 // and secure_protocols_.
238 void GetSSLConfig();
247 239
248 HINTERNET internet_; 240 HINTERNET internet_;
249 HINTERNET internet_no_tls_; 241 HINTERNET internet_no_tls_;
250 MessageLoop* message_loop_; 242 MessageLoop* message_loop_;
251 scoped_ptr<ProxyService> proxy_service_; 243 scoped_ptr<ProxyService> proxy_service_;
252 scoped_ptr<ProxyResolver> proxy_resolver_; 244 scoped_ptr<ProxyResolver> proxy_resolver_;
253 AuthCache auth_cache_; 245 AuthCache auth_cache_;
254 246
255 // This event object is used when destroying a transaction. It is given 247 // This event object is used when destroying a transaction. It is given
256 // to the transaction's session callback if WinHTTP still has the caller's 248 // to the transaction's session callback if WinHTTP still has the caller's
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // the session, we will have to remember all the servers we have visited 289 // the session, we will have to remember all the servers we have visited
298 // while the rev_checking_enabled setting is false. This will consume a 290 // while the rev_checking_enabled setting is false. This will consume a
299 // lot of memory. So we now require the users to restart Chrome for a 291 // lot of memory. So we now require the users to restart Chrome for a
300 // rev_checking_enabled change to take effect, just like IE does. 292 // rev_checking_enabled change to take effect, just like IE does.
301 typedef std::set<std::string> OriginSet; 293 typedef std::set<std::string> OriginSet;
302 OriginSet ignore_cert_rev_servers_; 294 OriginSet ignore_cert_rev_servers_;
303 295
304 WinHttpRequestThrottle request_throttle_; 296 WinHttpRequestThrottle request_throttle_;
305 }; 297 };
306 298
299 HttpTransactionWinHttp::Session::Session()
300 : internet_(NULL),
301 internet_no_tls_(NULL),
302 session_callback_ref_count_(0),
303 quitting_(false) {
304 proxy_resolver_.reset(new ProxyResolverWinHttp());
305 proxy_service_.reset(new ProxyService(proxy_resolver_.get()));
306
307 GetSSLConfig();
308
309 // Save the current message loop for callback notifications.
310 message_loop_ = MessageLoop::current();
311
312 handle_closing_event_ = CreateEvent(NULL,
313 FALSE, // auto-reset
314 FALSE, // initially nonsignaled
315 NULL); // unnamed
316
317 quit_event_ = CreateEvent(NULL,
318 FALSE, // auto-reset
319 FALSE, // initially nonsignaled
320 NULL); // unnamed
321 }
322
307 HttpTransactionWinHttp::Session::~Session() { 323 HttpTransactionWinHttp::Session::~Session() {
308 // It is important to shutdown the proxy service before closing the WinHTTP 324 // It is important to shutdown the proxy service before closing the WinHTTP
309 // session handle since the proxy service uses the WinHTTP session handle. 325 // session handle since the proxy service uses the WinHTTP session handle.
310 proxy_service_.reset(); 326 proxy_service_.reset();
311 327
312 // Next, the resolver which also references our session handle. 328 // Next, the resolver which also references our session handle.
313 proxy_resolver_.reset(); 329 proxy_resolver_.reset();
314 330
315 if (internet_) { 331 if (internet_) {
316 WinHttpCloseHandle(internet_); 332 WinHttpCloseHandle(internet_);
317 if (internet_no_tls_) 333 if (internet_no_tls_)
318 WinHttpCloseHandle(internet_no_tls_); 334 WinHttpCloseHandle(internet_no_tls_);
319 335
320 // Ensure that all status callbacks that may reference the MessageLoop 336 // Ensure that all status callbacks that may reference the MessageLoop
321 // of this thread are done before we can allow the current thread to exit. 337 // of this thread are done before we can allow the current thread to exit.
322 WaitUntilCallbacksAllDone(); 338 WaitUntilCallbacksAllDone();
323 } 339 }
324 340
325 if (handle_closing_event_) 341 if (handle_closing_event_)
326 CloseHandle(handle_closing_event_); 342 CloseHandle(handle_closing_event_);
327 if (quit_event_) 343 if (quit_event_)
328 CloseHandle(quit_event_); 344 CloseHandle(quit_event_);
329 } 345 }
330 346
331 bool HttpTransactionWinHttp::Session::Init() { 347 bool HttpTransactionWinHttp::Session::Init(const std::string& user_agent) {
332 DCHECK(!internet_); 348 DCHECK(!internet_);
333 349
334 internet_ = OpenWinHttpSession(); 350 internet_ = OpenWinHttpSession(user_agent);
335 351
336 if (!internet_) 352 if (!internet_)
337 return false; 353 return false;
338 354
339 proxy_resolver_.reset(new ProxyResolverWinHttp()); 355 if (secure_protocols_ != SECURE_PROTOCOLS_SSL3_TLS1) {
340 proxy_service_.reset(new ProxyService(proxy_resolver_.get())); 356 BOOL rv = WinHttpSetOption(internet_, WINHTTP_OPTION_SECURE_PROTOCOLS,
341 357 &secure_protocols_, sizeof(secure_protocols_));
342 ConfigureSSL(); 358 DCHECK(rv);
343 359 }
344 // Save the current message loop for callback notifications.
345 message_loop_ = MessageLoop::current();
346
347 handle_closing_event_ = CreateEvent(NULL,
348 FALSE, // auto-reset
349 FALSE, // initially nonsignaled
350 NULL); // unnamed
351
352 quit_event_ = CreateEvent(NULL,
353 FALSE, // auto-reset
354 FALSE, // initially nonsignaled
355 NULL); // unnamed
356 360
357 return true; 361 return true;
358 } 362 }
359 363
360 bool HttpTransactionWinHttp::Session::InitNoTLS() { 364 bool HttpTransactionWinHttp::Session::InitNoTLS(
365 const std::string& user_agent) {
361 DCHECK(tls_enabled()); 366 DCHECK(tls_enabled());
362 DCHECK(internet_); 367 DCHECK(internet_);
363 DCHECK(!internet_no_tls_); 368 DCHECK(!internet_no_tls_);
364 369
365 internet_no_tls_ = OpenWinHttpSession(); 370 internet_no_tls_ = OpenWinHttpSession(user_agent);
366 371
367 if (!internet_no_tls_) 372 if (!internet_no_tls_)
368 return false; 373 return false;
369 374
370 DWORD protocols = secure_protocols_ & ~WINHTTP_FLAG_SECURE_PROTOCOL_TLS1; 375 DWORD protocols = secure_protocols_ & ~WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
371 BOOL rv = WinHttpSetOption(internet_no_tls_, 376 BOOL rv = WinHttpSetOption(internet_no_tls_,
372 WINHTTP_OPTION_SECURE_PROTOCOLS, 377 WINHTTP_OPTION_SECURE_PROTOCOLS,
373 &protocols, sizeof(protocols)); 378 &protocols, sizeof(protocols));
374 DCHECK(rv); 379 DCHECK(rv);
375 380
(...skipping 26 matching lines...) Expand all
402 { 407 {
403 AutoLock lock(lock_); 408 AutoLock lock(lock_);
404 quitting_ = true; 409 quitting_ = true;
405 need_to_wait = (session_callback_ref_count_ != 0); 410 need_to_wait = (session_callback_ref_count_ != 0);
406 } 411 }
407 if (need_to_wait) 412 if (need_to_wait)
408 WaitForSingleObject(quit_event_, INFINITE); 413 WaitForSingleObject(quit_event_, INFINITE);
409 DCHECK(session_callback_ref_count_ == 0); 414 DCHECK(session_callback_ref_count_ == 0);
410 } 415 }
411 416
412 HINTERNET HttpTransactionWinHttp::Session::OpenWinHttpSession() { 417 HINTERNET HttpTransactionWinHttp::Session::OpenWinHttpSession(
413 // UA string and proxy config will be set explicitly for each request 418 const std::string& user_agent) {
414 HINTERNET internet = WinHttpOpen(NULL, 419 // Proxy config will be set explicitly for each request.
420 //
421 // Although UA string will also be set explicitly for each request, HTTP
422 // CONNECT requests use the UA string of the session handle, so we have to
423 // pass a UA string to WinHttpOpen.
424 HINTERNET internet = WinHttpOpen(ASCIIToWide(user_agent).c_str(),
415 WINHTTP_ACCESS_TYPE_NO_PROXY, 425 WINHTTP_ACCESS_TYPE_NO_PROXY,
416 WINHTTP_NO_PROXY_NAME, 426 WINHTTP_NO_PROXY_NAME,
417 WINHTTP_NO_PROXY_BYPASS, 427 WINHTTP_NO_PROXY_BYPASS,
418 WINHTTP_FLAG_ASYNC); 428 WINHTTP_FLAG_ASYNC);
419 if (!internet) 429 if (!internet)
420 return internet; 430 return internet;
421 431
422 // Use a 90-second timeout (1.5 times the default) for connect. Disable 432 // Use a 90-second timeout (1.5 times the default) for connect. Disable
423 // name resolution, send, and receive timeouts. We expect our consumer to 433 // name resolution, send, and receive timeouts. We expect our consumer to
424 // apply timeouts or provide controls for users to stop requests that are 434 // apply timeouts or provide controls for users to stop requests that are
425 // taking too long. 435 // taking too long.
426 BOOL rv = WinHttpSetTimeouts(internet, 0, 90000, 0, 0); 436 BOOL rv = WinHttpSetTimeouts(internet, 0, 90000, 0, 0);
427 DCHECK(rv); 437 DCHECK(rv);
428 438
429 return internet; 439 return internet;
430 } 440 }
431 441
432 void HttpTransactionWinHttp::Session::ConfigureSSL() { 442 void HttpTransactionWinHttp::Session::GetSSLConfig() {
433 DCHECK(internet_);
434
435 SSLConfig ssl_config; 443 SSLConfig ssl_config;
436 SSLConfigService::GetSSLConfigNow(&ssl_config); 444 SSLConfigService::GetSSLConfigNow(&ssl_config);
437 rev_checking_enabled_ = ssl_config.rev_checking_enabled; 445 rev_checking_enabled_ = ssl_config.rev_checking_enabled;
438 DWORD protocols = 0; 446 secure_protocols_ = 0;
439 if (ssl_config.ssl2_enabled) 447 if (ssl_config.ssl2_enabled)
440 protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL2; 448 secure_protocols_ |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL2;
441 if (ssl_config.ssl3_enabled) 449 if (ssl_config.ssl3_enabled)
442 protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL3; 450 secure_protocols_ |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL3;
443 if (ssl_config.tls1_enabled) 451 if (ssl_config.tls1_enabled)
444 protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1; 452 secure_protocols_ |= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
445 if (protocols != secure_protocols_) {
446 BOOL rv = WinHttpSetOption(internet_, WINHTTP_OPTION_SECURE_PROTOCOLS,
447 &protocols, sizeof(protocols));
448 DCHECK(rv);
449 secure_protocols_ = protocols;
450 }
451 } 453 }
452 454
453 // SessionCallback ------------------------------------------------------------ 455 // SessionCallback ------------------------------------------------------------
454 456
455 class HttpTransactionWinHttp::SessionCallback 457 class HttpTransactionWinHttp::SessionCallback
456 : public base::RefCountedThreadSafe<HttpTransactionWinHttp::SessionCallback> { 458 : public base::RefCountedThreadSafe<HttpTransactionWinHttp::SessionCallback> {
457 public: 459 public:
458 SessionCallback(HttpTransactionWinHttp* trans, Session* session) 460 SessionCallback(HttpTransactionWinHttp* trans, Session* session)
459 : trans_(trans), 461 : trans_(trans),
460 session_(session), 462 session_(session),
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 session_->Release(); 737 session_->Release();
736 } 738 }
737 739
738 HttpTransaction* HttpTransactionWinHttp::Factory::CreateTransaction() { 740 HttpTransaction* HttpTransactionWinHttp::Factory::CreateTransaction() {
739 if (is_suspended_) 741 if (is_suspended_)
740 return NULL; 742 return NULL;
741 743
742 if (!session_) { 744 if (!session_) {
743 session_ = new Session(); 745 session_ = new Session();
744 session_->AddRef(); 746 session_->AddRef();
745 if (!session_->Init()) {
746 DLOG(ERROR) << "unable to create the internet";
747 session_->Release();
748 session_ = NULL;
749 return NULL;
750 }
751 } 747 }
752 return new HttpTransactionWinHttp(session_, proxy_info_.get()); 748 return new HttpTransactionWinHttp(session_, proxy_info_.get());
753 } 749 }
754 750
755 HttpCache* HttpTransactionWinHttp::Factory::GetCache() { 751 HttpCache* HttpTransactionWinHttp::Factory::GetCache() {
756 return NULL; 752 return NULL;
757 } 753 }
758 754
759 AuthCache* HttpTransactionWinHttp::Factory::GetAuthCache() { 755 AuthCache* HttpTransactionWinHttp::Factory::GetAuthCache() {
760 return session_->auth_cache(); 756 return session_->auth_cache();
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 } 1051 }
1056 1052
1057 const std::string& host = url.host(); 1053 const std::string& host = url.host();
1058 1054
1059 // Use the primary session handle unless we are talking to a TLS-intolerant 1055 // Use the primary session handle unless we are talking to a TLS-intolerant
1060 // server. 1056 // server.
1061 // 1057 //
1062 // Since the SSL protocol versions enabled are an option of a session 1058 // Since the SSL protocol versions enabled are an option of a session
1063 // handle, supporting TLS-intolerant servers unfortunately requires opening 1059 // handle, supporting TLS-intolerant servers unfortunately requires opening
1064 // an alternative session in which TLS 1.0 is disabled. 1060 // an alternative session in which TLS 1.0 is disabled.
1061 if (!session_->internet() && !session_->Init(request_->user_agent)) {
1062 DLOG(ERROR) << "unable to create the internet";
1063 return false;
1064 }
1065 HINTERNET internet = session_->internet(); 1065 HINTERNET internet = session_->internet();
1066 if (is_tls_intolerant_) { 1066 if (is_tls_intolerant_) {
1067 if (!session_->internet_no_tls() && !session_->InitNoTLS()) { 1067 if (!session_->internet_no_tls() &&
1068 !session_->InitNoTLS(request_->user_agent)) {
1068 DLOG(ERROR) << "unable to create the no-TLS alternative internet"; 1069 DLOG(ERROR) << "unable to create the no-TLS alternative internet";
1069 return false; 1070 return false;
1070 } 1071 }
1071 internet = session_->internet_no_tls(); 1072 internet = session_->internet_no_tls();
1072 } 1073 }
1073 1074
1074 // This function operates synchronously. 1075 // This function operates synchronously.
1075 connect_handle_ = 1076 connect_handle_ =
1076 WinHttpConnect(internet, ASCIIToWide(host).c_str(), port, 0); 1077 WinHttpConnect(internet, ASCIIToWide(host).c_str(), port, 0);
1077 if (!connect_handle_) { 1078 if (!connect_handle_) {
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 1789
1789 if (rv == ERR_IO_PENDING) { 1790 if (rv == ERR_IO_PENDING) {
1790 session_callback_->AddRef(); // balanced when callback runs. 1791 session_callback_->AddRef(); // balanced when callback runs.
1791 } else if (callback_) { 1792 } else if (callback_) {
1792 DoCallback(rv); 1793 DoCallback(rv);
1793 } 1794 }
1794 } 1795 }
1795 1796
1796 } // namespace net 1797 } // namespace net
1797 1798
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698