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

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

Issue 2739323003: DevTools protocol interception, blocking & modification of requests (Closed)
Patch Set: Address remaining TODOs Created 3 years, 7 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/weak_ptr.h"
12 #include "base/optional.h"
13 #include "content/browser/devtools/protocol/network.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/base/net_errors.h"
16 #include "net/url_request/url_request_interceptor.h"
17
18 namespace content {
19 namespace protocol {
20 class NetworkHandler;
21 } // namespace
22
23 class BrowserContext;
24 class DevToolsURLInterceptorRequestJob;
25 class WebContents;
26
27 // An interceptor that creates DevToolsURLInterceptorRequestJobs for requests
28 // from pages where interception has been enabled via
29 // Network.enableFetchInterception.
30 class DevToolsURLRequestInterceptor : public net::URLRequestInterceptor {
31 public:
32 explicit DevToolsURLRequestInterceptor(BrowserContext* browser_context);
33 ~DevToolsURLRequestInterceptor() override;
34
35 // Must be called on UI thread.
36 static DevToolsURLRequestInterceptor* FromBrowserContext(
37 BrowserContext* context);
38
39 // net::URLRequestInterceptor implementation:
40 net::URLRequestJob* MaybeInterceptRequest(
41 net::URLRequest* request,
42 net::NetworkDelegate* network_delegate) const override;
43
44 net::URLRequestJob* MaybeInterceptRedirect(
45 net::URLRequest* request,
46 net::NetworkDelegate* network_delegate,
47 const GURL& location) const override;
48
49 net::URLRequestJob* MaybeInterceptResponse(
50 net::URLRequest* request,
51 net::NetworkDelegate* network_delegate) const override;
52
53 enum class CommandStatus {
54 OK,
55 UnknownInterceptionId,
56 CommandAlreadyProcessed,
57 };
58
59 using CommandCallback = base::OnceCallback<void(const CommandStatus& status)>;
60
61 struct Modifications {
62 Modifications(base::Optional<net::Error> error_reason,
63 base::Optional<std::string> raw_response,
64 protocol::Maybe<std::string> modified_url,
65 protocol::Maybe<std::string> modified_method,
66 protocol::Maybe<std::string> modified_post_data,
67 protocol::Maybe<protocol::Network::Headers> modified_headers);
68 ~Modifications();
69
70 bool RequestShouldContineUnchanged() const;
71
72 // If none of the following are set then the request will be allowed to
73 // continue unchanged.
74 base::Optional<net::Error> error_reason; // Finish with error.
75 base::Optional<std::string> raw_response; // Finish with mock response.
76
77 // Optionally modify before sending to network.
78 protocol::Maybe<std::string> modified_url;
79 protocol::Maybe<std::string> modified_method;
80 protocol::Maybe<std::string> modified_post_data;
81 protocol::Maybe<protocol::Network::Headers> modified_headers;
82 };
83
84 // Unfortunately the interface methods are const so we need a mutable inner
85 // class to hold our state.
86 class State {
87 public:
88 State();
89 ~State();
90
91 // Must be called on the IO thread.
92 void ContinueRequest(std::string interception_id,
93 std::unique_ptr<Modifications> modifications,
94 CommandCallback callback);
95
96 // Returns true if |request| should be intercepted and sets
97 // |network_handler|. Must be called on the IO thread.
98 bool ShouldInterceptRequest(
99 const net::URLRequest* request,
100 base::WeakPtr<protocol::NetworkHandler>* network_handler) const;
101
102 // Must be called on the IO thread.
103 void StartInterceptingRequests(
104 WebContents* web_contents,
105 base::WeakPtr<protocol::NetworkHandler> network_handler);
106
107 // Must be called on the IO thread.
108 void StopInterceptingRequests(WebContents* web_contents);
109
110 // Registers a |sub_request| that should not be intercepted.
111 void RegisterSubRequest(const net::URLRequest* sub_request);
112
113 // Unregisters a |sub_request|. Must be called on the IO thread.
114 void UnregisterSubRequest(const net::URLRequest* sub_request);
115
116 // To make the user's life easier we make sure requests in a redirect chain
117 // all have the same id. Must be called on the IO thread.
118 void ExpectRequestAfterRedirect(const net::URLRequest* request,
119 std::string id);
120
121 // Must be called on the IO thread.
122 std::string GetIdForRequest(const net::URLRequest* request,
123 bool* is_redirect);
124
125 // Must be called on the IO thread.
126 void RegisterJob(DevToolsURLInterceptorRequestJob* job,
127 const std::string& interception_id);
128
129 // Must be called on the IO thread.
130 void UnregisterJob(const std::string& interception_id);
131
132 base::WeakPtr<State> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
133
134 private:
135 class InterceptedWebContentsObserver;
136
137 void StartInterceptingRequestsInternal(
138 int render_frame_id,
139 int frame_tree_node_id,
140 int process_id,
141 base::WeakPtr<protocol::NetworkHandler> network_handler);
142
143 void StopInterceptingRequestsInternal(int render_frame_id,
144 int frame_tree_node_id,
145 int process_id);
146
147 // Returns a WeakPtr to the DevToolsURLInterceptorRequestJob corresponding
148 // to |interception_id|. Must be called on the IO thread.
149 DevToolsURLInterceptorRequestJob* GetJob(
150 const std::string& interception_id) const;
151
152 base::flat_map<std::pair<int, int>, base::WeakPtr<protocol::NetworkHandler>>
153 intercepted_render_frames_;
154
155 base::flat_map<int, base::WeakPtr<protocol::NetworkHandler>>
156 intercepted_frame_tree_nodes_;
157
158 base::flat_map<WebContents*,
159 std::unique_ptr<InterceptedWebContentsObserver>>
160 observers_;
161
162 base::flat_map<std::string, DevToolsURLInterceptorRequestJob*>
163 interception_id_to_job_map_;
164
165 base::flat_set<const net::URLRequest*> sub_requests_;
166 base::flat_map<const net::URLRequest*, std::string> expected_redirects_;
167 size_t next_id_;
168
169 base::WeakPtrFactory<State> weak_ptr_factory_;
170 };
171
172 State& state() const { return *state_; }
173
174 private:
175 BrowserContext* const browser_context_;
176
177 std::unique_ptr<State> state_;
178
179 DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptor);
180 };
181
182 } // namespace content
183
184 #endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_REQUEST_INTERCEPTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698