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

Side by Side Diff: content/browser/devtools/devtools_url_request_interceptor.h

Issue 2739323003: DevTools protocol interception, blocking & modification of requests (Closed)
Patch Set: Add a comment Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_REQUEST_INTERCEPTOR_H_
6 #define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_REQUEST_INTERCEPTOR_H_
7
8 #include "base/containers/flat_map.h"
9 #include "base/containers/flat_set.h"
10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/optional.h"
14 #include "content/browser/devtools/protocol/network.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "net/base/net_errors.h"
17 #include "net/url_request/url_request_interceptor.h"
18
19 namespace content {
20 namespace protocol {
21 class NetworkHandler;
22 } // namespace
23
24 class BrowserContext;
25 class DevToolsURLInterceptorRequestJob;
26 class WebContents;
27
28 // An interceptor that creates DevToolsURLInterceptorRequestJobs for requests
29 // from pages where interception has been enabled via
30 // Network.enableRequestInterception.
31 class DevToolsURLRequestInterceptor : public net::URLRequestInterceptor {
32 public:
33 explicit DevToolsURLRequestInterceptor(BrowserContext* browser_context);
34 ~DevToolsURLRequestInterceptor() override;
35
36 // Must be called on UI thread.
37 static DevToolsURLRequestInterceptor* FromBrowserContext(
38 BrowserContext* context);
39
40 // net::URLRequestInterceptor implementation:
41 net::URLRequestJob* MaybeInterceptRequest(
42 net::URLRequest* request,
43 net::NetworkDelegate* network_delegate) const override;
44
45 net::URLRequestJob* MaybeInterceptRedirect(
46 net::URLRequest* request,
47 net::NetworkDelegate* network_delegate,
48 const GURL& location) const override;
49
50 net::URLRequestJob* MaybeInterceptResponse(
51 net::URLRequest* request,
52 net::NetworkDelegate* network_delegate) const override;
53
54 struct Modifications {
55 Modifications(base::Optional<net::Error> error_reason,
56 base::Optional<std::string> raw_response,
57 protocol::Maybe<std::string> modified_url,
58 protocol::Maybe<std::string> modified_method,
59 protocol::Maybe<std::string> modified_post_data,
60 protocol::Maybe<protocol::Network::Headers> modified_headers);
61 ~Modifications();
62
63 bool RequestShouldContineUnchanged() const;
64
65 // If none of the following are set then the request will be allowed to
66 // continue unchanged.
67 base::Optional<net::Error> error_reason; // Finish with error.
68 base::Optional<std::string> raw_response; // Finish with mock response.
69
70 // Optionally modify before sending to network.
71 protocol::Maybe<std::string> modified_url;
72 protocol::Maybe<std::string> modified_method;
73 protocol::Maybe<std::string> modified_post_data;
74 protocol::Maybe<protocol::Network::Headers> modified_headers;
75 };
76
77 // The State needs to be accessed on both UI and IO threads.
78 class State : public base::RefCountedThreadSafe<State> {
79 public:
80 State();
81
82 using ContinueInterceptedRequestCallback =
83 protocol::Network::Backend::ContinueInterceptedRequestCallback;
84
85 // Must be called on the UI thread.
86 void ContinueInterceptedRequest(
87 std::string interception_id,
88 std::unique_ptr<Modifications> modifications,
89 std::unique_ptr<ContinueInterceptedRequestCallback> callback);
90
91 // Returns a DevToolsURLInterceptorRequestJob if the request should be
92 // intercepted, otherwise returns nullptr. Must be called on the IO thread.
93 DevToolsURLInterceptorRequestJob*
94 MaybeCreateDevToolsURLInterceptorRequestJob(
95 net::URLRequest* request,
96 net::NetworkDelegate* network_delegate);
97
98 // Must be called on the UI thread.
99 void StartInterceptingRequests(
100 WebContents* web_contents,
101 base::WeakPtr<protocol::NetworkHandler> network_handler);
102
103 // Must be called on the UI thread.
104 void StopInterceptingRequests(WebContents* web_contents);
105
106 // Registers a |sub_request| that should not be intercepted.
107 void RegisterSubRequest(const net::URLRequest* sub_request);
108
109 // Unregisters a |sub_request|. Must be called on the IO thread.
110 void UnregisterSubRequest(const net::URLRequest* sub_request);
111
112 // To make the user's life easier we make sure requests in a redirect chain
113 // all have the same id. Must be called on the IO thread.
114 void ExpectRequestAfterRedirect(const net::URLRequest* request,
115 std::string id);
116
117 // Must be called on the IO thread.
118 void JobFinished(const std::string& interception_id);
119
120 private:
121 class InterceptedWebContentsObserver;
122
123 struct InterceptedPage {
124 InterceptedPage();
125 InterceptedPage(const InterceptedPage& other);
126 InterceptedPage(WebContents* web_contents,
127 base::WeakPtr<protocol::NetworkHandler> network_handler);
128 ~InterceptedPage();
129
130 WebContents* web_contents;
131 base::WeakPtr<protocol::NetworkHandler> network_handler;
132 };
133
134 void ContinueInterceptedRequestOnIoThread(
135 std::string interception_id,
136 std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
137 modifications,
138 std::unique_ptr<ContinueInterceptedRequestCallback> callback);
139
140 void StartInterceptingRequestsInternal(
141 int render_frame_id,
142 int frame_tree_node_id,
143 int process_id,
144 WebContents* web_contents,
145 base::WeakPtr<protocol::NetworkHandler> network_handler);
146
147 void StopInterceptingRequestsInternal(int render_frame_id,
148 int frame_tree_node_id,
149 int process_id);
150 void StopInterceptingRequestsOnIoThread(WebContents* web_contents);
151
152 std::string GetIdForRequest(const net::URLRequest* request,
153 bool* is_redirect);
154
155 // Returns a WeakPtr to the DevToolsURLInterceptorRequestJob corresponding
156 // to |interception_id|. Must be called on the IO thread.
157 DevToolsURLInterceptorRequestJob* GetJob(
158 const std::string& interception_id) const;
159
160 base::flat_map<std::pair<int, int>, InterceptedPage>
161 intercepted_render_frames_;
162
163 base::flat_map<int, InterceptedPage> intercepted_frame_tree_nodes_;
164
165 // UI thread only.
166 base::flat_map<WebContents*,
167 std::unique_ptr<InterceptedWebContentsObserver>>
168 observers_;
169
170 base::flat_map<std::string, DevToolsURLInterceptorRequestJob*>
171 interception_id_to_job_map_;
172
173 base::flat_set<const net::URLRequest*> sub_requests_;
174 base::flat_map<const net::URLRequest*, std::string> expected_redirects_;
175 size_t next_id_;
176
177 private:
178 friend class base::RefCountedThreadSafe<State>;
179 ~State();
180 DISALLOW_COPY_AND_ASSIGN(State);
181 };
182
183 const scoped_refptr<State>& state() const { return state_; }
184
185 private:
186 BrowserContext* const browser_context_;
187
188 scoped_refptr<State> state_;
189
190 DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptor);
191 };
192
193 } // namespace content
194
195 #endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_REQUEST_INTERCEPTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698