File: proxy_configuration.cc

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (124 lines) | stat: -rw-r--r-- 4,415 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/winhttp/proxy_configuration.h"

#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/sys_string_conversions.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "components/winhttp/net_util.h"
#include "components/winhttp/proxy_info.h"
#include "components/winhttp/scoped_winttp_proxy_info.h"
#include "url/gurl.h"

namespace winhttp {

ProxyConfiguration::ProxyConfiguration(const ProxyInfo& proxy_info)
    : proxy_info_(proxy_info) {}

int ProxyConfiguration::access_type() const {
  return DoGetAccessType();
}

int ProxyConfiguration::DoGetAccessType() const {
  const bool is_using_named_proxy = !proxy_info_.auto_detect &&
                                    proxy_info_.auto_config_url.empty() &&
                                    !proxy_info_.proxy.empty();

  return is_using_named_proxy ? WINHTTP_ACCESS_TYPE_NAMED_PROXY
                              : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
}

absl::optional<ScopedWinHttpProxyInfo> ProxyConfiguration::GetProxyForUrl(
    HINTERNET session_handle,
    const GURL& url) const {
  return DoGetProxyForUrl(session_handle, url);
}

absl::optional<ScopedWinHttpProxyInfo> ProxyConfiguration::DoGetProxyForUrl(
    HINTERNET session_handle,
    const GURL& url) const {
  // Detect proxy settings using Web Proxy Auto Detection (WPAD).
  WINHTTP_AUTOPROXY_OPTIONS auto_proxy_options = {0};

  // Per MSDN, setting fAutoLogonIfChallenged to false first may work
  // if Windows cached the proxy config.
  auto_proxy_options.fAutoLogonIfChallenged = false;

  bool try_auto_proxy = false;

  if (proxy_info_.auto_detect) {
    auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
    auto_proxy_options.dwAutoDetectFlags =
        WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
    try_auto_proxy = true;
  }

  // PAC Url was specified, let system auto detect given the PAC url.
  if (!proxy_info_.auto_config_url.empty()) {
    auto_proxy_options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
    auto_proxy_options.lpszAutoConfigUrl = proxy_info_.auto_config_url.c_str();
    try_auto_proxy = true;
  }

  // Find the proxy server for the url.
  ScopedWinHttpProxyInfo winhttp_proxy_info = {};
  if (try_auto_proxy) {
    const std::wstring url_str = base::SysUTF8ToWide(url.spec());
    bool success = ::WinHttpGetProxyForUrl(session_handle, url_str.c_str(),
                                           &auto_proxy_options,
                                           winhttp_proxy_info.receive());
    if (!success && ::GetLastError() == ERROR_WINHTTP_LOGIN_FAILURE) {
      auto_proxy_options.fAutoLogonIfChallenged = true;
      success = ::WinHttpGetProxyForUrl(session_handle, url_str.c_str(),
                                        &auto_proxy_options,
                                        winhttp_proxy_info.receive());
    }

    if (!success) {
      PLOG(ERROR) << "Failed to get proxy for url";
      return {};
    }
  } else {
    winhttp_proxy_info.set_proxy(proxy_info_.proxy);
    winhttp_proxy_info.set_proxy_bypass(proxy_info_.proxy_bypass);
  }

  if (!winhttp_proxy_info.IsValid())
    return {};

  return winhttp_proxy_info;
}

void SetProxyForRequest(
    const HINTERNET request_handle,
    const absl::optional<ScopedWinHttpProxyInfo>& winhttp_proxy_info) {
  // Set the proxy option on the request handle.
  if (winhttp_proxy_info.has_value() && winhttp_proxy_info.value().IsValid()) {
    const ScopedWinHttpProxyInfo& proxy_info = winhttp_proxy_info.value();
    VLOG(1) << "Setting proxy " << proxy_info.proxy();
    auto hr = SetOption(request_handle, WINHTTP_OPTION_PROXY,
                        const_cast<WINHTTP_PROXY_INFO*>(proxy_info.get()));
    if (FAILED(hr)) {
      PLOG(ERROR) << "Failed to set WINHTTP_OPTION_PROXY: 0x" << std::hex << hr;
    }
  }
}

int AutoProxyConfiguration::DoGetAccessType() const {
  return WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY;
}

absl::optional<ScopedWinHttpProxyInfo> AutoProxyConfiguration::DoGetProxyForUrl(
    HINTERNET,
    const GURL&) const {
  // When using automatic proxy settings, Windows will resolve the proxy
  // for us.
  DVLOG(3) << "Auto-proxy: skip getting proxy for a url";
  return {};
}

}  // namespace winhttp