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

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

Issue 2739323003: DevTools protocol interception, blocking & modification of requests (Closed)
Patch Set: Hopefully sorted out the threading 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 enum class CommandStatus {
55 OK,
56 UnknownInterceptionId,
57 CommandAlreadyProcessed,
58 };
59
60 using CommandCallback = base::OnceCallback<void(const CommandStatus& status)>;
61
62 struct Modifications {
63 Modifications(base::Optional<net::Error> error_reason,
64 base::Optional<std::string> raw_response,
65 protocol::Maybe<std::string> modified_url,
66 protocol::Maybe<std::string> modified_method,
67 protocol::Maybe<std::string> modified_post_data,
68 protocol::Maybe<protocol::Network::Headers> modified_headers);
69 ~Modifications();
70
71 bool RequestShouldContineUnchanged() const;
72
73 // If none of the following are set then the request will be allowed to
74 // continue unchanged.
75 base::Optional<net::Error> error_reason; // Finish with error.
76 base::Optional<std::string> raw_response; // Finish with mock response.
77
78 // Optionally modify before sending to network.
79 protocol::Maybe<std::string> modified_url;
80 protocol::Maybe<std::string> modified_method;
81 protocol::Maybe<std::string> modified_post_data;
82 protocol::Maybe<protocol::Network::Headers> modified_headers;
83 };
84
85 struct InterceptedPage {
86 InterceptedPage();
87 explicit InterceptedPage(const InterceptedPage& other);
88 InterceptedPage(WebContents* web_contents,
89 base::WeakPtr<protocol::NetworkHandler> network_handler);
90 ~InterceptedPage();
91
92 WebContents* web_contents;
93 base::WeakPtr<protocol::NetworkHandler> network_handler;
94 };
95
96 // The State needs to be accessed on both UI and IO threads.
97 class State : public base::RefCountedThreadSafe<State> {
98 public:
99 State();
100
101 // Must be called on the IO thread.
102 void ContinueInterceptedRequest(
103 std::string interception_id,
104 std::unique_ptr<Modifications> modifications,
105 CommandCallback callback);
106
107 // Returns true if |request| should be intercepted and sets
108 // |network_handler|. Must be called on the IO thread.
109 bool ShouldInterceptRequest(const net::URLRequest* request,
110 const InterceptedPage** intercepted_page) const;
dgozman 2017/05/30 21:44:27 nit: can just return the struct by value, since yo
alex clarke (OOO till 29th) 2017/05/31 15:52:02 I was able to get rid of the default constructor b
alex clarke (OOO till 29th) 2017/05/31 15:54:37 Whoops I meant to say Chromium style mandates the
111
112 // Must be called on the IO thread.
113 DevToolsURLInterceptorRequestJob* CreateDevToolsURLInterceptorRequestJob(
114 net::URLRequest* request,
115 net::NetworkDelegate* network_delegate,
116 const InterceptedPage* intercepted_page);
117
118 // Must be called on the UI thread.
119 void StartInterceptingRequests(
120 WebContents* web_contents,
121 base::WeakPtr<protocol::NetworkHandler> network_handler);
122
123 // Must be called on the UI thread.
124 void StopInterceptingRequests(WebContents* web_contents);
125
126 // Registers a |sub_request| that should not be intercepted.
127 void RegisterSubRequest(const net::URLRequest* sub_request);
128
129 // Unregisters a |sub_request|. Must be called on the IO thread.
130 void UnregisterSubRequest(const net::URLRequest* sub_request);
131
132 // To make the user's life easier we make sure requests in a redirect chain
133 // all have the same id. Must be called on the IO thread.
134 void ExpectRequestAfterRedirect(const net::URLRequest* request,
135 std::string id);
136
137 // Must be called on the IO thread.
138 void JobFinished(const std::string& interception_id);
139
140 private:
141 class InterceptedWebContentsObserver;
142
143 void StartInterceptingRequestsInternal(
144 int render_frame_id,
145 int frame_tree_node_id,
146 int process_id,
147 WebContents* web_contents,
148 base::WeakPtr<protocol::NetworkHandler> network_handler);
149
150 void StopInterceptingRequestsInternal(int render_frame_id,
151 int frame_tree_node_id,
152 int process_id);
153 void StopInterceptingRequestsOnIoThread(WebContents* web_contents);
154
155 std::string GetIdForRequest(const net::URLRequest* request,
156 bool* is_redirect);
157
158 // Returns a WeakPtr to the DevToolsURLInterceptorRequestJob corresponding
159 // to |interception_id|. Must be called on the IO thread.
160 DevToolsURLInterceptorRequestJob* GetJob(
161 const std::string& interception_id) const;
162
163 base::flat_map<std::pair<int, int>, InterceptedPage>
164 intercepted_render_frames_;
165
166 base::flat_map<int, InterceptedPage> intercepted_frame_tree_nodes_;
167
168 // UI thread only.
169 base::flat_map<WebContents*,
170 std::unique_ptr<InterceptedWebContentsObserver>>
171 observers_;
172
173 base::flat_map<std::string, DevToolsURLInterceptorRequestJob*>
174 interception_id_to_job_map_;
175
176 base::flat_set<const net::URLRequest*> sub_requests_;
177 base::flat_map<const net::URLRequest*, std::string> expected_redirects_;
178 size_t next_id_;
179
180 private:
181 friend class base::RefCountedThreadSafe<State>;
182 ~State();
183 DISALLOW_COPY_AND_ASSIGN(State);
184 };
185
186 const scoped_refptr<State>& state() const { return state_; }
187
188 private:
189 BrowserContext* const browser_context_;
190
191 scoped_refptr<State> state_;
192
193 DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptor);
194 };
195
196 } // namespace content
197
198 #endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_REQUEST_INTERCEPTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698