Chromium Code Reviews| 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/base/net_errors.h" | |
| 15 #include "net/url_request/url_request.h" | |
| 16 #include "net/url_request/url_request_job.h" | |
| 17 | |
| 18 namespace content { | |
| 19 namespace protocol { | |
| 20 class NetworkHandler; | |
| 21 } // namespace | |
| 22 | |
| 23 // A URLRequestJob that allows programmatic request blocking / modification or | |
| 24 // response mocking. | |
| 25 class DevToolsURLInterceptorRequestJob : public net::URLRequestJob, | |
|
Sami
2017/03/22 17:00:46
I'm wondering if there's any risk of wires getting
alex clarke (OOO till 29th)
2017/03/24 13:57:23
When we modify a request I think we do need to cre
| |
| 26 public net::URLRequest::Delegate { | |
| 27 public: | |
| 28 DevToolsURLInterceptorRequestJob( | |
| 29 base::WeakPtr<DevToolsURLRequestInterceptor::State> interceptor_state, | |
| 30 const std::string& intercept_id, | |
| 31 net::URLRequest* origional_request, | |
| 32 net::NetworkDelegate* origional_network_delegate, | |
| 33 protocol::NetworkHandler* network_handler, | |
| 34 bool is_redirect); | |
| 35 | |
| 36 ~DevToolsURLInterceptorRequestJob() override; | |
| 37 | |
| 38 // net::URLRequestJob implementation: | |
| 39 void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override; | |
| 40 void Start() override; | |
| 41 void Kill() override; | |
| 42 int ReadRawData(net::IOBuffer* buf, int buf_size) override; | |
| 43 int GetResponseCode() const override; | |
| 44 void GetResponseInfo(net::HttpResponseInfo* info) override; | |
| 45 bool GetMimeType(std::string* mime_type) const override; | |
| 46 bool GetCharset(std::string* charset) override; | |
| 47 void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; | |
| 48 | |
| 49 // net::URLRequest::Delegate methods: | |
| 50 void OnAuthRequired(net::URLRequest* request, | |
| 51 net::AuthChallengeInfo* auth_info) override; | |
| 52 void OnSSLCertificateError(net::URLRequest* request, | |
| 53 const net::SSLInfo& ssl_info, | |
| 54 bool fatal) override; | |
| 55 void OnResponseStarted(net::URLRequest* request, int net_error) override; | |
| 56 void OnReadCompleted(net::URLRequest* request, int bytes_read) override; | |
| 57 void OnReceivedRedirect(net::URLRequest* request, | |
| 58 const net::RedirectInfo& redirect_info, | |
| 59 bool* defer_redirect) override; | |
| 60 | |
| 61 bool OnAllow(); | |
|
Sami
2017/03/22 17:00:45
minor naming nit: These 4 seem like normal methods
alex clarke (OOO till 29th)
2017/03/24 13:57:23
Done.
| |
| 62 bool OnBlock(net::Error error_reason); | |
| 63 bool OnModifyRequest(protocol::Maybe<protocol::String> url, | |
| 64 protocol::Maybe<protocol::String> method, | |
| 65 protocol::Maybe<protocol::String> post_data, | |
| 66 protocol::Maybe<protocol::Network::Headers> headers); | |
| 67 bool OnMockResponse(const protocol::String& raw_response); | |
| 68 | |
| 69 void OnNetworkHandlerDeleted(); | |
| 70 | |
| 71 // We keep a copy of the original request details to facilitate the | |
| 72 // Network.modifyRequest command which could potentially change any of these | |
| 73 // fields. | |
| 74 struct RequestDetails { | |
| 75 RequestDetails(const GURL& url, | |
| 76 const std::string& method, | |
| 77 const std::string& post_data, | |
| 78 const net::HttpRequestHeaders& extra_request_headers, | |
| 79 const net::RequestPriority& priority, | |
| 80 const net::URLRequestContext* url_request_context); | |
| 81 ~RequestDetails(); | |
| 82 | |
| 83 GURL url; | |
| 84 std::string method; | |
| 85 std::string post_data; | |
| 86 net::HttpRequestHeaders extra_request_headers; | |
| 87 net::RequestPriority priority; | |
| 88 const net::URLRequestContext* url_request_context; | |
| 89 }; | |
| 90 | |
| 91 private: | |
| 92 class SubRequest; | |
| 93 | |
| 94 struct ModifyRequest { | |
| 95 ModifyRequest(protocol::Maybe<protocol::String> url, | |
| 96 protocol::Maybe<protocol::String> method, | |
| 97 protocol::Maybe<protocol::String> post_data, | |
| 98 protocol::Maybe<protocol::Network::Headers> headers); | |
| 99 ModifyRequest(ModifyRequest&& other); | |
| 100 ~ModifyRequest(); | |
| 101 | |
| 102 protocol::Maybe<protocol::String> url; | |
| 103 protocol::Maybe<protocol::String> method; | |
| 104 protocol::Maybe<protocol::String> post_data; | |
| 105 protocol::Maybe<protocol::Network::Headers> headers; | |
| 106 }; | |
| 107 | |
| 108 // If the request was either allowed or modified, a SubRequest will be used to | |
| 109 // perform the fetch and the results proxied to the original request. | |
| 110 class SubRequest { | |
| 111 public: | |
| 112 SubRequest( | |
| 113 const DevToolsURLInterceptorRequestJob::RequestDetails& request_details, | |
| 114 base::WeakPtr<DevToolsURLRequestInterceptor::State> interceptor_state, | |
| 115 DevToolsURLInterceptorRequestJob* devtools_interceptor_request_job); | |
| 116 ~SubRequest(); | |
| 117 | |
| 118 void Cancel(); | |
| 119 | |
| 120 net::URLRequest* request() const { return request_.get(); } | |
| 121 | |
| 122 private: | |
| 123 enum { kBufSize = 4096 }; | |
| 124 | |
| 125 std::unique_ptr<net::URLRequest> request_; | |
| 126 | |
| 127 // Buffer that |request| writes into. | |
| 128 scoped_refptr<net::IOBuffer> buf_; | |
|
Sami
2017/03/22 17:00:45
Is this used?
alex clarke (OOO till 29th)
2017/03/24 13:57:23
It was in earlier patch sets, can remove it now :)
| |
| 129 | |
| 130 base::WeakPtr<DevToolsURLRequestInterceptor::State> interceptor_state_; | |
| 131 | |
| 132 DevToolsURLInterceptorRequestJob* | |
| 133 devtools_interceptor_request_job_; // NOT OWNED. | |
| 134 | |
| 135 bool fetch_in_progress_; | |
| 136 }; | |
| 137 | |
| 138 class MockResponse { | |
| 139 public: | |
| 140 MockResponse(std::string response_bytes, | |
| 141 base::TimeTicks response_time, | |
| 142 const std::string& intercept_id); | |
| 143 | |
| 144 MockResponse( | |
| 145 const scoped_refptr<net::HttpResponseHeaders>& response_headers, | |
| 146 std::string response_bytes, | |
| 147 size_t read_offset, | |
| 148 base::TimeTicks response_time); | |
| 149 | |
| 150 ~MockResponse(); | |
| 151 | |
| 152 const scoped_refptr<net::HttpResponseHeaders>& response_headers() const { | |
| 153 return response_headers_; | |
| 154 } | |
| 155 | |
| 156 base::TimeTicks response_time() const { return response_time_; } | |
| 157 | |
| 158 int ReadRawData(net::IOBuffer* buf, int buf_size); | |
| 159 | |
| 160 private: | |
| 161 scoped_refptr<net::HttpResponseHeaders> response_headers_; | |
| 162 std::string response_bytes_; | |
| 163 size_t read_offset_; | |
| 164 base::TimeTicks response_time_; | |
| 165 }; | |
| 166 | |
| 167 // Retrieves the response headers from either the |sub_request_| or the | |
| 168 // |mock_response_|. In some cases (e.g. file access) this may be null. | |
| 169 const net::HttpResponseHeaders* GetHttpResponseHeaders() const; | |
| 170 | |
| 171 void DispatchError(net::Error reason); | |
| 172 void ModifyRequestOnIoThread(std::unique_ptr<ModifyRequest> modify_request); | |
| 173 void ProcessMockResponeOnIoThread(protocol::String response); | |
| 174 void ProcessOnAllowOnIoThread(); | |
| 175 void SendInterceptedRequestEventOnUiThread(); | |
| 176 void SendInterceptedRedirectEventOnUiThread( | |
| 177 protocol::DictionaryValue* headers_dict, | |
| 178 int http_status_code, | |
| 179 std::string redirect_url); | |
| 180 | |
| 181 struct IoThreadOnly { | |
| 182 explicit IoThreadOnly(net::URLRequest* request); | |
| 183 ~IoThreadOnly(); | |
| 184 | |
| 185 RequestDetails request_details; | |
| 186 std::unique_ptr<SubRequest> sub_request; | |
| 187 std::unique_ptr<MockResponse> mock_response; | |
| 188 std::unique_ptr<net::RedirectInfo> redirect; | |
| 189 }; | |
| 190 | |
| 191 struct UiThreadOnly { | |
| 192 UiThreadOnly(); | |
| 193 | |
| 194 bool waiting_for_user_response; | |
| 195 }; | |
| 196 | |
| 197 IoThreadOnly io_thread_only_; | |
| 198 IoThreadOnly& io_thread_only() { | |
|
Sami
2017/03/22 17:00:45
Thanks for making threading explicit!
alex clarke (OOO till 29th)
2017/03/24 13:57:23
Acknowledged.
| |
| 199 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 200 return io_thread_only_; | |
| 201 } | |
| 202 const IoThreadOnly& io_thread_only() const { | |
| 203 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 204 return io_thread_only_; | |
| 205 } | |
| 206 | |
| 207 UiThreadOnly ui_thread_only_; | |
| 208 UiThreadOnly& ui_thread_only() { | |
| 209 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 210 return ui_thread_only_; | |
| 211 } | |
| 212 const UiThreadOnly& ui_thread_only() const { | |
| 213 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 214 return ui_thread_only_; | |
| 215 } | |
| 216 | |
| 217 const std::string intercept_id_; | |
| 218 protocol::NetworkHandler* network_handler_; // NOT OWNED | |
| 219 const base::WeakPtr<DevToolsURLRequestInterceptor::State> interceptor_state_; | |
| 220 const scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; | |
| 221 const bool is_redirect_; | |
| 222 | |
| 223 DISALLOW_COPY_AND_ASSIGN(DevToolsURLInterceptorRequestJob); | |
| 224 }; | |
| 225 | |
| 226 } // namespace content | |
| 227 | |
| 228 #endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_URL_INTERCEPTOR_REQUEST_JOB_H_ | |
| OLD | NEW |