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

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

Issue 2739323003: DevTools protocol interception, blocking & modification of requests (Closed)
Patch Set: Dont assume there's only one element reader 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 explicit InterceptedPage(const InterceptedPage& other);
125 InterceptedPage(WebContents* web_contents,
126 base::WeakPtr<protocol::NetworkHandler> network_handler);
127 ~InterceptedPage();
128
129 WebContents* web_contents;
130 base::WeakPtr<protocol::NetworkHandler> network_handler;
131 };
132
133 void ContinueInterceptedRequestOnIoThread(
134 std::string interception_id,
135 std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
136 modifications,
137 std::unique_ptr<ContinueInterceptedRequestCallback> callback);
138
139 void StartInterceptingRequestsInternal(
140 int render_frame_id,
141 int frame_tree_node_id,
142 int process_id,
143 WebContents* web_contents,
144 base::WeakPtr<protocol::NetworkHandler> network_handler);
145
146 void StopInterceptingRequestsInternal(int render_frame_id,
147 int frame_tree_node_id,
148 int process_id);
149 void StopInterceptingRequestsOnIoThread(WebContents* web_contents);
150
151 std::string GetIdForRequest(const net::URLRequest* request,
152 bool* is_redirect);
153
154 // Returns a WeakPtr to the DevToolsURLInterceptorRequestJob corresponding
155 // to |interception_id|. Must be called on the IO thread.
156 DevToolsURLInterceptorRequestJob* GetJob(
157 const std::string& interception_id) const;
158
159 base::flat_map<std::pair<int, int>, InterceptedPage>
160 intercepted_render_frames_;
161
162 base::flat_map<int, InterceptedPage> intercepted_frame_tree_nodes_;
163
164 // UI thread only.
165 base::flat_map<WebContents*,
166 std::unique_ptr<InterceptedWebContentsObserver>>
167 observers_;
168
169 base::flat_map<std::string, DevToolsURLInterceptorRequestJob*>
170 interception_id_to_job_map_;
171
172 base::flat_set<const net::URLRequest*> sub_requests_;
173 base::flat_map<const net::URLRequest*, std::string> expected_redirects_;
174 size_t next_id_;
175
176 private:
177 friend class base::RefCountedThreadSafe<State>;
178 ~State();
179 DISALLOW_COPY_AND_ASSIGN(State);
180 };
181
182 const scoped_refptr<State>& state() const { return state_; }
183
184 private:
185 BrowserContext* const browser_context_;
186
187 scoped_refptr<State> state_;
188
189 DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptor);
190 };
191
192 } // namespace content
193
194 #endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_REQUEST_INTERCEPTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698