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

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

Issue 2877423004: without the plumbing!
Patch Set: 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 #include "content/browser/devtools/devtools_url_request_interceptor.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/supports_user_data.h"
10 #include "content/browser/devtools/devtools_agent_host_impl.h"
11 #include "content/browser/devtools/devtools_url_interceptor_request_job.h"
12 #include "content/browser/devtools/protocol/network_handler.h"
13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/devtools_agent_host.h"
16 #include "content/public/browser/resource_request_info.h"
17 #include "net/http/http_request_headers.h"
18 #include "net/url_request/url_request.h"
19
20 namespace content {
21
22 namespace {
23 const char kDevToolsURLRequestInterceptorKeyName[] =
24 "DevToolsURLRequestInterceptor";
25
26 class DevToolsURLRequestInterceptorUserData
27 : public base::SupportsUserData::Data {
28 public:
29 explicit DevToolsURLRequestInterceptorUserData(
30 DevToolsURLRequestInterceptor* devtools_url_request_interceptor)
31 : devtools_url_request_interceptor_(devtools_url_request_interceptor) {}
32
33 DevToolsURLRequestInterceptor* devtools_url_request_interceptor() const {
34 return devtools_url_request_interceptor_;
35 }
36
37 private:
38 DevToolsURLRequestInterceptor* devtools_url_request_interceptor_;
39
40 DISALLOW_COPY_AND_ASSIGN(DevToolsURLRequestInterceptorUserData);
41 };
42
43 } // namespace
44
45 DevToolsURLRequestInterceptor::DevToolsURLRequestInterceptor(
46 BrowserContext* browser_context)
47 : browser_context_(browser_context), weak_ptr_factory_(this) {
48 DCHECK_CURRENTLY_ON(BrowserThread::UI);
49 browser_context_->SetUserData(
50 kDevToolsURLRequestInterceptorKeyName,
51 base::MakeUnique<DevToolsURLRequestInterceptorUserData>(this));
52
53 // The State object needs to be created on the IO thread or we can't use
54 // WeakPtr when posing tasks to run on the IO thread.
55 BrowserThread::PostTask(
56 BrowserThread::IO, FROM_HERE,
57 base::BindOnce(&DevToolsURLRequestInterceptor::CreateStateOnIoThread,
58 weak_ptr_factory_.GetWeakPtr()));
59 }
60
61 DevToolsURLRequestInterceptor::~DevToolsURLRequestInterceptor() {
62 DCHECK_CURRENTLY_ON(BrowserThread::IO);
63 // The BrowserContext owns us, so we don't need to unregister
64 // DevToolsURLRequestInterceptorUserData explicitly.
65 }
66
67 net::URLRequestJob* DevToolsURLRequestInterceptor::MaybeInterceptRequest(
68 net::URLRequest* request,
69 net::NetworkDelegate* network_delegate) const {
70 DCHECK_CURRENTLY_ON(BrowserThread::IO);
71
72 base::WeakPtr<protocol::NetworkHandler> network_handler;
73 if (!state().ShouldInterceptRequest(request, &network_handler))
74 return nullptr;
75
76 bool is_redirect;
77 return new DevToolsURLInterceptorRequestJob(
78 state().GetWeakPtr(), state().GetIdForRequest(request, &is_redirect),
79 request, network_delegate, network_handler, is_redirect);
80 }
81
82 net::URLRequestJob* DevToolsURLRequestInterceptor::MaybeInterceptRedirect(
83 net::URLRequest* request,
84 net::NetworkDelegate* network_delegate,
85 const GURL& location) const {
86 return nullptr;
87 }
88
89 net::URLRequestJob* DevToolsURLRequestInterceptor::MaybeInterceptResponse(
90 net::URLRequest* request,
91 net::NetworkDelegate* network_delegate) const {
92 return nullptr;
93 }
94
95 void DevToolsURLRequestInterceptor::State::AllowRequest(
96 protocol::String interception_id,
97 CommandCallback callback) {
98 DCHECK_CURRENTLY_ON(BrowserThread::IO);
99 DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
100 if (!job) {
101 std::move(callback).Run(CommandStatus::UnknownInterceptionId);
102 } else {
103 std::move(callback).Run(job->AllowRequest());
104 }
105 }
106
107 void DevToolsURLRequestInterceptor::State::BlockRequest(
108 protocol::String interception_id,
109 net::Error error_reason,
110 CommandCallback callback) {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
113 if (!job) {
114 std::move(callback).Run(CommandStatus::UnknownInterceptionId);
115 } else {
116 std::move(callback).Run(job->BlockRequest(error_reason));
117 }
118 }
119
120 void DevToolsURLRequestInterceptor::State::ModifyRequest(
121 protocol::String interception_id,
122 std::unique_ptr<Modifications> modifications,
123 CommandCallback callback) {
124 DCHECK_CURRENTLY_ON(BrowserThread::IO);
125 DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
126 if (!job) {
127 std::move(callback).Run(CommandStatus::UnknownInterceptionId);
128 } else {
129 std::move(callback).Run(job->ModifyRequest(std::move(modifications)));
130 }
131 }
132
133 void DevToolsURLRequestInterceptor::State::MockResponse(
134 protocol::String interception_id,
135 protocol::String raw_response,
136 CommandCallback callback) {
137 DCHECK_CURRENTLY_ON(BrowserThread::IO);
138 DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
139 if (!job) {
140 std::move(callback).Run(CommandStatus::UnknownInterceptionId);
141 } else {
142 std::move(callback).Run(job->MockResponse(std::move(raw_response)));
143 }
144 }
145
146 DevToolsURLRequestInterceptor::State::State()
147 : next_id_(0), weak_ptr_factory_(this) {}
148
149 DevToolsURLRequestInterceptor::State::~State() {}
150
151 bool DevToolsURLRequestInterceptor::State::ShouldInterceptRequest(
152 const net::URLRequest* request,
153 base::WeakPtr<protocol::NetworkHandler>* network_handler) const {
154 const ResourceRequestInfo* resource_request_info =
155 ResourceRequestInfo::ForRequest(request);
156 if (!resource_request_info)
157 return false;
158 int frame_tree_node_id = resource_request_info->GetFrameTreeNodeId();
159 if (frame_tree_node_id == -1) {
160 // |frame_tree_node_id| is not set for renderer side requests, fall back to
161 // the RenderFrameID.
162 int render_frame_id = resource_request_info->GetRenderFrameID();
163 const auto find_it = intercepted_render_frames_.find(render_frame_id);
164 if (find_it == intercepted_render_frames_.end())
165 return false;
166 *network_handler = find_it->second;
167 } else {
168 // |frame_tree_node_id| is set for browser side navigations, so use that
169 // because the RenderFrameID isn't known.
170 const auto find_it = intercepted_frame_tree_nodes_.find(frame_tree_node_id);
171 if (find_it == intercepted_frame_tree_nodes_.end())
172 return false;
173 *network_handler = find_it->second;
174 }
175
176 // We don't want to intercept our own sub requests.
177 return sub_requests_.find(request) == sub_requests_.end();
178 }
179
180 void DevToolsURLRequestInterceptor::State::StartInterceptingRequestsFrom(
181 int render_frame_id,
182 int frame_tree_node_id,
183 base::WeakPtr<protocol::NetworkHandler> network_handler) {
184 DCHECK_CURRENTLY_ON(BrowserThread::IO);
185 intercepted_render_frames_[render_frame_id] = network_handler;
186 intercepted_frame_tree_nodes_[frame_tree_node_id] = network_handler;
187 }
188
189 void DevToolsURLRequestInterceptor::State::StopInterceptingRequestsFrom(
190 int render_frame_id,
191 int frame_tree_node_id) {
192 DCHECK_CURRENTLY_ON(BrowserThread::IO);
193 intercepted_render_frames_.erase(render_frame_id);
194 intercepted_frame_tree_nodes_.erase(frame_tree_node_id);
195 }
196
197 void DevToolsURLRequestInterceptor::State::RegisterSubRequest(
198 const net::URLRequest* sub_request) {
199 DCHECK_CURRENTLY_ON(BrowserThread::IO);
200 DCHECK(sub_requests_.find(sub_request) == sub_requests_.end());
201 sub_requests_.insert(sub_request);
202 }
203
204 void DevToolsURLRequestInterceptor::State::UnregisterSubRequest(
205 const net::URLRequest* sub_request) {
206 DCHECK_CURRENTLY_ON(BrowserThread::IO);
207 DCHECK(sub_requests_.find(sub_request) != sub_requests_.end());
208 sub_requests_.erase(sub_request);
209 }
210
211 void DevToolsURLRequestInterceptor::State::ExpectRequestAfterRedirect(
212 const net::URLRequest* request,
213 std::string id) {
214 DCHECK_CURRENTLY_ON(BrowserThread::IO);
215 expected_redirects_[request] = id;
216 }
217
218 std::string DevToolsURLRequestInterceptor::State::GetIdForRequest(
219 const net::URLRequest* request,
220 bool* is_redirect) {
221 DCHECK_CURRENTLY_ON(BrowserThread::IO);
222 auto find_it = expected_redirects_.find(request);
223 if (find_it == expected_redirects_.end()) {
224 *is_redirect = false;
225 return base::StringPrintf("id-%zu", ++next_id_);
226 }
227 *is_redirect = true;
228 std::string id = find_it->second;
229 expected_redirects_.erase(find_it);
230 return id;
231 }
232
233 DevToolsURLInterceptorRequestJob* DevToolsURLRequestInterceptor::State::GetJob(
234 const std::string& interception_id) const {
235 DCHECK_CURRENTLY_ON(BrowserThread::IO);
236 const auto it = interception_id_to_job_map_.find(interception_id);
237 if (it == interception_id_to_job_map_.end())
238 return nullptr;
239 return it->second;
240 }
241
242 void DevToolsURLRequestInterceptor::State::RegisterJob(
243 DevToolsURLInterceptorRequestJob* job,
244 const std::string& interception_id) {
245 DCHECK_CURRENTLY_ON(BrowserThread::IO);
246 interception_id_to_job_map_[interception_id] = job;
247 }
248
249 void DevToolsURLRequestInterceptor::State::UnregisterJob(
250 const std::string& interception_id) {
251 DCHECK_CURRENTLY_ON(BrowserThread::IO);
252 interception_id_to_job_map_.erase(interception_id);
253 }
254
255 // static
256 DevToolsURLRequestInterceptor*
257 DevToolsURLRequestInterceptor::FromBrowserContext(BrowserContext* context) {
258 DCHECK_CURRENTLY_ON(BrowserThread::UI);
259 return static_cast<DevToolsURLRequestInterceptorUserData*>(
260 context->GetUserData(kDevToolsURLRequestInterceptorKeyName))
261 ->devtools_url_request_interceptor();
262 }
263
264 void DevToolsURLRequestInterceptor::CreateStateOnIoThread() {
265 DCHECK_CURRENTLY_ON(BrowserThread::IO);
266 state_.reset(new State());
267 }
268
269 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/devtools_url_request_interceptor.h ('k') | content/browser/devtools/protocol/network_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698