summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_main.cc11
-rw-r--r--chrome/common/chrome_switches.cc5
-rw-r--r--chrome/common/chrome_switches.h2
-rw-r--r--net/build/net.vcproj24
-rw-r--r--net/build/net_unittests.vcproj8
-rw-r--r--net/http/cert_status_cache.cc65
-rw-r--r--net/http/cert_status_cache.h50
-rw-r--r--net/http/http_network_layer.cc19
-rw-r--r--net/http/http_network_layer.h9
-rw-r--r--net/http/http_transaction_winhttp.cc1827
-rw-r--r--net/http/http_transaction_winhttp.h199
-rw-r--r--net/http/http_transaction_winhttp_unittest.cc55
-rw-r--r--net/http/winhttp_request_throttle.cc176
-rw-r--r--net/http/winhttp_request_throttle.h104
-rw-r--r--net/http/winhttp_request_throttle_unittest.cc112
-rw-r--r--net/net.xcodeproj/project.pbxproj6
-rw-r--r--net/net_lib.scons8
-rw-r--r--net/net_unittests.scons4
-rw-r--r--net/proxy/proxy_service.cc1
-rwxr-xr-xwebkit/tools/layout_tests/run_webkit_tests.py6
-rw-r--r--webkit/tools/test_shell/test_shell_switches.cc5
-rw-r--r--webkit/tools/test_shell/test_shell_switches.h1
-rw-r--r--webkit/tools/test_shell/test_shell_win.cc36
23 files changed, 20 insertions, 2713 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 6a5b879..21e93e7 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -147,9 +147,9 @@ StringPiece NetResourceProvider(int key) {
// Main routine for running as the Browser process.
int BrowserMain(const MainFunctionParams& parameters) {
CommandLine& parsed_command_line = parameters.command_line_;
- sandbox::BrokerServices* broker_services =
+ sandbox::BrokerServices* broker_services =
parameters.sandbox_info_.BrokerServices();
-
+
// WARNING: If we get a WM_ENDSESSION objects created on the stack here
// are NOT deleted. If you need something to run during WM_ENDSESSION add it
// to browser_shutdown::Shutdown or BrowserProcess::EndSession.
@@ -180,13 +180,6 @@ int BrowserMain(const MainFunctionParams& parameters) {
main_message_loop.set_thread_name(thread_name);
bool already_running = Upgrade::IsBrowserAlreadyRunning();
-#if defined(OS_WIN)
- // Make the selection of network stacks early on before any consumers try to
- // issue HTTP requests.
- if (parsed_command_line.HasSwitch(switches::kUseWinHttp))
- net::HttpNetworkLayer::UseWinHttp(true);
-#endif
-
std::wstring user_data_dir;
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
BrowserInit::MessageWindow message_window(user_data_dir);
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index cc390da..046b7ea 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -315,9 +315,6 @@ const wchar_t kGearsPluginPathOverride[] = L"gears-plugin-path";
// Switch to load Gears in the renderer process.
const wchar_t kGearsInRenderer[] = L"gears-in-renderer";
-// Enable winhttp HTTP stack.
-const wchar_t kUseWinHttp[] = L"winhttp";
-
// Enable the fastback page cache.
const wchar_t kEnableFastback[] = L"enable-fastback";
@@ -346,7 +343,7 @@ const wchar_t kIncognito[] = L"incognito";
// problems on some computers during updates.
const wchar_t kUseOldSafeBrowsing[] = L"old-safe-browsing";
-// Turns on the accessibility in the renderer. Off by default until
+// Turns on the accessibility in the renderer. Off by default until
// http://b/issue?id=1432077 is fixed.
const wchar_t kEnableRendererAccessibility[] = L"enable-renderer-accessibility";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index acd84a7..e712596 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -119,8 +119,6 @@ extern const wchar_t kGearsPluginPathOverride[];
extern const wchar_t kGearsInRenderer[];
-extern const wchar_t kUseWinHttp[];
-
extern const wchar_t kEnableFastback[];
extern const wchar_t kJavaScriptDebuggerPath[];
diff --git a/net/build/net.vcproj b/net/build/net.vcproj
index 275d7fd..5a71089 100644
--- a/net/build/net.vcproj
+++ b/net/build/net.vcproj
@@ -685,14 +685,6 @@
Name="http"
>
<File
- RelativePath="..\http\cert_status_cache.cc"
- >
- </File>
- <File
- RelativePath="..\http\cert_status_cache.h"
- >
- </File>
- <File
RelativePath="..\http\http_atom_list.h"
>
</File>
@@ -757,14 +749,6 @@
>
</File>
<File
- RelativePath="..\http\http_transaction_winhttp.cc"
- >
- </File>
- <File
- RelativePath="..\http\http_transaction_winhttp.h"
- >
- </File>
- <File
RelativePath="..\http\http_util.cc"
>
</File>
@@ -852,14 +836,6 @@
RelativePath="..\http\http_vary_data.h"
>
</File>
- <File
- RelativePath="..\http\winhttp_request_throttle.cc"
- >
- </File>
- <File
- RelativePath="..\http\winhttp_request_throttle.h"
- >
- </File>
</Filter>
<Filter
Name="disk_cache"
diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj
index 0180e11..c28bc20 100644
--- a/net/build/net_unittests.vcproj
+++ b/net/build/net_unittests.vcproj
@@ -271,10 +271,6 @@
>
</File>
<File
- RelativePath="..\http\http_transaction_winhttp_unittest.cc"
- >
- </File>
- <File
RelativePath="..\http\http_util_unittest.cc"
>
</File>
@@ -282,10 +278,6 @@
RelativePath="..\http\http_vary_data_unittest.cc"
>
</File>
- <File
- RelativePath="..\http\winhttp_request_throttle_unittest.cc"
- >
- </File>
</Filter>
<Filter
Name="base"
diff --git a/net/http/cert_status_cache.cc b/net/http/cert_status_cache.cc
deleted file mode 100644
index 12e5723..0000000
--- a/net/http/cert_status_cache.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/cert_status_flags.h"
-#include "net/http/cert_status_cache.h"
-
-namespace net {
-
-CertStatusCache::CertStatusCache() {
-}
-
-CertStatusCache::~CertStatusCache() {
- for (HostMap::iterator iter = fingerprint_to_bad_hosts_.begin();
- iter != fingerprint_to_bad_hosts_.end(); ++iter) {
- delete iter->second;
- }
-}
-
-int CertStatusCache::GetCertStatus(const X509Certificate& cert,
- const std::string& host) const {
- StatusMap::const_iterator iter =
- fingerprint_to_cert_status_.find(cert.fingerprint());
- if (iter != fingerprint_to_cert_status_.end()) {
- int cert_status = iter->second;
-
- // We get the CERT_STATUS_COMMON_NAME_INVALID error based on the host.
- HostMap::const_iterator fp_iter =
- fingerprint_to_bad_hosts_.find(cert.fingerprint());
- if (fp_iter != fingerprint_to_bad_hosts_.end()) {
- StringSet* bad_hosts = fp_iter->second;
- StringSet::const_iterator host_iter = bad_hosts->find(host);
- if (host_iter != bad_hosts->end())
- cert_status |= net::CERT_STATUS_COMMON_NAME_INVALID;
- }
-
- return cert_status;
- }
- return 0; // The cert has never had errors.
-}
-
-void CertStatusCache::SetCertStatus(const X509Certificate& cert,
- const std::string& host,
- int status) {
- // We store the CERT_STATUS_COMMON_NAME_INVALID status separately as it is
- // host related.
- fingerprint_to_cert_status_[cert.fingerprint()] =
- status & ~net::CERT_STATUS_COMMON_NAME_INVALID;
-
- if ((status & net::CERT_STATUS_COMMON_NAME_INVALID) != 0) {
- StringSet* bad_hosts;
- HostMap::const_iterator iter =
- fingerprint_to_bad_hosts_.find(cert.fingerprint());
- if (iter == fingerprint_to_bad_hosts_.end()) {
- bad_hosts = new StringSet;
- fingerprint_to_bad_hosts_[cert.fingerprint()] = bad_hosts;
- } else {
- bad_hosts = iter->second;
- }
- bad_hosts->insert(host);
- }
-}
-
-}
-
diff --git a/net/http/cert_status_cache.h b/net/http/cert_status_cache.h
deleted file mode 100644
index eb0a5c3..0000000
--- a/net/http/cert_status_cache.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_HTTP_CERT_STATUS_CACHE_H
-#define NET_HTTP_CERT_STATUS_CACHE_H
-
-#include <vector>
-#include <map>
-
-#include "net/base/x509_certificate.h"
-
-// This class is used to remember the status of certificates, as WinHTTP
-// does not report errors once it has been told to ignore them.
-// It only exists because of the WinHTTP bug.
-// IMPORTANT: this class is not thread-safe.
-
-namespace net {
-
-class CertStatusCache {
- public:
- CertStatusCache();
- ~CertStatusCache();
-
- int GetCertStatus(const X509Certificate& cert,
- const std::string& host_name) const;
- void SetCertStatus(const X509Certificate& cert,
- const std::string& host_name,
- int status);
-
- private:
- typedef std::map<X509Certificate::Fingerprint, int,
- X509Certificate::FingerprintLessThan> StatusMap;
- typedef std::set<std::string> StringSet;
- typedef std::map<X509Certificate::Fingerprint, StringSet*,
- X509Certificate::FingerprintLessThan> HostMap;
-
- StatusMap fingerprint_to_cert_status_;
-
- // We keep a map for each cert to the list of host names that have been marked
- // with the CN invalid error, as that error is host name specific.
- HostMap fingerprint_to_bad_hosts_;
-
- DISALLOW_EVIL_CONSTRUCTORS(CertStatusCache);
-};
-
-} // namespace net
-
-#endif // NET_HTTP_CERT_STATUS_CACHE_H
-
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 2b84682..23f53f7 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.cc
@@ -8,38 +8,19 @@
#include "net/base/client_socket_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_transaction.h"
-#if defined(OS_WIN)
-#include "net/http/http_transaction_winhttp.h"
-#endif
namespace net {
//-----------------------------------------------------------------------------
-#if defined(OS_WIN)
-// static
-bool HttpNetworkLayer::use_winhttp_ = false;
-#endif
-
// static
HttpTransactionFactory* HttpNetworkLayer::CreateFactory(
ProxyService* proxy_service) {
DCHECK(proxy_service);
-#if defined(OS_WIN)
- if (use_winhttp_)
- return new HttpTransactionWinHttp::Factory(proxy_service);
-#endif
return new HttpNetworkLayer(proxy_service);
}
-#if defined(OS_WIN)
-// static
-void HttpNetworkLayer::UseWinHttp(bool value) {
- use_winhttp_ = value;
-}
-#endif
-
//-----------------------------------------------------------------------------
HttpNetworkLayer::HttpNetworkLayer(ProxyService* proxy_service)
diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h
index 5364642..8424b2f 100644
--- a/net/http/http_network_layer.h
+++ b/net/http/http_network_layer.h
@@ -25,21 +25,12 @@ class HttpNetworkLayer : public HttpTransactionFactory {
// and allows other implementations to be substituted.
static HttpTransactionFactory* CreateFactory(ProxyService* proxy_service);
-#if defined(OS_WIN)
- // If value is true, then WinHTTP will be used.
- static void UseWinHttp(bool value);
-#endif
-
// HttpTransactionFactory methods:
virtual HttpTransaction* CreateTransaction();
virtual HttpCache* GetCache();
virtual void Suspend(bool suspend);
private:
-#if defined(OS_WIN)
- static bool use_winhttp_;
-#endif
-
// The proxy service being used for the session.
ProxyService* proxy_service_;
diff --git a/net/http/http_transaction_winhttp.cc b/net/http/http_transaction_winhttp.cc
deleted file mode 100644
index 06cd391..0000000
--- a/net/http/http_transaction_winhttp.cc
+++ /dev/null
@@ -1,1827 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/http_transaction_winhttp.h"
-
-#include <winhttp.h>
-
-#include "base/lock.h"
-#include "base/memory_debug.h"
-#include "base/message_loop.h"
-#include "base/string_piece.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/auth_cache.h"
-#include "net/base/cert_status_flags.h"
-#include "net/base/dns_resolution_observer.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "net/base/ssl_config_service.h"
-#include "net/base/upload_data_stream.h"
-#include "net/http/cert_status_cache.h"
-#include "net/http/http_request_info.h"
-#include "net/http/winhttp_request_throttle.h"
-#include "net/proxy/proxy_resolver_winhttp.h"
-
-#pragma comment(lib, "winhttp.lib")
-#pragma warning(disable: 4355)
-
-using base::Time;
-
-namespace net {
-
-static int TranslateOSError(DWORD error) {
- switch (error) {
- case ERROR_SUCCESS:
- return OK;
- case ERROR_FILE_NOT_FOUND:
- return ERR_FILE_NOT_FOUND;
- case ERROR_HANDLE_EOF: // TODO(wtc): return OK?
- return ERR_CONNECTION_CLOSED;
- case ERROR_INVALID_HANDLE:
- return ERR_INVALID_HANDLE;
- case ERROR_INVALID_PARAMETER:
- return ERR_INVALID_ARGUMENT;
-
- case ERROR_WINHTTP_CANNOT_CONNECT:
- return ERR_CONNECTION_FAILED;
- case ERROR_WINHTTP_TIMEOUT:
- return ERR_TIMED_OUT;
- case ERROR_WINHTTP_INVALID_URL:
- return ERR_INVALID_URL;
- case ERROR_WINHTTP_NAME_NOT_RESOLVED:
- return ERR_NAME_NOT_RESOLVED;
- case ERROR_WINHTTP_OPERATION_CANCELLED:
- return ERR_ABORTED;
- case ERROR_WINHTTP_SECURE_CHANNEL_ERROR:
- case ERROR_WINHTTP_SECURE_FAILURE:
- case SEC_E_ILLEGAL_MESSAGE:
- return ERR_SSL_PROTOCOL_ERROR;
- case SEC_E_ALGORITHM_MISMATCH:
- return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
- case ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED:
- return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
- case ERROR_WINHTTP_UNRECOGNIZED_SCHEME:
- return ERR_UNKNOWN_URL_SCHEME;
- case ERROR_WINHTTP_INVALID_SERVER_RESPONSE:
- return ERR_INVALID_RESPONSE;
-
- // SSL certificate errors
- case ERROR_WINHTTP_SECURE_CERT_CN_INVALID:
- return ERR_CERT_COMMON_NAME_INVALID;
- case ERROR_WINHTTP_SECURE_CERT_DATE_INVALID:
- return ERR_CERT_DATE_INVALID;
- case ERROR_WINHTTP_SECURE_INVALID_CA:
- return ERR_CERT_AUTHORITY_INVALID;
- case ERROR_WINHTTP_SECURE_CERT_REV_FAILED:
- return ERR_CERT_UNABLE_TO_CHECK_REVOCATION;
- case ERROR_WINHTTP_SECURE_CERT_REVOKED:
- return ERR_CERT_REVOKED;
- case ERROR_WINHTTP_SECURE_INVALID_CERT:
- return ERR_CERT_INVALID;
-
- default:
- DCHECK(error != ERROR_IO_PENDING); // WinHTTP doesn't use this error.
- LOG(WARNING) << "Unknown error " << error
- << " mapped to net::ERR_FAILED";
- return ERR_FAILED;
- }
-}
-
-static int TranslateLastOSError() {
- return TranslateOSError(GetLastError());
-}
-
-// Clear certificate errors that we want to ignore.
-static DWORD FilterSecureFailure(DWORD status, int load_flags) {
- if (load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID)
- status &= ~WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID;
- if (load_flags & LOAD_IGNORE_CERT_DATE_INVALID)
- status &= ~WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID;
- if (load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID)
- status &= ~WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA;
- if (load_flags & LOAD_IGNORE_CERT_WRONG_USAGE)
- status &= ~WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE;
- return status;
-}
-
-static DWORD MapSecureFailureToError(DWORD status) {
- // A certificate may have multiple errors. We report the most
- // serious error.
-
- // Unrecoverable errors
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR)
- return ERROR_WINHTTP_SECURE_CHANNEL_ERROR;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
- return ERROR_WINHTTP_SECURE_INVALID_CERT;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
- return ERROR_WINHTTP_SECURE_CERT_REVOKED;
-
- // Recoverable errors
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
- return ERROR_WINHTTP_SECURE_INVALID_CA;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
- return ERROR_WINHTTP_SECURE_CERT_CN_INVALID;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
- return ERROR_WINHTTP_SECURE_CERT_DATE_INVALID;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
- return ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE;
-
- // Unknown status. Give it the benefit of the doubt.
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
- return ERROR_WINHTTP_SECURE_CERT_REV_FAILED;
-
- // Map a status of 0 to the generic secure failure error. We have seen a
- // case where WinHttp doesn't notify us of a secure failure (so status is 0)
- // before notifying us of a request error with ERROR_WINHTTP_SECURE_FAILURE.
- // (WinInet fails with ERROR_INTERNET_SECURITY_CHANNEL_ERROR in that case.)
- return ERROR_WINHTTP_SECURE_FAILURE;
-}
-
-static int MapSecureFailureToCertStatus(DWORD status) {
- int cert_status = 0;
-
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
- cert_status |= CERT_STATUS_INVALID;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
- cert_status |= CERT_STATUS_REVOKED;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
- cert_status |= CERT_STATUS_AUTHORITY_INVALID;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
- cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
- cert_status |= CERT_STATUS_DATE_INVALID;
- if (status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
- cert_status |= CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
-
- return cert_status;
- // TODO(jcampan): what about ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE?
-}
-
-// Session --------------------------------------------------------------------
-
-class HttpTransactionWinHttp::Session
- : public base::RefCounted<HttpTransactionWinHttp::Session> {
- public:
- enum {
- // By default WinHTTP enables only SSL3 and TLS1.
- SECURE_PROTOCOLS_SSL3_TLS1 = WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 |
- WINHTTP_FLAG_SECURE_PROTOCOL_TLS1
- };
-
- explicit Session(ProxyService* proxy_service);
-
- // Opens the primary WinHttp session handle.
- bool Init(const std::string& user_agent);
-
- // Opens the alternative WinHttp session handle for TLS-intolerant servers.
- bool InitNoTLS(const std::string& user_agent);
-
- void AddRefBySessionCallback();
-
- void ReleaseBySessionCallback();
-
- // The primary WinHttp session handle.
- HINTERNET internet() { return internet_; }
-
- // An alternative WinHttp session handle. It is not opened until we have
- // encountered a TLS-intolerant server and used for those servers only.
- // TLS is disabled in this session.
- HINTERNET internet_no_tls() { return internet_no_tls_; }
-
- // The message loop of the thread where the session was created.
- MessageLoop* message_loop() { return message_loop_; }
-
- ProxyService* proxy_service() { return proxy_service_; }
-
- // Gets the HTTP authentication cache for the session.
- AuthCache* auth_cache() { return &auth_cache_; }
-
- HANDLE handle_closing_event() const { return handle_closing_event_; }
-
- CertStatusCache* cert_status_cache() { return &cert_status_cache_; }
-
- bool rev_checking_enabled() const { return rev_checking_enabled_; }
-
- bool tls_enabled() const {
- return (secure_protocols_ & WINHTTP_FLAG_SECURE_PROTOCOL_TLS1) != 0;
- }
-
- bool ShouldIgnoreCertRev(const std::string& origin) const {
- OriginSet::const_iterator pos = ignore_cert_rev_servers_.find(origin);
- return pos != ignore_cert_rev_servers_.end();
- }
-
- void IgnoreCertRev(const std::string& origin) {
- ignore_cert_rev_servers_.insert(origin);
- }
-
- WinHttpRequestThrottle* request_throttle() {
- return &request_throttle_;
- }
-
- private:
- friend class base::RefCounted<HttpTransactionWinHttp::Session>;
-
- ~Session();
-
- // Called by the destructor only.
- void WaitUntilCallbacksAllDone();
-
- HINTERNET OpenWinHttpSession(const std::string& user_agent);
-
- // Get the SSL configuration settings and save them in rev_checking_enabled_
- // and secure_protocols_.
- void GetSSLConfig();
-
- HINTERNET internet_;
- HINTERNET internet_no_tls_;
- MessageLoop* message_loop_;
- ProxyService* proxy_service_;
- AuthCache auth_cache_;
-
- // This event object is used when destroying a transaction. It is given
- // to the transaction's session callback if WinHTTP still has the caller's
- // data (request info or read buffer) and we need to wait until WinHTTP is
- // done with the data.
- HANDLE handle_closing_event_;
-
- // The following members ensure a clean destruction of the Session object.
- // The Session destructor waits until all the request handles have been
- // terminated by WinHTTP, at which point no more status callbacks will
- // reference the MessageLoop of the Session.
- //
- // quit_event_ is the event object used for this wait.
- //
- // lock_ protects session_callback_ref_count_ and quitting_.
- //
- // session_callback_ref_count_ is the number of SessionCallback objects
- // that may reference the MessageLoop of the Session.
- //
- // The boolean quitting_ is true when the Session object is being
- // destructed.
- HANDLE quit_event_;
- Lock lock_;
- int session_callback_ref_count_;
- bool quitting_;
-
- // We use a cache to store the certificate error as we cannot always rely on
- // WinHTTP to provide us the SSL error once we restarted a connection asking
- // to ignored errors.
- CertStatusCache cert_status_cache_;
-
- // SSL settings
- bool rev_checking_enabled_;
- DWORD secure_protocols_;
-
- // The servers for which certificate revocation should be ignored.
- //
- // WinHTTP verifies each certificate only once and caches the certificate
- // verification results, so if we ever ignore certificate revocation for a
- // server, we cannot enable revocation checking again for that server for
- // the rest of the session.
- //
- // If we honor changes to the rev_checking_enabled system setting during
- // the session, we will have to remember all the servers we have visited
- // while the rev_checking_enabled setting is false. This will consume a
- // lot of memory. So we now require the users to restart Chrome for a
- // rev_checking_enabled change to take effect, just like IE does.
- typedef std::set<std::string> OriginSet;
- OriginSet ignore_cert_rev_servers_;
-
- WinHttpRequestThrottle request_throttle_;
-};
-
-HttpTransactionWinHttp::Session::Session(ProxyService* proxy_service)
- : internet_(NULL),
- internet_no_tls_(NULL),
- proxy_service_(proxy_service),
- session_callback_ref_count_(0),
- quitting_(false) {
- GetSSLConfig();
-
- // Save the current message loop for callback notifications.
- message_loop_ = MessageLoop::current();
-
- handle_closing_event_ = CreateEvent(NULL,
- FALSE, // auto-reset
- FALSE, // initially nonsignaled
- NULL); // unnamed
-
- quit_event_ = CreateEvent(NULL,
- FALSE, // auto-reset
- FALSE, // initially nonsignaled
- NULL); // unnamed
-}
-
-HttpTransactionWinHttp::Session::~Session() {
- if (internet_) {
- WinHttpCloseHandle(internet_);
- if (internet_no_tls_)
- WinHttpCloseHandle(internet_no_tls_);
-
- // Ensure that all status callbacks that may reference the MessageLoop
- // of this thread are done before we can allow the current thread to exit.
- WaitUntilCallbacksAllDone();
- }
-
- if (handle_closing_event_)
- CloseHandle(handle_closing_event_);
- if (quit_event_)
- CloseHandle(quit_event_);
-}
-
-bool HttpTransactionWinHttp::Session::Init(const std::string& user_agent) {
- DCHECK(!internet_);
-
- internet_ = OpenWinHttpSession(user_agent);
-
- if (!internet_)
- return false;
-
- if (secure_protocols_ != SECURE_PROTOCOLS_SSL3_TLS1) {
- BOOL rv = WinHttpSetOption(internet_, WINHTTP_OPTION_SECURE_PROTOCOLS,
- &secure_protocols_, sizeof(secure_protocols_));
- DCHECK(rv);
- }
-
- return true;
-}
-
-bool HttpTransactionWinHttp::Session::InitNoTLS(
- const std::string& user_agent) {
- DCHECK(tls_enabled());
- DCHECK(internet_);
- DCHECK(!internet_no_tls_);
-
- internet_no_tls_ = OpenWinHttpSession(user_agent);
-
- if (!internet_no_tls_)
- return false;
-
- DWORD protocols = secure_protocols_ & ~WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
- BOOL rv = WinHttpSetOption(internet_no_tls_,
- WINHTTP_OPTION_SECURE_PROTOCOLS,
- &protocols, sizeof(protocols));
- DCHECK(rv);
-
- return true;
-}
-
-void HttpTransactionWinHttp::Session::AddRefBySessionCallback() {
- AutoLock lock(lock_);
- session_callback_ref_count_++;
-}
-
-void HttpTransactionWinHttp::Session::ReleaseBySessionCallback() {
- bool need_to_signal;
- {
- AutoLock lock(lock_);
- session_callback_ref_count_--;
- need_to_signal = (quitting_ && session_callback_ref_count_ == 0);
- }
- if (need_to_signal)
- SetEvent(quit_event_);
-}
-
-// This is called by the Session destructor only. By now the transaction
-// factory and all the transactions have been destructed. This means that
-// new transactions can't be created, and existing transactions can't be
-// started, which in turn implies that session_callback_ref_count_ cannot
-// increase. We wait until session_callback_ref_count_ drops to 0.
-void HttpTransactionWinHttp::Session::WaitUntilCallbacksAllDone() {
- bool need_to_wait;
- {
- AutoLock lock(lock_);
- quitting_ = true;
- need_to_wait = (session_callback_ref_count_ != 0);
- }
- if (need_to_wait)
- WaitForSingleObject(quit_event_, INFINITE);
- DCHECK(session_callback_ref_count_ == 0);
-}
-
-HINTERNET HttpTransactionWinHttp::Session::OpenWinHttpSession(
- const std::string& user_agent) {
- // Proxy config will be set explicitly for each request.
- //
- // Although UA string will also be set explicitly for each request, HTTP
- // CONNECT requests use the UA string of the session handle, so we have to
- // pass a UA string to WinHttpOpen.
- HINTERNET internet = WinHttpOpen(ASCIIToWide(user_agent).c_str(),
- WINHTTP_ACCESS_TYPE_NO_PROXY,
- WINHTTP_NO_PROXY_NAME,
- WINHTTP_NO_PROXY_BYPASS,
- WINHTTP_FLAG_ASYNC);
- if (!internet)
- return internet;
-
- // Use a 90-second timeout (1.5 times the default) for connect. Disable
- // name resolution, send, and receive timeouts. We expect our consumer to
- // apply timeouts or provide controls for users to stop requests that are
- // taking too long.
- BOOL rv = WinHttpSetTimeouts(internet, 0, 90000, 0, 0);
- DCHECK(rv);
-
- return internet;
-}
-
-void HttpTransactionWinHttp::Session::GetSSLConfig() {
- SSLConfig ssl_config;
- SSLConfigService::GetSSLConfigNow(&ssl_config);
- rev_checking_enabled_ = ssl_config.rev_checking_enabled;
- secure_protocols_ = 0;
- if (ssl_config.ssl2_enabled)
- secure_protocols_ |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL2;
- if (ssl_config.ssl3_enabled)
- secure_protocols_ |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL3;
- if (ssl_config.tls1_enabled)
- secure_protocols_ |= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
-}
-
-// SessionCallback ------------------------------------------------------------
-
-class HttpTransactionWinHttp::SessionCallback
- : public base::RefCountedThreadSafe<HttpTransactionWinHttp::SessionCallback> {
- public:
- SessionCallback(HttpTransactionWinHttp* trans, Session* session)
- : trans_(trans),
- session_(session),
- load_state_(LOAD_STATE_IDLE),
- handle_closing_event_(NULL),
- bytes_available_(0),
- read_buf_(NULL),
- read_buf_len_(0),
- secure_failure_(0),
- connection_was_opened_(false),
- request_was_probably_sent_(false),
- response_was_received_(false),
- response_is_empty_(true) {
- }
-
- // Called when the associated trans_ has to reopen its connection and
- // request handles to recover from certain SSL errors. Resets the members
- // that may have been modified at that point.
- void ResetForNewRequest() {
- secure_failure_ = 0;
- connection_was_opened_ = false;
- }
-
- void DropTransaction() {
- trans_ = NULL;
- }
-
- void Notify(DWORD status, DWORD_PTR result, DWORD error) {
- DWORD secure_failure = 0;
- if (status == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) {
- switch (error) {
- // WinHttp sends this error code in two interesting cases: 1) when a
- // response header is malformed, and 2) when a response is empty. In
- // the latter case, we want to actually resend the request if the
- // request was sent over a reused "keep-alive" connection. This is a
- // risky thing to do since it is possible that the server did receive
- // our request, but it is unfortunately required to support HTTP keep-
- // alive connections properly, and other browsers all do this too.
- case ERROR_WINHTTP_INVALID_SERVER_RESPONSE:
- if (empty_response_was_received() && !connection_was_opened_)
- error = ERROR_WINHTTP_RESEND_REQUEST;
- break;
- case ERROR_WINHTTP_SECURE_FAILURE:
- secure_failure = secure_failure_;
- break;
- }
- } else if (status == WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE) {
- secure_failure = secure_failure_;
- }
- session_->message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this,
- &HttpTransactionWinHttp::SessionCallback::OnNotify,
- status, result, error, secure_failure));
- }
-
- // Calls WinHttpReadData and returns its return value.
- BOOL ReadData(HINTERNET request_handle);
-
- void OnHandleClosing() {
- if (handle_closing_event_)
- SetEvent(handle_closing_event_);
- session_->ReleaseBySessionCallback();
- Release();
- }
-
- // Modified from any thread.
- void set_load_state(LoadState state) {
- load_state_ = state;
- }
- LoadState load_state() const {
- return load_state_;
- }
-
- int bytes_available() const { return bytes_available_; }
- void set_bytes_available(int n) { bytes_available_ = n; }
- void reduce_bytes_available(int n) { bytes_available_ -= n; }
-
- char* read_buf() const { return read_buf_; }
- void set_read_buf(char* buf) { read_buf_ = buf; }
-
- int read_buf_len() const { return read_buf_len_; }
- void set_read_buf_len(int buf_len) { read_buf_len_ = buf_len; }
-
- // Tells this SessionCallback to signal this event when receiving the
- // handle closing status callback.
- void set_handle_closing_event(HANDLE event) {
- handle_closing_event_ = event;
- }
-
- void set_secure_failure(DWORD flags) { secure_failure_ = flags; }
-
- void did_open_connection() {
- connection_was_opened_ = true;
- }
-
- void did_start_sending_request() {
- request_was_probably_sent_ = true;
- }
- bool request_was_probably_sent() const {
- return request_was_probably_sent_;
- }
-
- void did_receive_bytes(DWORD count) {
- response_was_received_ = true;
- if (count)
- response_is_empty_ = false;
- }
-
- private:
- friend base::RefCountedThreadSafe<HttpTransactionWinHttp::SessionCallback>;
- ~SessionCallback() {}
-
- void OnNotify(DWORD status,
- DWORD_PTR result,
- DWORD error,
- DWORD secure_failure) {
- if (trans_)
- trans_->HandleStatusCallback(status, result, error, secure_failure);
-
- // Balances the AddRefs made by the transaction object after an async
- // WinHTTP call.
- Release();
- }
-
- bool empty_response_was_received() const {
- return response_was_received_ && response_is_empty_;
- }
-
- HttpTransactionWinHttp* trans_;
-
- // Session is reference-counted, but this is a plain pointer. The
- // reference on the Session owned by SessionCallback is managed using
- // Session::AddRefBySessionCallback and Session::ReleaseBySessionCallback.
- Session* session_;
-
- // Modified from any thread.
- volatile LoadState load_state_;
-
- // Amount of data available reported by WinHttpQueryDataAvailable that
- // haven't been consumed by WinHttpReadData.
- int bytes_available_;
-
- // Caller's read buffer and buffer size, to be passed to WinHttpReadData.
- // These are used by the IO thread and the thread WinHTTP uses to make
- // status callbacks, but not at the same time.
- char* read_buf_;
- int read_buf_len_;
-
- // If not null, we set this event on receiving the handle closing callback.
- HANDLE handle_closing_event_;
-
- // The secure connection failure flags reported by the
- // WINHTTP_CALLBACK_STATUS_SECURE_FAILURE status callback.
- DWORD secure_failure_;
-
- // True if a connection was opened for this request.
- bool connection_was_opened_;
-
- // True if the request may have been sent to the server (and therefore we
- // should not restart the request).
- bool request_was_probably_sent_;
-
- // True if any response was received.
- bool response_was_received_;
-
- // True if we have an empty response (no headers, no status line, nothing).
- bool response_is_empty_;
-};
-
-BOOL HttpTransactionWinHttp::SessionCallback::ReadData(
- HINTERNET request_handle) {
- DCHECK(bytes_available_ >= 0);
- char* buf = read_buf_;
- read_buf_ = NULL;
- int bytes_to_read = std::min(bytes_available_, read_buf_len_);
- read_buf_len_ = 0;
- if (!bytes_to_read)
- bytes_to_read = 1;
-
- // Because of how WinHTTP fills memory when used asynchronously, Purify isn't
- // able to detect that it's been initialized, so it scans for 0xcd in the
- // buffer and reports UMRs (uninitialized memory reads) for those individual
- // bytes. We override that to avoid the false error reports.
- // See http://b/issue?id=1173916.
- base::MemoryDebug::MarkAsInitialized(buf, bytes_to_read);
- return WinHttpReadData(request_handle, buf, bytes_to_read, NULL);
-}
-
-// static
-void HttpTransactionWinHttp::StatusCallback(HINTERNET handle,
- DWORD_PTR context,
- DWORD status,
- LPVOID status_info,
- DWORD status_info_len) {
- SessionCallback* callback = reinterpret_cast<SessionCallback*>(context);
-
- switch (status) {
- case WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING:
- if (callback)
- callback->OnHandleClosing();
- break;
- case WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER:
- callback->set_load_state(LOAD_STATE_CONNECTING);
- break;
- case WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER:
- callback->did_open_connection();
- break;
- case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST:
- callback->set_load_state(LOAD_STATE_SENDING_REQUEST);
- callback->did_start_sending_request();
- break;
- case WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE:
- callback->set_load_state(LOAD_STATE_WAITING_FOR_RESPONSE);
- break;
- case WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED:
- callback->did_receive_bytes(*static_cast<DWORD*>(status_info));
- break;
- case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE:
- DCHECK(callback->bytes_available() == 0);
- DCHECK(status_info_len == sizeof(DWORD));
- callback->set_bytes_available(static_cast<DWORD*>(status_info)[0]);
- if (!callback->ReadData(handle))
- callback->Notify(WINHTTP_CALLBACK_STATUS_REQUEST_ERROR,
- API_READ_DATA, GetLastError());
- break;
- case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
- callback->Notify(status, status_info_len, 0);
- break;
- case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:
- DCHECK(status_info_len == sizeof(DWORD));
- callback->Notify(status, static_cast<DWORD*>(status_info)[0], 0);
- break;
- case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
- callback->Notify(status, TRUE, 0);
- break;
- case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
- callback->Notify(status, TRUE, 0);
- break;
- case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: {
- WINHTTP_ASYNC_RESULT* result =
- static_cast<WINHTTP_ASYNC_RESULT*>(status_info);
- callback->Notify(status, result->dwResult, result->dwError);
- if (API_SEND_REQUEST == result->dwResult &&
- ERROR_WINHTTP_NAME_NOT_RESOLVED == result->dwError)
- DidFinishDnsResolutionWithStatus(false,
- GURL(), // null referrer URL.
- reinterpret_cast<void*>(context));
- break;
- }
- // This status callback provides the detailed reason for a secure
- // failure. We map that to an error code and save it for later use.
- case WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: {
- DCHECK(status_info_len == sizeof(DWORD));
- DWORD* status_ptr = static_cast<DWORD*>(status_info);
- callback->set_secure_failure(*status_ptr);
- break;
- }
- // Looking up the IP address of a server name. The status_info
- // parameter contains a pointer to the server name being resolved.
- case WINHTTP_CALLBACK_STATUS_RESOLVING_NAME: {
- callback->set_load_state(LOAD_STATE_RESOLVING_HOST);
- std::wstring wname(static_cast<wchar_t*>(status_info),
- status_info_len - 1);
- DidStartDnsResolution(WideToASCII(wname),
- reinterpret_cast<void*>(context));
- break;
- }
- // Successfully found the IP address of the server.
- case WINHTTP_CALLBACK_STATUS_NAME_RESOLVED:
- DidFinishDnsResolutionWithStatus(true,
- GURL(), // null referrer URL.
- reinterpret_cast<void*>(context));
- break;
- }
-}
-
-// Factory --------------------------------------------------------------------
-
-HttpTransactionWinHttp::Factory::~Factory() {
- if (session_)
- session_->Release();
-}
-
-HttpTransaction* HttpTransactionWinHttp::Factory::CreateTransaction() {
- if (is_suspended_)
- return NULL;
-
- if (!session_) {
- session_ = new Session(proxy_service_);
- session_->AddRef();
- }
- return new HttpTransactionWinHttp(session_, proxy_service_->proxy_info());
-}
-
-HttpCache* HttpTransactionWinHttp::Factory::GetCache() {
- return NULL;
-}
-
-void HttpTransactionWinHttp::Factory::Suspend(bool suspend) {
- is_suspended_ = suspend;
-
- if (is_suspended_ && session_) {
- session_->Release();
- session_ = NULL;
- }
-}
-
-// Transaction ----------------------------------------------------------------
-
-HttpTransactionWinHttp::HttpTransactionWinHttp(Session* session,
- const ProxyInfo* info)
- : session_(session),
- request_(NULL),
- load_flags_(0),
- last_error_(ERROR_SUCCESS),
- content_length_remaining_(-1),
- pac_request_(NULL),
- proxy_callback_(this, &HttpTransactionWinHttp::OnProxyInfoAvailable),
- callback_(NULL),
- upload_progress_(0),
- connect_handle_(NULL),
- request_handle_(NULL),
- is_https_(false),
- is_tls_intolerant_(false),
- rev_checking_enabled_(false),
- have_proxy_info_(false),
- need_to_wait_for_handle_closing_(false),
- request_submitted_(false),
- used_embedded_credentials_(false) {
- session->AddRef();
- session_callback_ = new SessionCallback(this, session);
- if (info) {
- proxy_info_.Use(*info);
- have_proxy_info_ = true;
- }
-}
-
-HttpTransactionWinHttp::~HttpTransactionWinHttp() {
- if (pac_request_)
- session_->proxy_service()->CancelPacRequest(pac_request_);
-
- if (request_handle_) {
- if (need_to_wait_for_handle_closing_) {
- session_callback_->set_handle_closing_event(
- session_->handle_closing_event());
- }
- WinHttpCloseHandle(request_handle_);
- if (need_to_wait_for_handle_closing_)
- WaitForSingleObject(session_->handle_closing_event(), INFINITE);
- }
- if (connect_handle_)
- WinHttpCloseHandle(connect_handle_);
-
- if (request_submitted_) {
- session_->request_throttle()->RemoveRequest(connect_peer_,
- request_handle_);
- }
-
- if (session_callback_) {
- session_callback_->DropTransaction();
- session_callback_ = NULL; // Release() reference as side effect.
- }
- if (session_)
- session_->Release();
-}
-
-int HttpTransactionWinHttp::Start(const HttpRequestInfo* request_info,
- CompletionCallback* callback) {
- DCHECK(request_info);
- DCHECK(callback);
-
- // ensure that we only have one asynchronous call at a time.
- DCHECK(!callback_);
-
- LOG(INFO) << request_info->method << ": " << request_info->url;
-
- request_ = request_info;
- load_flags_ = request_info->load_flags;
-
- int rv = OK;
- if (!have_proxy_info_) {
- // Resolve proxy info.
- rv = session_->proxy_service()->ResolveProxy(request_->url,
- &proxy_info_,
- &proxy_callback_,
- &pac_request_);
- if (rv == ERR_IO_PENDING) {
- session_callback_->set_load_state(
- LOAD_STATE_RESOLVING_PROXY_FOR_URL);
- }
- }
-
- if (rv == OK)
- rv = DidResolveProxy(); // calls OpenRequest and SendRequest
-
- if (rv == ERR_IO_PENDING) {
- session_callback_->AddRef(); // balanced when callback runs or from
- // OnProxyInfoAvailable.
- callback_ = callback;
- }
-
- return rv;
-}
-
-int HttpTransactionWinHttp::RestartIgnoringLastError(
- CompletionCallback* callback) {
- int flags = load_flags_;
-
- // Depending on the error, we make different adjustments to our load flags.
- // We DCHECK that we shouldn't already have ignored this error.
- switch (last_error_) {
- case ERROR_WINHTTP_SECURE_CERT_CN_INVALID:
- DCHECK(!(flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID));
- flags |= LOAD_IGNORE_CERT_COMMON_NAME_INVALID;
- break;
- case ERROR_WINHTTP_SECURE_CERT_DATE_INVALID:
- DCHECK(!(flags & LOAD_IGNORE_CERT_DATE_INVALID));
- flags |= LOAD_IGNORE_CERT_DATE_INVALID;
- break;
- case ERROR_WINHTTP_SECURE_INVALID_CA:
- DCHECK(!(flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID));
- flags |= LOAD_IGNORE_CERT_AUTHORITY_INVALID;
- break;
- case ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE:
- DCHECK(!(flags & LOAD_IGNORE_CERT_WRONG_USAGE));
- flags |= LOAD_IGNORE_CERT_WRONG_USAGE;
- break;
- case ERROR_WINHTTP_SECURE_CERT_REV_FAILED: {
- DCHECK(!(flags & LOAD_IGNORE_CERT_REVOCATION));
- flags |= LOAD_IGNORE_CERT_REVOCATION;
- // WinHTTP doesn't have a SECURITY_FLAG_IGNORE_CERT_REV_FAILED flag
- // and doesn't let us undo WINHTTP_ENABLE_SSL_REVOCATION. The only
- // way to ignore this error is to open a new request without enabling
- // WINHTTP_ENABLE_SSL_REVOCATION.
- if (!ReopenRequest())
- return TranslateLastOSError();
- break;
- }
- // We can't instruct WinHttp to recover from these errors. No choice
- // but to cancel the request.
- case ERROR_WINHTTP_SECURE_CHANNEL_ERROR:
- case ERROR_WINHTTP_SECURE_INVALID_CERT:
- case ERROR_WINHTTP_SECURE_CERT_REVOKED:
- // We don't knows how to continue from here.
- default:
- LOG(ERROR) << "Unable to restart the HTTP transaction ignoring "
- "the error " << last_error_;
- return ERR_ABORTED;
- }
-
- // Update the load flags to ignore the specified error.
- load_flags_ = flags;
-
- return Restart(callback);
-}
-
-int HttpTransactionWinHttp::RestartWithAuth(
- const std::wstring& username,
- const std::wstring& password,
- CompletionCallback* callback) {
- DCHECK(proxy_auth_ && proxy_auth_->state == AUTH_STATE_NEED_AUTH ||
- server_auth_ && server_auth_->state == AUTH_STATE_NEED_AUTH);
-
- // Proxy gets set first, then WWW.
- AuthData* auth =
- proxy_auth_ && proxy_auth_->state == AUTH_STATE_NEED_AUTH ?
- proxy_auth_ : server_auth_;
-
- if (auth) {
- auth->state = AUTH_STATE_HAVE_AUTH;
- auth->username = username;
- auth->password = password;
- }
-
- return Restart(callback);
-}
-
-// The code common to RestartIgnoringLastError and RestartWithAuth.
-int HttpTransactionWinHttp::Restart(CompletionCallback* callback) {
- DCHECK(callback);
-
- // ensure that we only have one asynchronous call at a time.
- DCHECK(!callback_);
-
- int rv = RestartInternal();
- if (rv != ERR_IO_PENDING)
- return rv;
-
- session_callback_->AddRef(); // balanced when callback runs.
-
- callback_ = callback;
- return ERR_IO_PENDING;
-}
-
-// If HttpTransactionWinHttp needs to restart itself after handling an error,
-// it calls this method. This method leaves callback_ unchanged. The caller
-// is responsible for calling session_callback_->AddRef() if this method
-// returns ERR_IO_PENDING.
-int HttpTransactionWinHttp::RestartInternal() {
- content_length_remaining_ = -1;
- upload_progress_ = 0;
-
- return SendRequest();
-}
-
-// We use WinHttpQueryDataAvailable rather than pure async read to trade
-// a better latency for a decreased throughput. We'll make more IO calls,
-// and thus use more CPU for a given transaction by using
-// WinHttpQueryDataAvailable, but it allows us to get a faster response
-// time to the app for data, which is more important.
-int HttpTransactionWinHttp::Read(char* buf, int buf_len,
- CompletionCallback* callback) {
- DCHECK(buf);
- DCHECK(buf_len > 0);
- DCHECK(callback);
-
- DCHECK(!callback_);
- DCHECK(request_handle_);
-
- // If we have already received the full response, then we know we are done.
- if (content_length_remaining_ == 0) {
- LogTransactionMetrics();
- return 0;
- }
-
- session_callback_->set_read_buf(buf);
- session_callback_->set_read_buf_len(buf_len);
-
- // We must consume all the available data reported by the previous
- // WinHttpQueryDataAvailable call before we can call
- // WinHttpQueryDataAvailable again.
- BOOL ok;
- if (session_callback_->bytes_available()) {
- ok = session_callback_->ReadData(request_handle_);
- } else {
- ok = WinHttpQueryDataAvailable(request_handle_, NULL);
- }
- if (!ok)
- return TranslateLastOSError();
-
- session_callback_->set_load_state(LOAD_STATE_READING_RESPONSE);
- session_callback_->AddRef(); // balanced when callback runs.
- need_to_wait_for_handle_closing_ = true;
-
- callback_ = callback;
- return ERR_IO_PENDING;
-}
-
-const HttpResponseInfo* HttpTransactionWinHttp::GetResponseInfo() const {
- return (response_.headers || response_.ssl_info.cert) ? &response_ : NULL;
-}
-
-LoadState HttpTransactionWinHttp::GetLoadState() const {
- return session_callback_->load_state();
-}
-
-uint64 HttpTransactionWinHttp::GetUploadProgress() const {
- return upload_progress_;
-}
-
-void HttpTransactionWinHttp::DoCallback(int rv) {
- DCHECK(rv != ERR_IO_PENDING);
- DCHECK(callback_);
-
- // since Run may result in Read being called, clear callback_ up front.
- CompletionCallback* c = callback_;
- callback_ = NULL;
- c->Run(rv);
-}
-
-bool HttpTransactionWinHttp::OpenRequest() {
- DCHECK(!connect_handle_);
- DCHECK(!request_handle_);
-
- const GURL& url = request_->url;
- const std::string& scheme = url.scheme();
-
- // Flags passed to WinHttpOpenRequest. Disable any conversion WinHttp
- // might perform on our URL string. We handle the escaping ourselves.
- DWORD open_flags = WINHTTP_FLAG_ESCAPE_DISABLE |
- WINHTTP_FLAG_ESCAPE_DISABLE_QUERY |
- WINHTTP_FLAG_NULL_CODEPAGE;
-
- // We should only be dealing with HTTP at this point:
- DCHECK(LowerCaseEqualsASCII(scheme, "http") ||
- LowerCaseEqualsASCII(scheme, "https"));
-
- int in_port = url.IntPort();
- DCHECK(in_port != url_parse::PORT_INVALID) <<
- "Valid URLs should have valid ports";
-
- // Map to port numbers that Windows expects.
- INTERNET_PORT port = in_port;
- if (LowerCaseEqualsASCII(scheme, "https")) {
- is_https_ = true;
- open_flags |= WINHTTP_FLAG_SECURE;
- if (in_port == url_parse::PORT_UNSPECIFIED)
- port = INTERNET_DEFAULT_HTTPS_PORT;
- } else {
- if (in_port == url_parse::PORT_UNSPECIFIED)
- port = INTERNET_DEFAULT_HTTP_PORT;
- }
-
- const std::string& host = url.host();
-
- // Use the primary session handle unless we are talking to a TLS-intolerant
- // server.
- //
- // Since the SSL protocol versions enabled are an option of a session
- // handle, supporting TLS-intolerant servers unfortunately requires opening
- // an alternative session in which TLS 1.0 is disabled.
- if (!session_->internet() && !session_->Init(request_->user_agent)) {
- DLOG(ERROR) << "unable to create the internet";
- return false;
- }
- HINTERNET internet = session_->internet();
- if (is_tls_intolerant_) {
- if (!session_->internet_no_tls() &&
- !session_->InitNoTLS(request_->user_agent)) {
- DLOG(ERROR) << "unable to create the no-TLS alternative internet";
- return false;
- }
- internet = session_->internet_no_tls();
- }
-
- // This function operates synchronously.
- connect_handle_ =
- WinHttpConnect(internet, ASCIIToWide(host).c_str(), port, 0);
- if (!connect_handle_) {
- DLOG(ERROR) << "WinHttpConnect failed: " << GetLastError();
- return false;
- }
-
- std::string request_path = url.PathForRequest();
-
- // This function operates synchronously.
- request_handle_ =
- WinHttpOpenRequest(connect_handle_,
- ASCIIToWide(request_->method).c_str(),
- ASCIIToWide(request_path).c_str(),
- NULL, // use HTTP/1.1
- WINHTTP_NO_REFERER, // none
- WINHTTP_DEFAULT_ACCEPT_TYPES, // none
- open_flags);
- if (!request_handle_) {
- DLOG(ERROR) << "WinHttpOpenRequest failed: " << GetLastError();
- return false;
- }
-
- // TODO(darin): we may wish to prune-back the set of notifications we receive
- WINHTTP_STATUS_CALLBACK old_callback = WinHttpSetStatusCallback(
- request_handle_, StatusCallback,
- WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL);
- DCHECK(old_callback == NULL);
- if (old_callback == WINHTTP_INVALID_STATUS_CALLBACK) {
- DLOG(ERROR) << "WinHttpSetStatusCallback failed:" << GetLastError();
- return false;
- }
-
- DWORD_PTR ctx = reinterpret_cast<DWORD_PTR>(session_callback_.get());
- if (!WinHttpSetOption(request_handle_, WINHTTP_OPTION_CONTEXT_VALUE,
- &ctx, sizeof(ctx))) {
- DLOG(ERROR) << "WinHttpSetOption context value failed:" << GetLastError();
- return false;
- }
-
- // We just associated a status callback context value with the request
- // handle.
- session_callback_->AddRef(); // balanced in OnHandleClosing
- session_->AddRefBySessionCallback();
-
- // We have our own cookie and redirect management.
- DWORD options = WINHTTP_DISABLE_COOKIES |
- WINHTTP_DISABLE_REDIRECTS;
-
- if (!WinHttpSetOption(request_handle_, WINHTTP_OPTION_DISABLE_FEATURE,
- &options, sizeof(options))) {
- DLOG(ERROR) << "WinHttpSetOption disable feature failed:" << GetLastError();
- return false;
- }
-
- // Disable auto-login for Negotiate and NTLM auth methods.
- DWORD security_level = WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
- if (!WinHttpSetOption(request_handle_, WINHTTP_OPTION_AUTOLOGON_POLICY,
- &security_level, sizeof(security_level))) {
- DLOG(ERROR) << "WinHttpSetOption autologon failed: " << GetLastError();
- return false;
- }
-
- // Add request headers. WinHttp is known to convert the headers to bytes
- // using the system charset converter, so we use the same converter to map
- // our request headers to UTF-16 before handing the data to WinHttp.
- std::wstring request_headers = base::SysNativeMBToWide(GetRequestHeaders());
-
- DWORD len = static_cast<DWORD>(request_headers.size());
- if (!WinHttpAddRequestHeaders(request_handle_,
- request_headers.c_str(),
- len,
- WINHTTP_ADDREQ_FLAG_ADD |
- WINHTTP_ADDREQ_FLAG_REPLACE)) {
- DLOG(ERROR) << "WinHttpAddRequestHeaders failed: " << GetLastError();
- return false;
- }
-
- return true;
-}
-
-int HttpTransactionWinHttp::SendRequest() {
- DCHECK(request_handle_);
-
- // Apply any authentication (username/password) we might have.
- ApplyAuth();
-
- // Apply any proxy info.
- proxy_info_.Apply(request_handle_);
-
- // Check SSL server certificate revocation.
- if (is_https_) {
- bool ignore_cert_rev = (load_flags_ & LOAD_IGNORE_CERT_REVOCATION) != 0;
- GURL origin = request_->url.GetOrigin();
- const std::string& origin_spec = origin.spec();
- if (ignore_cert_rev)
- session_->IgnoreCertRev(origin_spec);
- else if (session_->ShouldIgnoreCertRev(origin_spec))
- ignore_cert_rev = true;
-
- if (session_->rev_checking_enabled() && !ignore_cert_rev) {
- DWORD options = WINHTTP_ENABLE_SSL_REVOCATION;
- if (!WinHttpSetOption(request_handle_, WINHTTP_OPTION_ENABLE_FEATURE,
- &options, sizeof(options))) {
- DLOG(ERROR) << "WinHttpSetOption failed: " << GetLastError();
- return TranslateLastOSError();
- }
- rev_checking_enabled_ = true;
- }
- }
-
- const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID |
- LOAD_IGNORE_CERT_DATE_INVALID |
- LOAD_IGNORE_CERT_AUTHORITY_INVALID |
- LOAD_IGNORE_CERT_WRONG_USAGE;
-
- if (load_flags_ & kCertFlags) {
- DWORD security_flags;
- DWORD length = sizeof(security_flags);
-
- if (!WinHttpQueryOption(request_handle_,
- WINHTTP_OPTION_SECURITY_FLAGS,
- &security_flags,
- &length)) {
- NOTREACHED() << "WinHttpQueryOption failed.";
- return TranslateLastOSError();
- }
-
- // On Vista, WinHttpSetOption() fails with an incorrect parameter error.
- // WinHttpQueryOption() sets an undocumented flag (0x01000000, which seems
- // to be a query-only flag) in security_flags that causes this error. To
- // work-around it, we only keep the documented error flags.
- security_flags &= (SECURITY_FLAG_IGNORE_UNKNOWN_CA |
- SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
- SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
- SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE);
-
- if (load_flags_ & LOAD_IGNORE_CERT_COMMON_NAME_INVALID)
- security_flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
-
- if (load_flags_ & LOAD_IGNORE_CERT_DATE_INVALID)
- security_flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
-
- if (load_flags_ & LOAD_IGNORE_CERT_AUTHORITY_INVALID)
- security_flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
-
- if (load_flags_ & LOAD_IGNORE_CERT_WRONG_USAGE)
- security_flags |= SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
-
- if (!WinHttpSetOption(request_handle_,
- WINHTTP_OPTION_SECURITY_FLAGS,
- &security_flags,
- sizeof(security_flags))) {
- NOTREACHED() << "WinHttpSetOption failed.";
- return TranslateLastOSError();
- }
- }
-
- response_.request_time = Time::Now();
- response_.was_cached = false;
-
- DWORD total_size = 0;
- if (request_->upload_data) {
- upload_stream_.reset(new UploadDataStream(request_->upload_data));
- uint64 upload_len = upload_stream_->size();
- if (upload_len == 0) {
- upload_stream_.reset();
- } else {
- // TODO(darin): no way to support >4GB uploads w/ WinHttp?
- if (upload_len > static_cast<uint64>(DWORD(-1))) {
- NOTREACHED() << "upload length is too large";
- return ERR_FILE_TOO_BIG;
- }
-
- total_size = static_cast<DWORD>(upload_len);
- }
- }
-
- if (request_submitted_) {
- request_submitted_ = false;
- session_->request_throttle()->NotifyRequestDone(connect_peer_);
- }
- if (proxy_info_.is_direct())
- connect_peer_ = request_->url.GetOrigin().spec();
- else
- connect_peer_ = proxy_info_.proxy_server();
- DWORD_PTR ctx = reinterpret_cast<DWORD_PTR>(session_callback_.get());
- if (!session_->request_throttle()->SubmitRequest(connect_peer_,
- request_handle_,
- total_size, ctx)) {
- last_error_ = GetLastError();
- DLOG(ERROR) << "WinHttpSendRequest failed: " << last_error_;
- return TranslateOSError(last_error_);
- }
-
- request_submitted_ = true;
- return ERR_IO_PENDING;
-}
-
-// Called after certain failures of SendRequest to reset the members opened
-// or modified in OpenRequest and SendRequest and call OpenRequest again.
-bool HttpTransactionWinHttp::ReopenRequest() {
- DCHECK(connect_handle_);
- DCHECK(request_handle_);
-
- session_callback_->set_handle_closing_event(
- session_->handle_closing_event());
- WinHttpCloseHandle(request_handle_);
- WaitForSingleObject(session_->handle_closing_event(), INFINITE);
- request_handle_ = NULL;
- WinHttpCloseHandle(connect_handle_);
- connect_handle_ = NULL;
- session_callback_->ResetForNewRequest();
-
- // Don't need to reset is_https_, rev_checking_enabled_, and
- // response_.request_time.
-
- return OpenRequest();
-}
-
-int HttpTransactionWinHttp::DidResolveProxy() {
- // We may already have a request handle if we are changing proxy config.
- if (!(request_handle_ ? ReopenRequest() : OpenRequest()))
- return TranslateLastOSError();
-
- return SendRequest();
-}
-
-int HttpTransactionWinHttp::DidReceiveError(DWORD error,
- DWORD secure_failure) {
- DCHECK(error != ERROR_SUCCESS);
-
- session_callback_->set_load_state(LOAD_STATE_IDLE);
- need_to_wait_for_handle_closing_ = false;
-
- int rv;
-
- if (error == ERROR_WINHTTP_RESEND_REQUEST)
- return RestartInternal();
-
- if (error == ERROR_WINHTTP_NAME_NOT_RESOLVED ||
- error == ERROR_WINHTTP_CANNOT_CONNECT ||
- error == ERROR_WINHTTP_TIMEOUT) {
- // These errors may have been caused by a proxy configuration error, or
- // rather they may go away by trying a different proxy config! If we have
- // an explicit proxy config, then we just have to report an error.
- if (!have_proxy_info_) {
- rv = session_->proxy_service()->ReconsiderProxyAfterError(
- request_->url, &proxy_info_, &proxy_callback_, &pac_request_);
- if (rv == OK) // got new proxy info to try
- return DidResolveProxy();
- if (rv == ERR_IO_PENDING) // waiting to resolve proxy info
- return rv;
- // else, fall through and just report an error.
- }
- }
-
- if (error == ERROR_WINHTTP_SECURE_FAILURE) {
- DWORD filtered_secure_failure = FilterSecureFailure(secure_failure,
- load_flags_);
- // If load_flags_ ignores all the errors in secure_failure, we shouldn't
- // get the ERROR_WINHTTP_SECURE_FAILURE error.
- DCHECK(filtered_secure_failure || !secure_failure);
- error = MapSecureFailureToError(filtered_secure_failure);
- }
-
- last_error_ = error;
- rv = TranslateOSError(error);
-
- if ((rv == ERR_SSL_PROTOCOL_ERROR ||
- rv == ERR_SSL_VERSION_OR_CIPHER_MISMATCH) &&
- !session_callback_->request_was_probably_sent() &&
- session_->tls_enabled() && !is_tls_intolerant_) {
- // The server might be TLS intolerant. Or it might be an SSL 3.0 server
- // that chose a TLS-only cipher suite, which we handle in the same way.
- // Downgrade to SSL 3.0 and retry.
- is_tls_intolerant_ = true;
- if (!ReopenRequest())
- return TranslateLastOSError();
- return RestartInternal();
- }
- if (rv == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
- // TODO(wtc): Bug 1230409: We don't support SSL client authentication yet.
- // For now we set a null client certificate, which works on XP SP3, Vista
- // and later. On XP SP2 and below, this fails with ERROR_INVALID_PARAMETER
- // (87). This allows us to access servers that request but do not require
- // client certificates.
- if (WinHttpSetOption(request_handle_,
- WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
- WINHTTP_NO_CLIENT_CERT_CONTEXT, 0))
- return RestartInternal();
- }
- if (IsCertificateError(rv)) {
- response_.ssl_info.cert = GetServerCertificate();
- response_.ssl_info.cert_status =
- MapSecureFailureToCertStatus(secure_failure);
- CertStatusCache* cert_status_cache = session_->cert_status_cache();
- cert_status_cache->SetCertStatus(*response_.ssl_info.cert,
- request_->url.host(),
- response_.ssl_info.cert_status);
- }
-
- return rv;
-}
-
-int HttpTransactionWinHttp::DidSendRequest() {
- BOOL ok;
- if (upload_stream_.get() && upload_stream_->buf_len() > 0) {
- // write upload data
- DWORD buf_len = static_cast<DWORD>(upload_stream_->buf_len());
- ok = WinHttpWriteData(request_handle_,
- upload_stream_->buf(),
- buf_len,
- NULL);
- if (ok)
- need_to_wait_for_handle_closing_ = true;
- } else {
- upload_stream_.reset();
- need_to_wait_for_handle_closing_ = false;
-
- // begin receiving the response
- ok = WinHttpReceiveResponse(request_handle_, NULL);
- }
- return ok ? ERR_IO_PENDING : TranslateLastOSError();
-}
-
-int HttpTransactionWinHttp::DidWriteData(DWORD num_bytes) {
- DCHECK(upload_stream_.get());
- DCHECK(num_bytes > 0);
-
- upload_stream_->DidConsume(num_bytes);
- upload_progress_ = upload_stream_->position();
-
- // OK, we are ready to start receiving the response. The code in
- // DidSendRequest does exactly what we want!
- return DidSendRequest();
-}
-
-int HttpTransactionWinHttp::DidReadData(DWORD num_bytes) {
- int rv = static_cast<int>(num_bytes);
- DCHECK(rv >= 0);
-
- session_callback_->set_load_state(LOAD_STATE_IDLE);
- session_callback_->reduce_bytes_available(rv);
- need_to_wait_for_handle_closing_ = false;
-
- if (content_length_remaining_ > 0) {
- content_length_remaining_ -= rv;
-
- // HTTP/1.0 servers are known to send more data than they report in their
- // Content-Length header (in the non-keepalive case). IE and Moz both
- // tolerate this situation, and therefore so must we.
- if (content_length_remaining_ < 0)
- content_length_remaining_ = 0;
- }
-
- // We have read the entire response. Mark the request done to unblock a
- // queued request.
- if (rv == 0) {
- LogTransactionMetrics();
- DCHECK(request_submitted_);
- request_submitted_ = false;
- session_->request_throttle()->NotifyRequestDone(connect_peer_);
- }
-
- return rv;
-}
-
-void HttpTransactionWinHttp::LogTransactionMetrics() const {
- base::TimeDelta duration = base::Time::Now() - response_.request_time;
- if (60 < duration.InMinutes())
- return;
- UMA_HISTOGRAM_LONG_TIMES(L"Net.Transaction_Latency_WinHTTP", duration);
-}
-
-int HttpTransactionWinHttp::DidReceiveHeaders() {
- session_callback_->set_load_state(LOAD_STATE_IDLE);
-
- DWORD size = 0;
- if (!WinHttpQueryHeaders(request_handle_,
- WINHTTP_QUERY_RAW_HEADERS,
- WINHTTP_HEADER_NAME_BY_INDEX,
- NULL,
- &size,
- WINHTTP_NO_HEADER_INDEX)) {
- DWORD error = GetLastError();
- if (error != ERROR_INSUFFICIENT_BUFFER) {
- DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();
- return TranslateLastOSError();
- }
- // OK, size should tell us how much to allocate...
- DCHECK(size > 0);
- }
-
- std::wstring raw_headers;
-
- // 'size' is the number of bytes rather than the number of characters.
- DCHECK(size % 2 == 0);
- if (!WinHttpQueryHeaders(request_handle_,
- WINHTTP_QUERY_RAW_HEADERS,
- WINHTTP_HEADER_NAME_BY_INDEX,
- WriteInto(&raw_headers, size/2 + 1),
- &size,
- WINHTTP_NO_HEADER_INDEX)) {
- DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();
- return TranslateLastOSError();
- }
-
- response_.response_time = Time::Now();
-
- // From experimentation, it appears that WinHttp translates non-ASCII bytes
- // found in the response headers to UTF-16 assuming that they are encoded
- // using the default system charset. We attempt to undo that here.
- response_.headers =
- new HttpResponseHeaders(base::SysWideToNativeMB(raw_headers));
-
- // WinHTTP truncates a response longer than 2GB. Perhaps it stores the
- // response's content length in a signed 32-bit integer. We fail rather
- // than reading a truncated response.
- if (response_.headers->GetContentLength() > 0x80000000)
- return ERR_FILE_TOO_BIG;
-
- response_.vary_data.Init(*request_, *response_.headers);
- int rv = PopulateAuthChallenge();
- if (rv != OK)
- return rv;
-
- // Unfortunately, WinHttp does not close the connection when a non-keepalive
- // response is _not_ followed by the server closing the connection. So, we
- // attempt to hack around this bug.
- if (!response_.headers->IsKeepAlive())
- content_length_remaining_ = response_.headers->GetContentLength();
-
- return OK;
-}
-
-// Populates response_.auth_challenge with the authentication challenge info.
-int HttpTransactionWinHttp::PopulateAuthChallenge() {
- DCHECK(response_.headers);
-
- int status = response_.headers->response_code();
- if (status != 401 && status != 407)
- return OK;
-
- scoped_refptr<AuthChallengeInfo> auth_info = new AuthChallengeInfo;
-
- auth_info->is_proxy = (status == 407);
-
- if (auth_info->is_proxy) {
- // TODO(wtc): get the proxy server host from proxy_info_.
- // TODO(wtc): internationalize?
- auth_info->host = L"proxy";
- } else {
- auth_info->host = ASCIIToWide(request_->url.host());
- }
-
- // Here we're checking only the first *-Authenticate header. When a server
- // responds with multiple methods, we use the first.
- // TODO(wtc): Bug 1124614: look at all the authentication methods and pick
- // the best one that we support. failover to other authentication methods.
- std::string header_value;
- std::string header_name = auth_info->is_proxy ?
- "Proxy-Authenticate" : "WWW-Authenticate";
- if (!response_.headers->EnumerateHeader(NULL, header_name, &header_value))
- return OK;
-
- // TODO(darin): Need to support RFC 2047 encoded realm strings. For now, we
- // limit our support to ASCII and "native code page" realm strings.
- std::wstring auth_header = base::SysNativeMBToWide(header_value);
-
- // auth_header is a string which looks like:
- // Digest realm="The Awesome Site", domain="/page.html", ...
- std::wstring::const_iterator space = find(auth_header.begin(),
- auth_header.end(), L' ');
- auth_info->scheme.assign(auth_header.begin(), space);
- auth_info->realm = GetHeaderParamValue(auth_header, L"realm");
-
- // Now auth_info has been fully populated. Before we swap it with
- // response_.auth_challenge, update the auth cache key and remove any
- // presumably incorrect auth data in the auth cache.
- std::string* auth_cache_key;
- AuthData* auth;
- if (auth_info->is_proxy) {
- if (!proxy_auth_)
- proxy_auth_ = new AuthData;
- auth = proxy_auth_;
- auth_cache_key = &proxy_auth_cache_key_;
- } else {
- if (!server_auth_)
- server_auth_ = new AuthData;
- auth = server_auth_;
- auth_cache_key = &server_auth_cache_key_;
- }
- *auth_cache_key = AuthCache::HttpKey(request_->url, *auth_info);
- DCHECK(!auth_cache_key->empty());
- auth->scheme = auth_info->scheme;
- if (auth->state == AUTH_STATE_HAVE_AUTH) {
- // Remove the cache entry for the credentials we just failed on.
- // Note: we require the username/password to match before removing
- // since the entry in the cache may be newer than what we used last time.
- AuthData* cached_auth = session_->auth_cache()->Lookup(*auth_cache_key);
- if (cached_auth && cached_auth->username == auth->username &&
- cached_auth->password == auth->password)
- session_->auth_cache()->Remove(*auth_cache_key);
- auth->state = AUTH_STATE_NEED_AUTH;
- }
- DCHECK(auth->state == AUTH_STATE_NEED_AUTH);
-
- // Try to use the username/password embedded in the URL first.
- // (By checking !used_embedded_credentials_, we make sure that this
- // is only done once for the transaction.)
- if (!auth_info->is_proxy && request_->url.has_username() &&
- !used_embedded_credentials_) {
- // TODO(wtc) It may be necessary to unescape the username and password
- // after extracting them from the URL. We should be careful about
- // embedded nulls in that case.
- used_embedded_credentials_ = true;
- auth->state = AUTH_STATE_HAVE_AUTH;
- auth->username = ASCIIToWide(request_->url.username());
- auth->password = ASCIIToWide(request_->url.password());
- return RestartInternal();
- }
-
- // Check the auth cache for an entry.
- AuthData* cached_auth = session_->auth_cache()->Lookup(*auth_cache_key);
- if (cached_auth) {
- auth->state = AUTH_STATE_HAVE_AUTH;
- auth->username = cached_auth->username;
- auth->password = cached_auth->password;
- return RestartInternal();
- }
-
- response_.auth_challenge.swap(auth_info);
- return OK;
-}
-
-static DWORD StringToAuthScheme(const std::wstring& scheme) {
- if (LowerCaseEqualsASCII(scheme, "basic"))
- return WINHTTP_AUTH_SCHEME_BASIC;
- if (LowerCaseEqualsASCII(scheme, "digest"))
- return WINHTTP_AUTH_SCHEME_DIGEST;
- if (LowerCaseEqualsASCII(scheme, "ntlm"))
- return WINHTTP_AUTH_SCHEME_NTLM;
- if (LowerCaseEqualsASCII(scheme, "negotiate"))
- return WINHTTP_AUTH_SCHEME_NEGOTIATE;
- if (LowerCaseEqualsASCII(scheme, "passport1.4"))
- return WINHTTP_AUTH_SCHEME_PASSPORT;
- return 0;
-}
-
-// Applies authentication credentials to request_handle_.
-void HttpTransactionWinHttp::ApplyAuth() {
- DWORD auth_scheme;
- BOOL rv;
- if (proxy_auth_ && proxy_auth_->state == AUTH_STATE_HAVE_AUTH) {
- // Add auth data to cache.
- DCHECK(!proxy_auth_cache_key_.empty());
- session_->auth_cache()->Add(proxy_auth_cache_key_, proxy_auth_);
- auth_scheme = StringToAuthScheme(proxy_auth_->scheme);
- if (auth_scheme == 0)
- return;
-
- rv = WinHttpSetCredentials(request_handle_,
- WINHTTP_AUTH_TARGET_PROXY,
- auth_scheme,
- proxy_auth_->username.c_str(),
- proxy_auth_->password.c_str(),
- NULL);
- }
-
- if (server_auth_ && server_auth_->state == AUTH_STATE_HAVE_AUTH) {
- // Add auth data to cache.
- DCHECK(!server_auth_cache_key_.empty());
- session_->auth_cache()->Add(server_auth_cache_key_, server_auth_);
- auth_scheme = StringToAuthScheme(server_auth_->scheme);
- if (auth_scheme == 0)
- return;
-
- rv = WinHttpSetCredentials(request_handle_,
- WINHTTP_AUTH_TARGET_SERVER,
- auth_scheme,
- server_auth_->username.c_str(),
- server_auth_->password.c_str(),
- NULL);
- }
-}
-
-void HttpTransactionWinHttp::OnProxyInfoAvailable(int result) {
- if (result != OK) {
- DLOG(WARNING) << "failed to get proxy info: " << result;
- proxy_info_.UseDirect();
- }
-
- // Balances extra reference taken when proxy resolution was initiated.
- session_callback_->Release();
-
- pac_request_ = NULL;
-
- // Since OnProxyInfoAvailable is always called asynchronously (via the
- // message loop), we need to trap any errors and pass them to the consumer
- // via their completion callback.
-
- int rv = DidResolveProxy();
- if (rv == ERR_IO_PENDING) {
- session_callback_->AddRef(); // balanced when callback runs.
- } else {
- DoCallback(rv);
- }
-}
-
-std::string HttpTransactionWinHttp::GetRequestHeaders() const {
- std::string headers;
-
- if (!request_->user_agent.empty())
- headers += "User-Agent: " + request_->user_agent + "\r\n";
-
- // Our consumer should have made sure that this is a safe referrer. See for
- // instance WebCore::FrameLoader::HideReferrer.
- if (request_->referrer.is_valid())
- headers += "Referer: " + request_->referrer.spec() + "\r\n";
-
- // IE and Safari do this. Presumably it is to support sending a HEAD request
- // to an URL that only expects to be sent a POST or some other method that
- // normally would have a message body.
- if (request_->method == "HEAD")
- headers += "Content-Length: 0\r\n";
-
- // Honor load flags that impact proxy caches.
- if (request_->load_flags & LOAD_BYPASS_CACHE) {
- headers += "Pragma: no-cache\r\nCache-Control: no-cache\r\n";
- } else if (request_->load_flags & LOAD_VALIDATE_CACHE) {
- headers += "Cache-Control: max-age=0\r\n";
- }
-
- // TODO(darin): Prune out duplicate headers?
- headers += request_->extra_headers;
-
- return headers;
-}
-
-// Retrieves the SSL server certificate associated with the transaction.
-// The caller is responsible for freeing the certificate.
-X509Certificate* HttpTransactionWinHttp::GetServerCertificate() const {
- DCHECK(is_https_);
- PCCERT_CONTEXT cert_context = NULL;
- DWORD length = sizeof(cert_context);
- if (!WinHttpQueryOption(request_handle_,
- WINHTTP_OPTION_SERVER_CERT_CONTEXT,
- &cert_context,
- &length)) {
- return NULL;
- }
- // cert_context may be NULL here even though WinHttpQueryOption succeeded.
- // For example, a proxy server may return a 404 error page to report the
- // DNS resolution failure of the server's hostname.
- if (!cert_context)
- return NULL;
- return X509Certificate::CreateFromHandle(cert_context);
-}
-
-// Retrieves the security strength, in bits, of the SSL cipher suite
-// associated with the transaction.
-int HttpTransactionWinHttp::GetSecurityBits() const {
- DCHECK(is_https_);
- DWORD key_bits = 0;
- DWORD length = sizeof(key_bits);
- if (!WinHttpQueryOption(request_handle_,
- WINHTTP_OPTION_SECURITY_KEY_BITNESS,
- &key_bits,
- &length)) {
- return -1;
- }
- return key_bits;
-}
-
-void HttpTransactionWinHttp::PopulateSSLInfo(DWORD secure_failure) {
- if (is_https_) {
- response_.ssl_info.cert = GetServerCertificate();
- response_.ssl_info.security_bits = GetSecurityBits();
- // If there is no cert (such as when the proxy server makes up a
- // 404 response to report a server name resolution error), don't set
- // the cert status.
- if (!response_.ssl_info.cert)
- return;
- response_.ssl_info.cert_status =
- MapSecureFailureToCertStatus(secure_failure);
- // WinHTTP does not always return a cert status once we ignored errors
- // for a cert. (Our experiments showed that WinHTTP reliably returns a
- // cert status only when there are unignored errors or when we resend a
- // request with the errors ignored.) So we have to remember what the
- // last status was for a cert. Note that if the cert status changes
- // from error to OK, we won't know that. If we have never stored our
- // status in the CertStatusCache (meaning no errors so far), then it is
- // OK (0).
- CertStatusCache* cert_status_cache = session_->cert_status_cache();
- if (net::IsCertStatusError(response_.ssl_info.cert_status)) {
- cert_status_cache->SetCertStatus(*response_.ssl_info.cert,
- request_->url.host(),
- response_.ssl_info.cert_status);
- } else {
- response_.ssl_info.cert_status |=
- cert_status_cache->GetCertStatus(*response_.ssl_info.cert,
- request_->url.host()) &
- net::CERT_STATUS_ALL_ERRORS;
- }
-
- if (rev_checking_enabled_)
- response_.ssl_info.cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
- } else {
- // If this is not https, we should not get a cert status.
- DCHECK(!secure_failure);
- }
-}
-
-void HttpTransactionWinHttp::HandleStatusCallback(DWORD status,
- DWORD_PTR result,
- DWORD error,
- DWORD secure_failure) {
- int rv;
-
- switch (status) {
- case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR:
- rv = DidReceiveError(error, secure_failure);
- break;
- case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
- PopulateSSLInfo(secure_failure);
- rv = DidSendRequest();
- break;
- case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE:
- rv = DidWriteData(static_cast<DWORD>(result));
- break;
- case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
- rv = DidReceiveHeaders();
- break;
- case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
- rv = DidReadData(static_cast<DWORD>(result));
- break;
- default:
- NOTREACHED() << "unexpected status code";
- rv = ERR_UNEXPECTED;
- break;
- }
-
- if (rv == ERR_IO_PENDING) {
- session_callback_->AddRef(); // balanced when callback runs.
- } else if (callback_) {
- DoCallback(rv);
- }
-}
-
-} // namespace net
-
diff --git a/net/http/http_transaction_winhttp.h b/net/http/http_transaction_winhttp.h
deleted file mode 100644
index 27ad730..0000000
--- a/net/http/http_transaction_winhttp.h
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_HTTP_HTTP_TRANSACTION_WINHTTP_H__
-#define NET_HTTP_HTTP_TRANSACTION_WINHTTP_H__
-
-#include <windows.h>
-#include <winhttp.h>
-
-#include <string>
-
-#include "base/ref_counted.h"
-#include "net/base/completion_callback.h"
-#include "net/http/http_response_info.h"
-#include "net/http/http_transaction.h"
-#include "net/http/http_transaction_factory.h"
-#include "net/proxy/proxy_service.h"
-
-namespace net {
-
-class UploadDataStream;
-
-class HttpTransactionWinHttp : public HttpTransaction {
- class Session; // Represents a WinHttp session handle.
- class SessionCallback;
- public:
- // Instantiate this class, and use it to create HttpTransaction objects.
- class Factory : public HttpTransactionFactory {
- public:
- explicit Factory(ProxyService* proxy_service)
- : session_(NULL), proxy_service_(proxy_service), is_suspended_(false) {
- DCHECK(proxy_service);
- }
- ~Factory();
-
- virtual HttpTransaction* CreateTransaction();
- virtual HttpCache* GetCache();
- virtual void Suspend(bool suspend);
-
- private:
- Session* session_;
- ProxyService* proxy_service_;
- bool is_suspended_;
- DISALLOW_EVIL_CONSTRUCTORS(Factory);
- };
-
- virtual ~HttpTransactionWinHttp();
-
- // HttpTransaction methods:
- virtual int Start(const HttpRequestInfo*, CompletionCallback*);
- virtual int RestartIgnoringLastError(CompletionCallback*);
- virtual int RestartWithAuth(const std::wstring&,
- const std::wstring&,
- CompletionCallback*);
- virtual int Read(char*, int, CompletionCallback*);
- virtual const HttpResponseInfo* GetResponseInfo() const;
- virtual LoadState GetLoadState() const;
- virtual uint64 GetUploadProgress() const;
-
- static void CALLBACK StatusCallback(HINTERNET handle,
- DWORD_PTR context,
- DWORD status,
- LPVOID status_info,
- DWORD status_info_len);
-
- // Called via the message loop in response to a WinHttp status callback.
- void HandleStatusCallback(DWORD status,
- DWORD_PTR result,
- DWORD error,
- DWORD secure_failure);
-
- private:
- friend class Factory;
-
- // Methods ------------------------------------------------------------------
-
- HttpTransactionWinHttp(Session* session, const ProxyInfo* info);
-
- void DoCallback(int rv);
- int ResolveProxy();
- bool OpenRequest();
- int SendRequest();
- bool ReopenRequest();
- int Restart(CompletionCallback* callback);
- int RestartInternal();
- int DidResolveProxy();
- int DidReceiveError(DWORD error, DWORD secure_failure);
- int DidSendRequest();
- int DidWriteData(DWORD num_bytes);
- int DidReadData(DWORD num_bytes);
- void LogTransactionMetrics() const;
- int DidReceiveHeaders();
-
- int PopulateAuthChallenge();
- void ApplyAuth();
-
- std::string GetRequestHeaders() const;
- X509Certificate* GetServerCertificate() const;
- int GetSecurityBits() const;
- void PopulateSSLInfo(DWORD secure_failure);
-
- void OnProxyInfoAvailable(int result);
-
- // Variables ----------------------------------------------------------------
-
- Session* session_;
- const HttpRequestInfo* request_;
-
- // A copy of request_->load_flags that we can modify in
- // RestartIgnoringLastError.
- int load_flags_;
-
- // Optional auth data for proxy and origin server.
- scoped_refptr<AuthData> proxy_auth_;
- scoped_refptr<AuthData> server_auth_;
-
- // The key for looking up the auth data in the auth cache, consisting
- // of the scheme, host, and port of the request URL and the realm in
- // the auth challenge.
- std::string proxy_auth_cache_key_;
- std::string server_auth_cache_key_;
-
- // The peer of the connection. For a direct connection, this is the
- // destination server. If we use a proxy, this is the proxy.
- std::string connect_peer_;
-
- // The last error from SendRequest that occurred. Used by
- // RestartIgnoringLastError to adjust load_flags_ to ignore this error.
- DWORD last_error_;
-
- // This value is non-negative when we are streaming a response over a
- // non-keepalive connection. We decrement this value as we receive data to
- // allow us to discover end-of-file. This is used to workaround a bug in
- // WinHttp (see bug 1063336).
- int64 content_length_remaining_;
-
- ProxyInfo proxy_info_;
- ProxyService::PacRequest* pac_request_;
- CompletionCallbackImpl<HttpTransactionWinHttp> proxy_callback_;
-
- HttpResponseInfo response_;
- CompletionCallback* callback_;
- HINTERNET connect_handle_;
- HINTERNET request_handle_;
- scoped_refptr<SessionCallback> session_callback_;
- scoped_ptr<UploadDataStream> upload_stream_;
- uint64 upload_progress_;
-
- // True if the URL's scheme is https.
- bool is_https_;
-
- // True if the SSL server doesn't support TLS but also cannot correctly
- // negotiate with a TLS-enabled client to use SSL 3.0. The workaround is
- // for the client to downgrade to SSL 3.0 and retry the SSL handshake.
- bool is_tls_intolerant_;
-
- // True if revocation checking of the SSL server certificate is enabled.
- bool rev_checking_enabled_;
-
- // A flag to indicate whether or not we already have proxy information.
- // If false, we will attempt to resolve proxy information from the proxy
- // service. This flag is set to true if proxy information is supplied by
- // a client.
- bool have_proxy_info_;
-
- // If WinHTTP is still using our caller's data (upload data or read buffer),
- // we need to wait for the HANDLE_CLOSING status notification after we close
- // the request handle.
- //
- // There are only five WinHTTP functions that work asynchronously (listed in
- // the order in which they're called):
- // WinHttpSendRequest, WinHttpWriteData, WinHttpReceiveResponse,
- // WinHttpQueryDataAvailable, WinHttpReadData.
- // WinHTTP is using our caller's data during the two time intervals:
- // - From the first WinHttpWriteData call to the completion of the last
- // WinHttpWriteData call. (We may call WinHttpWriteData multiple times.)
- // - From the WinHttpReadData call to its completion.
- // We set need_to_wait_for_handle_closing_ to true at the beginning of these
- // time intervals and set it to false at the end. We're not sandwiching the
- // intervals as tightly as possible. (To do that, we'd need to give WinHTTP
- // worker threads access to the need_to_wait_for_handle_closing_ flag and
- // worry about thread synchronization issues.)
- bool need_to_wait_for_handle_closing_;
-
- // True if we have called WinHttpRequestThrottle::SubmitRequest but haven't
- // called WinHttpRequestThrottle::NotifyRequestDone.
- bool request_submitted_;
-
- // True if we have used the username/password embedded in the URL.
- bool used_embedded_credentials_;
-
- DISALLOW_EVIL_CONSTRUCTORS(HttpTransactionWinHttp);
-};
-
-} // namespace net
-
-#endif // NET_HTTP_HTTP_TRANSACTION_WINHTTP_H__
-
diff --git a/net/http/http_transaction_winhttp_unittest.cc b/net/http/http_transaction_winhttp_unittest.cc
deleted file mode 100644
index e24c8d8..0000000
--- a/net/http/http_transaction_winhttp_unittest.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/http_transaction_winhttp.h"
-#include "net/http/http_transaction_unittest.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(HttpTransactionWinHttp, CreateAndDestroy) {
- scoped_ptr<net::ProxyService> proxy_service(net::ProxyService::CreateNull());
- net::HttpTransactionWinHttp::Factory factory(proxy_service.get());
-
- scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
-}
-
-TEST(HttpTransactionWinHttp, Suspend) {
- scoped_ptr<net::ProxyService> proxy_service(net::ProxyService::CreateNull());
- net::HttpTransactionWinHttp::Factory factory(proxy_service.get());
-
- scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
- trans.reset();
-
- factory.Suspend(true);
-
- trans.reset(factory.CreateTransaction());
- ASSERT_TRUE(trans == NULL);
-
- factory.Suspend(false);
-
- trans.reset(factory.CreateTransaction());
-}
-
-TEST(HttpTransactionWinHttp, GoogleGET) {
- scoped_ptr<net::ProxyService> proxy_service(net::ProxyService::CreateNull());
- net::HttpTransactionWinHttp::Factory factory(proxy_service.get());
- TestCompletionCallback callback;
-
- scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
-
- net::HttpRequestInfo request_info;
- request_info.url = GURL("http://www.google.com/");
- request_info.method = "GET";
- request_info.user_agent = "Foo/1.0";
- request_info.load_flags = net::LOAD_NORMAL;
-
- int rv = trans->Start(&request_info, &callback);
- if (rv == net::ERR_IO_PENDING)
- rv = callback.WaitForResult();
- EXPECT_EQ(net::OK, rv);
-
- std::string contents;
- rv = ReadTransaction(trans.get(), &contents);
- EXPECT_EQ(net::OK, rv);
-}
-
diff --git a/net/http/winhttp_request_throttle.cc b/net/http/winhttp_request_throttle.cc
deleted file mode 100644
index 79415b3..0000000
--- a/net/http/winhttp_request_throttle.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/winhttp_request_throttle.h"
-
-#include "base/logging.h"
-#include "net/http/http_transaction_winhttp.h"
-
-namespace {
-
-// The arguments to a WinHttpSendRequest call.
-struct SendRequestArgs {
- SendRequestArgs() : request_handle(NULL), total_size(0), context(0) {}
-
- SendRequestArgs(HINTERNET handle, DWORD size, DWORD_PTR context_value)
- : request_handle(handle), total_size(size), context(context_value) {}
-
- HINTERNET request_handle;
- DWORD total_size;
- DWORD_PTR context;
-};
-
-} // namespace
-
-namespace net {
-
-// Per-server queue for WinHttpSendRequest calls.
-class WinHttpRequestThrottle::RequestQueue {
- public:
- RequestQueue() {}
-
- // Adds |args| to the end of the queue.
- void PushBack(const SendRequestArgs& args) { queue_.push_back(args); }
-
- // If the queue is not empty, pops the first entry off the queue, saves it
- // in |*args|, and returns true. If the queue is empty, returns false.
- bool GetFront(SendRequestArgs* args);
-
- // If the queue has an entry containing |request_handle|, removes it and
- // returns true. Otherwise, returns false.
- bool Remove(HINTERNET request_handle);
-
- bool empty() const { return queue_.empty(); }
-
- private:
- std::list<SendRequestArgs> queue_;
-
- DISALLOW_EVIL_CONSTRUCTORS(RequestQueue);
-};
-
-bool WinHttpRequestThrottle::RequestQueue::GetFront(SendRequestArgs* args) {
- if (queue_.empty())
- return false;
- *args = queue_.front();
- queue_.pop_front();
- return true;
-}
-
-bool WinHttpRequestThrottle::RequestQueue::Remove(HINTERNET request_handle) {
- std::list<SendRequestArgs>::iterator it;
- for (it = queue_.begin(); it != queue_.end(); ++it) {
- if (it->request_handle == request_handle) {
- queue_.erase(it);
- return true;
- }
- }
- return false;
-}
-
-WinHttpRequestThrottle::~WinHttpRequestThrottle() {
-#ifndef NDEBUG
- ThrottleMap::const_iterator throttle_iter = throttles_.begin();
- for (; throttle_iter != throttles_.end(); ++throttle_iter) {
- const PerServerThrottle& throttle = throttle_iter->second;
- DCHECK(throttle.num_requests == 0);
- DCHECK(!throttle.request_queue.get() || throttle.request_queue->empty());
- }
-#endif
-}
-
-BOOL WinHttpRequestThrottle::SubmitRequest(const std::string &server,
- HINTERNET request_handle,
- DWORD total_size,
- DWORD_PTR context) {
- PerServerThrottle& throttle = throttles_[server];
- DCHECK(throttle.num_requests >= 0 &&
- throttle.num_requests <= kMaxConnectionsPerServer);
- if (throttle.num_requests >= kMaxConnectionsPerServer) {
- if (!throttle.request_queue.get())
- throttle.request_queue.reset(new RequestQueue);
- SendRequestArgs args(request_handle, total_size, context);
- throttle.request_queue->PushBack(args);
- return TRUE;
- }
-
- BOOL ok = SendRequest(request_handle, total_size, context, false);
- if (ok)
- throttle.num_requests += 1;
- return ok;
-}
-
-void WinHttpRequestThrottle::NotifyRequestDone(const std::string& server) {
- PerServerThrottle& throttle = throttles_[server];
- DCHECK(throttle.num_requests > 0 &&
- throttle.num_requests <= kMaxConnectionsPerServer);
- throttle.num_requests -= 1;
- SendRequestArgs args;
- if (throttle.request_queue.get() &&
- throttle.request_queue->GetFront(&args)) {
- throttle.num_requests += 1;
- SendRequest(args.request_handle, args.total_size, args.context, true);
- }
- if (throttles_.size() > static_cast<size_t>(kGarbageCollectionThreshold))
- GarbageCollect();
-}
-
-void WinHttpRequestThrottle::RemoveRequest(const std::string& server,
- HINTERNET request_handle) {
- PerServerThrottle& throttle = throttles_[server];
- if (throttle.request_queue.get() &&
- throttle.request_queue->Remove(request_handle))
- return;
- NotifyRequestDone(server);
-}
-
-BOOL WinHttpRequestThrottle::SendRequest(HINTERNET request_handle,
- DWORD total_size,
- DWORD_PTR context,
- bool report_async_error) {
- BOOL ok = WinHttpSendRequest(request_handle,
- WINHTTP_NO_ADDITIONAL_HEADERS,
- 0,
- WINHTTP_NO_REQUEST_DATA,
- 0,
- total_size,
- context);
- if (!ok && report_async_error) {
- WINHTTP_ASYNC_RESULT async_result = { API_SEND_REQUEST, GetLastError() };
- HttpTransactionWinHttp::StatusCallback(
- request_handle, context,
- WINHTTP_CALLBACK_STATUS_REQUEST_ERROR,
- &async_result, sizeof(async_result));
- }
- return ok;
-}
-
-WinHttpRequestThrottle::PerServerThrottle::PerServerThrottle()
- : num_requests(0) {
-}
-
-WinHttpRequestThrottle::PerServerThrottle::~PerServerThrottle() {
-}
-
-// static
-const int WinHttpRequestThrottle::kMaxConnectionsPerServer = 6;
-
-// static
-const int WinHttpRequestThrottle::kGarbageCollectionThreshold = 64;
-
-void WinHttpRequestThrottle::GarbageCollect() {
- ThrottleMap::iterator throttle_iter = throttles_.begin();
- while (throttle_iter != throttles_.end()) {
- PerServerThrottle& throttle = throttle_iter->second;
- if (throttle.num_requests == 0 &&
- (!throttle.request_queue.get() || throttle.request_queue->empty())) {
- // Erase the current item but keep the iterator valid.
- throttles_.erase(throttle_iter++);
- } else {
- ++throttle_iter;
- }
- }
-}
-
-} // namespace net
-
diff --git a/net/http/winhttp_request_throttle.h b/net/http/winhttp_request_throttle.h
deleted file mode 100644
index fc20c11..0000000
--- a/net/http/winhttp_request_throttle.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_HTTP_WINHTTP_REQUEST_THROTTLE_H_
-#define NET_HTTP_WINHTTP_REQUEST_THROTTLE_H_
-
-#include <windows.h>
-#include <winhttp.h>
-
-#include <map>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/linked_ptr.h"
-#include "testing/gtest/include/gtest/gtest_prod.h"
-
-namespace net {
-
-// The WinHttpRequestThrottle class regulates the rate at which we call
-// WinHttpSendRequest, ensuring that at any time there are at most 6 WinHTTP
-// requests in progress for each server or proxy.
-//
-// The throttling is intended to cause WinHTTP to maintain at most 6
-// persistent HTTP connections with each server or proxy. This works well in
-// most cases, except when making HTTPS requests via a proxy, in which case
-// WinHTTP may open much more than 6 connections to the proxy in spite of our
-// rate limiting.
-//
-// Because we identify a server by its hostname rather than its IP address,
-// we also can't distinguish between two different hostnames that resolve to
-// the same IP address.
-//
-// Although WinHTTP has the WINHTTP_OPTION_MAX_CONNS_PER_SERVER option to
-// limit the number of connections allowed per server, we can't use it
-// because it has two serious bugs:
-// 1. It causes WinHTTP to not close idle persistent connections, leaving
-// many connections in the CLOSE_WAIT state. This may cause system
-// crashes (Blue Screen of Death) when VPN is used.
-// 2. It causes WinHTTP to crash intermittently in
-// HTTP_REQUEST_HANDLE_OBJECT::OpenProxyTunnel_Fsm() if a proxy is used.
-// Therefore, we have to resort to throttling our WinHTTP requests to achieve
-// the same effect.
-//
-// Note on thread safety: The WinHttpRequestThrottle class is only used by
-// the IO thread, so it doesn't need to be protected with a lock. The
-// drawback is that the time we mark a request done is only approximate.
-// We do that in the HttpTransactionWinHttp destructor, rather than in the
-// WinHTTP status callback upon receiving HANDLE_CLOSING.
-class WinHttpRequestThrottle {
- public:
- WinHttpRequestThrottle() {}
-
- virtual ~WinHttpRequestThrottle();
-
- // Intended to be a near drop-in replacement of WinHttpSendRequest.
- BOOL SubmitRequest(const std::string& server,
- HINTERNET request_handle,
- DWORD total_size,
- DWORD_PTR context);
-
- // Called when a request failed or completed successfully.
- void NotifyRequestDone(const std::string& server);
-
- // Called from the HttpTransactionWinHttp destructor.
- void RemoveRequest(const std::string& server,
- HINTERNET request_handle);
-
- protected:
- // Unit tests can stub out this method in a derived class.
- virtual BOOL SendRequest(HINTERNET request_handle,
- DWORD total_size,
- DWORD_PTR context,
- bool report_async_error);
-
- private:
- FRIEND_TEST(WinHttpRequestThrottleTest, GarbageCollect);
-
- class RequestQueue;
-
- struct PerServerThrottle {
- PerServerThrottle();
- ~PerServerThrottle();
-
- int num_requests; // Number of requests in progress
- linked_ptr<RequestQueue> request_queue; // Requests waiting to be sent
- };
-
- typedef std::map<std::string, PerServerThrottle> ThrottleMap;
-
- static const int kMaxConnectionsPerServer;
- static const int kGarbageCollectionThreshold;
-
- void GarbageCollect();
-
- ThrottleMap throttles_;
-
- DISALLOW_EVIL_CONSTRUCTORS(WinHttpRequestThrottle);
-};
-
-} // namespace net
-
-#endif // NET_HTTP_WINHTTP_REQUEST_THROTTLE_H_
-
diff --git a/net/http/winhttp_request_throttle_unittest.cc b/net/http/winhttp_request_throttle_unittest.cc
deleted file mode 100644
index 7ba0022..0000000
--- a/net/http/winhttp_request_throttle_unittest.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/string_util.h"
-#include "net/http/winhttp_request_throttle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// Converts an int i to an HINTERNET (void *) request handle.
-HINTERNET RequestHandle(int i) {
- return reinterpret_cast<HINTERNET>(static_cast<intptr_t>(i));
-}
-
-class MockRequestThrottle : public net::WinHttpRequestThrottle {
- public:
- MockRequestThrottle() : last_sent_request_(NULL) { }
-
- // The request handle of the last sent request. This allows us to determine
- // whether a submitted request was sent or queued.
- HINTERNET last_sent_request() const { return last_sent_request_; }
-
- protected:
- virtual BOOL SendRequest(HINTERNET request_handle,
- DWORD total_size,
- DWORD_PTR context,
- bool report_async_error) {
- last_sent_request_ = request_handle;
- return TRUE;
- }
-
- private:
- HINTERNET last_sent_request_;
-
- DISALLOW_EVIL_CONSTRUCTORS(MockRequestThrottle);
-};
-
-} // namespace
-
-namespace net {
-
-TEST(WinHttpRequestThrottleTest, OneServer) {
- MockRequestThrottle throttle;
- std::string server("http://www.foo.com");
- HINTERNET request_handle;
-
- // Submit 20 requests to the request throttle.
- // Expected outcome: 6 requests should be in progress, and requests 7-20
- // should be queued.
- for (int i = 1; i <= 20; i++) {
- request_handle = RequestHandle(i);
- EXPECT_TRUE(throttle.SubmitRequest(server, request_handle, 0, 0));
- if (i <= 6)
- EXPECT_EQ(request_handle, throttle.last_sent_request());
- else
- EXPECT_EQ(RequestHandle(6), throttle.last_sent_request());
- }
-
- // Notify the request throttle of the completion of 10 requests.
- // Expected outcome: 6 requests should be in progress, and requests 17-20
- // should be queued.
- for (int j = 0; j < 10; j++) {
- throttle.NotifyRequestDone(server);
- EXPECT_EQ(RequestHandle(7 + j), throttle.last_sent_request());
- }
-
- // Remove request 17, which is queued.
- // Expected outcome: Requests 18-20 should remain queued.
- request_handle = RequestHandle(17);
- throttle.RemoveRequest(server, request_handle);
- EXPECT_EQ(RequestHandle(16), throttle.last_sent_request());
-
- // Remove request 16, which is in progress.
- // Expected outcome: The request throttle should send request 18.
- // Requests 19-20 should remained queued.
- request_handle = RequestHandle(16);
- throttle.RemoveRequest(server, request_handle);
- EXPECT_EQ(RequestHandle(18), throttle.last_sent_request());
-
- // Notify the request throttle of the completion of the remaining
- // 8 requests.
- for (int j = 0; j < 8; j++) {
- throttle.NotifyRequestDone(server);
- if (j < 2)
- EXPECT_EQ(RequestHandle(19 + j), throttle.last_sent_request());
- else
- EXPECT_EQ(RequestHandle(20), throttle.last_sent_request());
- }
-}
-
-// Submit requests to a large number (> 64) of servers to force the garbage
-// collection of idle PerServerThrottles.
-TEST(WinHttpRequestThrottleTest, GarbageCollect) {
- MockRequestThrottle throttle;
- for (int i = 0; i < 150; i++) {
- std::string server("http://www.foo");
- server.append(IntToString(i));
- server.append(".com");
- throttle.SubmitRequest(server, RequestHandle(1), 0, 0);
- throttle.NotifyRequestDone(server);
- if (i < 64)
- EXPECT_EQ(i + 1, throttle.throttles_.size());
- else if (i < 129)
- EXPECT_EQ(i - 64, throttle.throttles_.size());
- else
- EXPECT_EQ(i - 129, throttle.throttles_.size());
- }
-}
-
-} // namespace net
-
diff --git a/net/net.xcodeproj/project.pbxproj b/net/net.xcodeproj/project.pbxproj
index d085c9f..d183dd9 100644
--- a/net/net.xcodeproj/project.pbxproj
+++ b/net/net.xcodeproj/project.pbxproj
@@ -141,7 +141,6 @@
82113A1D0E8434EE00E3848F /* x509_certificate_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 82113A1C0E8434EE00E3848F /* x509_certificate_unittest.cc */; };
82113A280E84360200E3848F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82113A270E84360200E3848F /* Security.framework */; };
82113BBD0E892E5800E3848F /* x509_certificate.cc in Sources */ = {isa = PBXBuildFile; fileRef = 82113BBC0E892E5800E3848F /* x509_certificate.cc */; };
- 821F207B0E5CD342003C7E38 /* cert_status_cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33610E5A194700A747DB /* cert_status_cache.cc */; };
821F207F0E5CD3C6003C7E38 /* http_vary_data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33520E5A194700A747DB /* http_vary_data.cc */; };
821F20A30E5CD407003C7E38 /* mime_sniffer_proxy.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33A60E5A198600A747DB /* mime_sniffer_proxy.cc */; };
821F20A50E5CD414003C7E38 /* url_request_view_cache_job.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33A90E5A198600A747DB /* url_request_view_cache_job.cc */; };
@@ -626,12 +625,10 @@
7BED33570E5A194700A747DB /* http_chunked_decoder_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_chunked_decoder_unittest.cc; sourceTree = "<group>"; };
7BED33580E5A194700A747DB /* http_util_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_util_unittest.cc; sourceTree = "<group>"; };
7BED33590E5A194700A747DB /* http_network_transaction_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_network_transaction_unittest.cc; sourceTree = "<group>"; };
- 7BED335A0E5A194700A747DB /* cert_status_cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cert_status_cache.h; sourceTree = "<group>"; };
7BED335C0E5A194700A747DB /* http_network_layer_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_network_layer_unittest.cc; sourceTree = "<group>"; };
7BED335D0E5A194700A747DB /* http_network_transaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http_network_transaction.h; sourceTree = "<group>"; };
7BED335E0E5A194700A747DB /* http_chunked_decoder.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_chunked_decoder.cc; sourceTree = "<group>"; };
7BED33600E5A194700A747DB /* http_atom_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http_atom_list.h; sourceTree = "<group>"; };
- 7BED33610E5A194700A747DB /* cert_status_cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cert_status_cache.cc; sourceTree = "<group>"; };
7BED33620E5A194700A747DB /* http_network_layer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_network_layer.cc; sourceTree = "<group>"; };
7BED33630E5A194700A747DB /* http_request_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http_request_info.h; sourceTree = "<group>"; };
7BED33640E5A194700A747DB /* http_chunked_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http_chunked_decoder.h; sourceTree = "<group>"; };
@@ -1068,8 +1065,6 @@
7BED33390E5A193400A747DB /* http */ = {
isa = PBXGroup;
children = (
- 7BED33610E5A194700A747DB /* cert_status_cache.cc */,
- 7BED335A0E5A194700A747DB /* cert_status_cache.h */,
7BED33600E5A194700A747DB /* http_atom_list.h */,
0435A4650E8DD69C00E4DF08 /* http_auth.cc */,
0435A4670E8DD6B300E4DF08 /* http_auth.h */,
@@ -1473,7 +1468,6 @@
7B8503FC0E5B2DA200730B43 /* block_files.cc in Sources */,
7BA0172F0E5A244D00044150 /* bzip2_filter.cc in Sources */,
7B8504050E5B2DBD00730B43 /* cache_util_posix.cc in Sources */,
- 821F207B0E5CD342003C7E38 /* cert_status_cache.cc in Sources */,
E4CE9C0D0E8BFFFA00D5378C /* client_socket_factory.cc in Sources */,
7B8504080E5B2DD800730B43 /* client_socket_handle.cc in Sources */,
7B8504090E5B2DD800730B43 /* client_socket_pool.cc in Sources */,
diff --git a/net/net_lib.scons b/net/net_lib.scons
index 20d2e6b..af94a53 100644
--- a/net/net_lib.scons
+++ b/net/net_lib.scons
@@ -153,8 +153,6 @@ input_files = ChromeFileList([
'url_request/url_request_view_cache_job.h',
]),
MSVSFilter('http', [
- 'http/cert_status_cache.cc',
- 'http/cert_status_cache.h',
'http/http_atom_list.h',
'http/http_cache.cc',
'http/http_cache.h',
@@ -171,8 +169,6 @@ input_files = ChromeFileList([
'http/http_response_info.h',
'http/http_transaction.h',
'http/http_transaction_factory.h',
- 'http/http_transaction_winhttp.cc',
- 'http/http_transaction_winhttp.h',
'http/http_util.cc',
'http/http_util.h',
'http/http_auth.cc',
@@ -195,8 +191,6 @@ input_files = ChromeFileList([
'http/http_auth_handler_digest.h',
'http/http_vary_data.cc',
'http/http_vary_data.h',
- 'http/winhttp_request_throttle.cc',
- 'http/winhttp_request_throttle.h',
]),
MSVSFilter('disk_cache', [
'disk_cache/addr.h',
@@ -268,8 +262,6 @@ if env.Bit('posix'):
# TODO(port): delete files from this list as they get ported.
input_files.Remove(
'base/ssl_config_service.cc',
- 'http/http_transaction_winhttp.cc',
- 'http/winhttp_request_throttle.cc',
'url_request/url_request_ftp_job.cc',
)
diff --git a/net/net_unittests.scons b/net/net_unittests.scons
index 17c75ef..fdbdf89 100644
--- a/net/net_unittests.scons
+++ b/net/net_unittests.scons
@@ -68,10 +68,8 @@ input_files = ChromeFileList([
'http/http_response_headers_unittest.cc',
'http/http_transaction_unittest.cc',
'http/http_transaction_unittest.h',
- 'http/http_transaction_winhttp_unittest.cc',
'http/http_util_unittest.cc',
'http/http_vary_data_unittest.cc',
- 'http/winhttp_request_throttle_unittest.cc',
]),
MSVSFilter('base', [
'base/auth_cache_unittest.cc',
@@ -117,8 +115,6 @@ if not env.Bit('windows'):
input_files.Remove(
'base/wininet_util_unittest.cc',
'build/precompiled_net$OBJSUFFIX',
- 'http/http_transaction_winhttp_unittest.cc',
- 'http/winhttp_request_throttle_unittest.cc',
)
if env.Bit('linux'):
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 7f51f52..06141f6 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -19,7 +19,6 @@
#include "net/base/net_errors.h"
#include "net/proxy/proxy_config_service_fixed.h"
#if defined(OS_WIN)
-#include "net/http/http_transaction_winhttp.h"
#include "net/proxy/proxy_config_service_win.h"
#include "net/proxy/proxy_resolver_winhttp.h"
#elif defined(OS_MACOSX)
diff --git a/webkit/tools/layout_tests/run_webkit_tests.py b/webkit/tools/layout_tests/run_webkit_tests.py
index 49a82b0..c70642e 100755
--- a/webkit/tools/layout_tests/run_webkit_tests.py
+++ b/webkit/tools/layout_tests/run_webkit_tests.py
@@ -347,9 +347,6 @@ class TestRunner:
if self._options.gp_fault_error_box:
shell_args.append('--gp-fault-error-box')
- if self._options.winhttp:
- shell_args.append('--winhttp')
-
# larger timeout if page heap is enabled.
if self._options.time_out_ms:
shell_args.append('--time-out-ms=' + self._options.time_out_ms)
@@ -771,9 +768,6 @@ if '__main__' == __name__:
"of test_shell; option is split on whitespace "
"before running. (example: "
"--wrapper='valgrind --smc-check=all')")
- option_parser.add_option("", "--winhttp", action="store_true",
- default=False,
- help="Use WinHTTP stack")
option_parser.add_option("", "--test-list", action="append",
help="read list of tests to run from file",
metavar="FILE")
diff --git a/webkit/tools/test_shell/test_shell_switches.cc b/webkit/tools/test_shell/test_shell_switches.cc
index 54e7af3..bf66faf 100644
--- a/webkit/tools/test_shell/test_shell_switches.cc
+++ b/webkit/tools/test_shell/test_shell_switches.cc
@@ -45,16 +45,13 @@ const wchar_t kDumpStatsTable[] = L"stats";
// Use a specified cache directory.
const wchar_t kCacheDir[] = L"cache-dir";
-// When being run through a memory profiler, trigger memory in use dumps at
+// When being run through a memory profiler, trigger memory in use dumps at
// startup and just prior to shutdown.
const wchar_t kDebugMemoryInUse[] = L"debug-memory-in-use";
// Enable cookies on the file:// scheme. --layout-tests also enables this.
const wchar_t kEnableFileCookies[] = L"enable-file-cookies";
-// Enable the winhttp network stack.
-const wchar_t kUseWinHttp[] = L"winhttp";
-
// Enable tracing events (see base/trace_event.h)
const wchar_t kEnableTracing[] = L"enable-tracing";
diff --git a/webkit/tools/test_shell/test_shell_switches.h b/webkit/tools/test_shell/test_shell_switches.h
index 22bc982..ce10d3f 100644
--- a/webkit/tools/test_shell/test_shell_switches.h
+++ b/webkit/tools/test_shell/test_shell_switches.h
@@ -25,7 +25,6 @@ extern const wchar_t kDumpStatsTable[];
extern const wchar_t kCacheDir[];
extern const wchar_t kDebugMemoryInUse[];
extern const wchar_t kEnableFileCookies[];
-extern const wchar_t kUseWinHttp[];
extern const wchar_t kEnableTracing[];
extern const wchar_t kAllowScriptsToCloseWindows[];
extern const wchar_t kCheckLayoutTestSystemDeps[];
diff --git a/webkit/tools/test_shell/test_shell_win.cc b/webkit/tools/test_shell/test_shell_win.cc
index d0dc942..1dec4db 100644
--- a/webkit/tools/test_shell/test_shell_win.cc
+++ b/webkit/tools/test_shell/test_shell_win.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "webkit/tools/test_shell/test_shell.h"
+
#include <windows.h>
#include <atlbase.h>
#include <commdlg.h>
#include <objbase.h>
#include <shlwapi.h>
-#include <wininet.h>
-
-#include "webkit/tools/test_shell/test_shell.h"
+#include <wininet.h> // For INTERNET_MAX_URL_LENGTH
#include "base/command_line.h"
#include "base/memory_debug.h"
@@ -143,11 +143,6 @@ void TestShell::InitializeTestShell(bool layout_test_mode) {
}
CommandLine parsed_command_line;
- // Make the selection of network stacks early on before any consumers try to
- // issue HTTP requests.
- if (parsed_command_line.HasSwitch(test_shell::kUseWinHttp))
- net::HttpNetworkLayer::UseWinHttp(true);
-
if (parsed_command_line.HasSwitch(test_shell::kCrashDumps)) {
std::wstring dir(
parsed_command_line.GetSwitchValue(test_shell::kCrashDumps));
@@ -223,7 +218,7 @@ bool TestShell::RunFileTest(const char *filename, const TestParams& params) {
static_cast<TestShell*>(win_util::GetWindowUserData(hwnd));
shell->ResetTestController();
- // ResetTestController may have closed the window we were holding on to.
+ // ResetTestController may have closed the window we were holding on to.
// Grab the first window again.
hwnd = *(TestShell::windowList()->begin());
shell = static_cast<TestShell*>(win_util::GetWindowUserData(hwnd));
@@ -272,7 +267,8 @@ bool TestShell::RunFileTest(const char *filename, const TestParams& params) {
// which we handle here.
if (!should_dump_as_text) {
// Plain text pages should be dumped as text
- std::wstring mime_type = webFrame->GetDataSource()->GetResponseMimeType();
+ std::wstring mime_type =
+ webFrame->GetDataSource()->GetResponseMimeType();
should_dump_as_text = (mime_type == L"text/plain");
}
if (should_dump_as_text) {
@@ -297,7 +293,7 @@ bool TestShell::RunFileTest(const char *filename, const TestParams& params) {
printf("%s", WideToUTF8(bfDump).c_str());
}
}
-
+
if (params.dump_pixels && !should_dump_as_text) {
// Image output: we write the image data to the file given on the
// command line (for the dump pixels argument), and the MD5 sum to
@@ -342,8 +338,8 @@ std::string TestShell::RewriteLocalUrl(const std::string& url) {
// TestShell implementation
void TestShell::PlatformCleanUp() {
- // When the window is destroyed, tell the Edit field to forget about us,
- // otherwise we will crash.
+ // When the window is destroyed, tell the Edit field to forget about us,
+ // otherwise we will crash.
win_util::SetWindowProc(m_editWnd, default_edit_wnd_proc_);
win_util::SetWindowUserData(m_editWnd, NULL);
}
@@ -358,7 +354,7 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
HWND hwnd;
int x = 0;
-
+
hwnd = CreateWindow(L"BUTTON", L"Back",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
@@ -386,7 +382,7 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
// this control is positioned by ResizeSubViews
m_editWnd = CreateWindow(L"EDIT", 0,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
- ES_AUTOVSCROLL | ES_AUTOHSCROLL,
+ ES_AUTOVSCROLL | ES_AUTOHSCROLL,
x, 0, 0, 0, m_mainWnd, 0, instance_handle_, 0);
default_edit_wnd_proc_ =
@@ -398,7 +394,7 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
WebViewHost::Create(m_mainWnd, delegate_.get(), *TestShell::web_prefs_));
webView()->SetUseEditorDelegate(true);
delegate_->RegisterDragDrop();
-
+
// Load our initial content.
if (!startingURL.empty())
LoadURL(startingURL.c_str());
@@ -456,8 +452,8 @@ void TestShell::WaitTestFinished() {
// Create a watchdog thread which just sets a timer and
// kills the process if it times out. This catches really
- // bad hangs where the shell isn't coming back to the
- // message loop. If the watchdog is what catches a
+ // bad hangs where the shell isn't coming back to the
+ // message loop. If the watchdog is what catches a
// timeout, it can't do anything except terminate the test
// shell, which is unfortunate.
finished_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -481,7 +477,7 @@ void TestShell::WaitTestFinished() {
SetEvent(finished_event_);
// Wait to join the watchdog thread. (up to 1s, then quit)
- WaitForSingleObject(thread_handle, 1000);
+ WaitForSingleObject(thread_handle, 1000);
}
void TestShell::InteractiveSetFocus(WebWidgetHost* host, bool enable) {
@@ -649,7 +645,7 @@ LRESULT CALLBACK TestShell::EditWndProc(HWND hwnd, UINT message,
case WM_CHAR:
if (wParam == VK_RETURN) {
wchar_t strPtr[MAX_URL_LENGTH + 1]; // Leave room for adding a NULL;
- *((LPWORD)strPtr) = MAX_URL_LENGTH;
+ *((LPWORD)strPtr) = MAX_URL_LENGTH;
LRESULT strLen = SendMessage(hwnd, EM_GETLINE, 0, (LPARAM)strPtr);
if (strLen > 0) {
strPtr[strLen] = 0; // EM_GETLINE doesn't NULL terminate.