File: https_upgrades_interceptor.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (149 lines) | stat: -rw-r--r-- 6,528 bytes parent folder | download | duplicates (4)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SSL_HTTPS_UPGRADES_INTERCEPTOR_H_
#define CHROME_BROWSER_SSL_HTTPS_UPGRADES_INTERCEPTOR_H_

#include <memory>

#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
// #include "chrome/browser/ssl/https_first_mode_settings_tracker.h"
#include <optional>

#include "chrome/browser/ssl/https_only_mode_tab_helper.h"
#include "components/security_interstitials/core/https_only_mode_metrics.h"
#include "content/public/browser/url_loader_request_interceptor.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/request_priority.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "url/gurl.h"

namespace blink {
class ThrottlingURLLoader;
}  // namespace blink

namespace content {
class BrowserContext;
class NavigationUIData;
class WebContents;
}  // namespace content

// A class that attempts to intercept HTTP navigation requests and redirect them
// to HTTPS, and then if the upgraded requests fail redirect them back to HTTP.
// Its lifetime matches that of the content/ navigation loader code.
//
// (Aside: An alternate implementation of this class would be as a
// NavigationLoaderInterceptor in content/, which could have a slightly simpler
// implementation, but by having this in chrome/ we don't need a Delegate
// interface for the embedder logic. If we move this into content/ in the future
// -- for example, in order to have a default HTTPS Upgrades implementation in
// the content/ platform -- then we can make that switch.)
class HttpsUpgradesInterceptor : public content::URLLoaderRequestInterceptor,
                                 public network::mojom::URLLoader {
 public:
  static std::unique_ptr<HttpsUpgradesInterceptor> MaybeCreateInterceptor(
      content::FrameTreeNodeId frame_tree_node_id,
      content::NavigationUIData* navigation_ui_data_);

  HttpsUpgradesInterceptor(content::FrameTreeNodeId frame_tree_node_id,
                           bool http_interstitial_enabled,
                           content::NavigationUIData* navigation_ui_data_);
  ~HttpsUpgradesInterceptor() override;

  HttpsUpgradesInterceptor(const HttpsUpgradesInterceptor&) = delete;
  HttpsUpgradesInterceptor& operator=(const HttpsUpgradesInterceptor&) = delete;

  // content::URLLoaderRequestInterceptor:
  void MaybeCreateLoader(
      const network::ResourceRequest& tentative_resource_request,
      content::BrowserContext* browser_context,
      content::URLLoaderRequestInterceptor::LoaderCallback callback) override;
  bool MaybeCreateLoaderForResponse(
      const network::URLLoaderCompletionStatus& status,
      const network::ResourceRequest& request,
      network::mojom::URLResponseHeadPtr* response_head,
      mojo::ScopedDataPipeConsumerHandle* response_body,
      mojo::PendingRemote<network::mojom::URLLoader>* loader,
      mojo::PendingReceiver<network::mojom::URLLoaderClient>* client_receiver,
      blink::ThrottlingURLLoader* url_loader) override;

  // Continuation of MaybeCreateLoader() after querying the network service for
  // the HSTS status for the hostname in the request.
  void MaybeCreateLoaderOnHstsQueryCompleted(
      const network::ResourceRequest& tentative_resource_request,
      content::URLLoaderRequestInterceptor::LoaderCallback callback,
      bool is_hsts_active_for_host);

  // Sets the ports used by the EmbeddedTestServer (which uses random ports)
  // to determine the correct port to upgrade/fallback to in tests.
  static void SetHttpsPortForTesting(int port);
  static void SetHttpPortForTesting(int port);
  static int GetHttpsPortForTesting();
  static int GetHttpPortForTesting();

 private:
  // network::mojom::URLLoader:
  void FollowRedirect(
      const std::vector<std::string>& removed_headers,
      const net::HttpRequestHeaders& modified_headers,
      const net::HttpRequestHeaders& modified_cors_exempt_headers,
      const std::optional<GURL>& new_url) override {}
  void SetPriority(net::RequestPriority priority,
                   int intra_priority_value) override {}

  // Returns a RequestHandler callback that can be passed to the underlying
  // LoaderCallback to serve an artificial redirect to `new_url`.
  RequestHandler CreateRedirectHandler(const GURL& new_url);

  // Passed to the LoaderCallback as the ResponseHandler with `new_url` bound,
  // this method receives the receiver and client_remote from the
  // NavigationLoader, to bind against. Triggers a redirect to `new_url` using
  // `client`.
  void RedirectHandler(
      const GURL& new_url,
      const network::ResourceRequest& request,
      mojo::PendingReceiver<network::mojom::URLLoader> receiver,
      mojo::PendingRemote<network::mojom::URLLoaderClient> client);

  // Mojo error handling. Resets `receiver_` and `client_`.
  void OnConnectionClosed();

  // Used to access the WebContents for the navigation.
  content::FrameTreeNodeId frame_tree_node_id_;

  // Controls whether we are upgrading and falling back with an interstitial
  // before proceeding with the HTTP navigation. This reflects the general
  // UI setting. Only used to set the values of interstitial_state_.
  bool http_interstitial_enabled_by_pref_ = false;

  // Parameters about whether the throttle should trigger the interstitial
  // warning before navigating to the HTTP fallback URL. Can be null if the
  // current load isn't eligible for an upgrade.
  std::unique_ptr<
      security_interstitials::https_only_mode::HttpInterstitialState>
      interstitial_state_;

  // URLs seen by the interceptor, used to detect a redirect loop.
  std::set<GURL> urls_seen_;

  // Receiver for the URLLoader interface.
  mojo::Receiver<network::mojom::URLLoader> receiver_{this};

  // The owning client. Used for serving redirects.
  mojo::Remote<network::mojom::URLLoaderClient> client_;

  // Owned by NavigationURLLoaderImpl, which should outlive the interceptor.
  raw_ptr<content::NavigationUIData> navigation_ui_data_;
  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<HttpsUpgradesInterceptor> weak_factory_{this};
};

#endif  // CHROME_BROWSER_SSL_HTTPS_UPGRADES_INTERCEPTOR_H_