OLD | NEW |
---|---|
(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_INTERCEPTOR_REQUEST_JOB_H_ | |
6 #define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_INTERCEPTOR_REQUEST_JOB_H_ | |
7 | |
8 #include "base/macros.h" | |
9 #include "base/memory/weak_ptr.h" | |
10 #include "base/single_thread_task_runner.h" | |
11 #include "content/browser/devtools/devtools_url_request_interceptor.h" | |
12 #include "content/browser/devtools/protocol/network.h" | |
13 #include "content/public/browser/browser_thread.h" | |
14 #include "net/url_request/url_request.h" | |
15 #include "net/url_request/url_request_job.h" | |
16 | |
17 namespace net { | |
18 class UploadElementReader; | |
19 } | |
20 | |
21 namespace content { | |
22 | |
23 // A URLRequestJob that allows programmatic request blocking / modification or | |
24 // response mocking. This class should only be accessed on the IO thread. | |
25 class DevToolsURLInterceptorRequestJob : public net::URLRequestJob, | |
26 public net::URLRequest::Delegate { | |
27 public: | |
28 DevToolsURLInterceptorRequestJob( | |
29 base::WeakPtr<DevToolsURLRequestInterceptor::State> | |
30 devtools_url_request_interceptor_state, | |
31 const std::string& intercept_id, | |
32 net::URLRequest* original_request, | |
33 net::NetworkDelegate* original_network_delegate, | |
34 base::WeakPtr<protocol::NetworkHandler> network_handler, | |
35 bool is_redirect); | |
36 | |
37 ~DevToolsURLInterceptorRequestJob() override; | |
38 | |
39 // net::URLRequestJob implementation: | |
40 void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override; | |
41 void Start() override; | |
42 void Kill() override; | |
43 int ReadRawData(net::IOBuffer* buf, int buf_size) override; | |
44 int GetResponseCode() const override; | |
45 void GetResponseInfo(net::HttpResponseInfo* info) override; | |
46 bool GetMimeType(std::string* mime_type) const override; | |
47 bool GetCharset(std::string* charset) override; | |
48 void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; | |
49 | |
50 // net::URLRequest::Delegate methods: | |
51 void OnAuthRequired(net::URLRequest* request, | |
52 net::AuthChallengeInfo* auth_info) override; | |
53 void OnSSLCertificateError(net::URLRequest* request, | |
54 const net::SSLInfo& ssl_info, | |
55 bool fatal) override; | |
56 void OnResponseStarted(net::URLRequest* request, int net_error) override; | |
57 void OnReadCompleted(net::URLRequest* request, int bytes_read) override; | |
58 void OnReceivedRedirect(net::URLRequest* request, | |
59 const net::RedirectInfo& redirect_info, | |
60 bool* defer_redirect) override; | |
61 | |
62 DevToolsURLRequestInterceptor::CommandStatus AllowRequest(); | |
63 DevToolsURLRequestInterceptor::CommandStatus BlockRequest( | |
64 net::Error error_reason); | |
65 DevToolsURLRequestInterceptor::CommandStatus ModifyRequest( | |
66 std::unique_ptr<DevToolsURLRequestInterceptor::Modifications> | |
67 modifications); | |
68 DevToolsURLRequestInterceptor::CommandStatus MockResponse( | |
69 std::string raw_response); | |
Sami
2017/05/19 17:15:43
nit: const ref
alex clarke (OOO till 29th)
2017/05/23 15:46:55
Can't do that safely since this is called via post
| |
70 | |
71 private: | |
72 class SubRequest; | |
73 | |
74 // We keep a copy of the original request details to facilitate the | |
75 // Network.modifyRequest command which could potentially change any of these | |
76 // fields. | |
77 struct RequestDetails { | |
78 RequestDetails(const GURL& url, | |
79 const std::string& method, | |
80 std::unique_ptr<net::UploadElementReader> post_data, | |
81 const net::HttpRequestHeaders& extra_request_headers, | |
82 const net::RequestPriority& priority, | |
83 const net::URLRequestContext* url_request_context); | |
84 ~RequestDetails(); | |
85 | |
86 GURL url; | |
87 std::string method; | |
88 std::unique_ptr<net::UploadElementReader> post_data; | |
89 net::HttpRequestHeaders extra_request_headers; | |
90 net::RequestPriority priority; | |
91 const net::URLRequestContext* url_request_context; | |
92 }; | |
93 | |
94 // If the request was either allowed or modified, a SubRequest will be used to | |
95 // perform the fetch and the results proxied to the original request. This | |
96 // gives us the flexibility to pretend redirects didn't happen if the user | |
97 // chooses to mock the response. | |
Sami
2017/05/19 17:15:43
Maybe also worth mentioning that the subrequest is
alex clarke (OOO till 29th)
2017/05/23 15:46:56
Done.
| |
98 class SubRequest { | |
99 public: | |
100 SubRequest( | |
101 DevToolsURLInterceptorRequestJob::RequestDetails& request_details, | |
102 DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job); | |
103 ~SubRequest(); | |
104 | |
105 void Cancel(); | |
106 | |
107 net::URLRequest* request() const { return request_.get(); } | |
108 | |
109 private: | |
110 std::unique_ptr<net::URLRequest> request_; | |
111 | |
112 DevToolsURLInterceptorRequestJob* | |
113 devtools_interceptor_request_job_; // NOT OWNED. | |
114 | |
115 base::WeakPtr<DevToolsURLRequestInterceptor::State> | |
116 devtools_url_request_interceptor_state_; | |
117 bool fetch_in_progress_; | |
118 }; | |
119 | |
120 class MockResponseDetails { | |
121 public: | |
122 MockResponseDetails(std::string response_bytes, | |
123 base::TimeTicks response_time); | |
124 | |
125 MockResponseDetails( | |
126 const scoped_refptr<net::HttpResponseHeaders>& response_headers, | |
127 std::string response_bytes, | |
128 size_t read_offset, | |
129 base::TimeTicks response_time); | |
130 | |
131 ~MockResponseDetails(); | |
132 | |
133 const scoped_refptr<net::HttpResponseHeaders>& response_headers() const { | |
Sami
2017/05/19 17:15:43
nit: Maybe just return net::HttpResponseHeaders* s
alex clarke (OOO till 29th)
2017/05/23 15:46:55
Actually that's exactly what DevToolsURLIntercepto
| |
134 return response_headers_; | |
135 } | |
136 | |
137 base::TimeTicks response_time() const { return response_time_; } | |
138 | |
139 int ReadRawData(net::IOBuffer* buf, int buf_size); | |
140 | |
141 private: | |
142 scoped_refptr<net::HttpResponseHeaders> response_headers_; | |
143 std::string response_bytes_; | |
144 size_t read_offset_; | |
145 base::TimeTicks response_time_; | |
146 }; | |
147 | |
148 // Retrieves the response headers from either the |sub_request_| or the | |
149 // |mock_response_|. In some cases (e.g. file access) this may be null. | |
150 const net::HttpResponseHeaders* GetHttpResponseHeaders() const; | |
151 | |
152 void DispatchError(net::Error reason); | |
153 void SendInterceptedRequestEventOnUiThread(); | |
154 void SendInterceptedRedirectEventOnUiThread( | |
155 protocol::DictionaryValue* headers_dict, | |
156 int http_status_code, | |
157 std::string redirect_url); | |
Sami
2017/05/19 17:15:43
nit: const ref
alex clarke (OOO till 29th)
2017/05/23 15:46:56
Can't do that due to PostTask and the source going
| |
158 | |
159 base::WeakPtr<DevToolsURLRequestInterceptor::State> | |
160 devtools_url_request_interceptor_state_; | |
161 RequestDetails request_details_; | |
162 std::unique_ptr<SubRequest> sub_request_; | |
163 std::unique_ptr<MockResponseDetails> mock_response_details_; | |
164 std::unique_ptr<net::RedirectInfo> redirect_; | |
165 bool waiting_for_user_response_; | |
Sami
2017/05/19 17:15:43
Uninitialized?
alex clarke (OOO till 29th)
2017/05/23 15:46:56
Done.
| |
166 | |
167 const std::string intercept_id_; | |
168 base::WeakPtr<protocol::NetworkHandler> network_handler_; | |
169 const scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; | |
170 const bool is_redirect_; | |
171 base::WeakPtrFactory<DevToolsURLInterceptorRequestJob> weak_ptr_factory_; | |
172 | |
173 DISALLOW_COPY_AND_ASSIGN(DevToolsURLInterceptorRequestJob); | |
174 }; | |
175 | |
176 } // namespace content | |
177 | |
178 #endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_INTERCEPTOR_REQUEST_JOB_H_ | |
OLD | NEW |