blob: 8ccd5f098f0db71f71384a48a66b257d19a80ffc [file] [log] [blame]
[email protected]9c1662b2012-03-06 15:44:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2e4633c2009-07-09 16:58:062// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/automation/url_request_automation_job.h"
6
[email protected]8c6517e52011-10-17 01:20:367#include "base/bind.h"
[email protected]4630e5a2010-12-03 06:16:558#include "base/compiler_specific.h"
[email protected]2e4633c2009-07-09 16:58:069#include "base/message_loop.h"
[email protected]7c46ef72009-08-07 20:52:5810#include "base/time.h"
[email protected]2e4633c2009-07-09 16:58:0611#include "chrome/browser/automation/automation_resource_message_filter.h"
[email protected]a8ba6362010-11-10 20:02:2512#include "chrome/common/automation_messages.h"
[email protected]c38831a12011-10-28 12:44:4913#include "content/public/browser/browser_thread.h"
[email protected]9c1662b2012-03-06 15:44:3314#include "content/public/browser/render_view_host.h"
[email protected]60cf2db2012-03-07 21:24:1815#include "content/public/browser/resource_request_info.h"
[email protected]0d282c2e2011-02-24 20:42:5116#include "net/base/host_port_pair.h"
[email protected]2e4633c2009-07-09 16:58:0617#include "net/base/io_buffer.h"
18#include "net/base/net_errors.h"
[email protected]0736d9e2012-11-28 19:50:4019#include "net/base/upload_bytes_element_reader.h"
20#include "net/base/upload_data_stream.h"
21#include "net/base/upload_file_element_reader.h"
[email protected]aa84a7e2012-03-15 21:29:0622#include "net/cookies/cookie_monster.h"
[email protected]ee1a29b02010-05-06 20:42:1223#include "net/http/http_request_headers.h"
[email protected]d0cc35b2011-09-08 12:02:0524#include "net/http/http_response_headers.h"
[email protected]fa0cf1a2009-07-31 00:20:0825#include "net/http/http_util.h"
[email protected]ee4c30d2012-11-07 15:08:4326#include "net/url_request/http_user_agent_settings.h"
[email protected]180aad72012-06-29 19:07:3327#include "net/url_request/url_request.h"
[email protected]5f450e52009-07-28 13:28:1128#include "net/url_request/url_request_context.h"
[email protected]2e4633c2009-07-09 16:58:0629
[email protected]7c46ef72009-08-07 20:52:5830using base::Time;
31using base::TimeDelta;
[email protected]631bb742011-11-02 11:29:3932using content::BrowserThread;
[email protected]60cf2db2012-03-07 21:24:1833using content::ResourceRequestInfo;
[email protected]2e4633c2009-07-09 16:58:0634
[email protected]0736d9e2012-11-28 19:50:4035namespace {
36
[email protected]fa0cf1a2009-07-31 00:20:0837// The list of filtered headers that are removed from requests sent via
38// StartAsync(). These must be lower case.
[email protected]0736d9e2012-11-28 19:50:4039const char* const kFilteredHeaderStrings[] = {
[email protected]fa0cf1a2009-07-31 00:20:0840 "connection",
41 "cookie",
42 "expect",
[email protected]fa0cf1a2009-07-31 00:20:0843 "max-forwards",
44 "proxy-authorization",
[email protected]c10450102011-06-27 09:06:1645 "referer",
[email protected]fa0cf1a2009-07-31 00:20:0846 "te",
47 "upgrade",
48 "via"
49};
50
[email protected]0736d9e2012-11-28 19:50:4051// Creates UploadData from UploadDataStream.
52net::UploadData* CreateUploadData(
53 const net::UploadDataStream* upload_data_stream) {
54 net::UploadData* upload_data = new net::UploadData();
55 const ScopedVector<net::UploadElementReader>& element_readers =
56 upload_data_stream->element_readers();
57 for (size_t i = 0; i < element_readers.size(); ++i) {
58 const net::UploadElementReader* reader = element_readers[i];
59 if (reader->AsBytesReader()) {
60 const net::UploadBytesElementReader* bytes_reader =
61 reader->AsBytesReader();
62 upload_data->AppendBytes(bytes_reader->bytes(), bytes_reader->length());
63 } else if (reader->AsFileReader()) {
64 const net::UploadFileElementReader* file_reader =
65 reader->AsFileReader();
66 upload_data->AppendFileRange(file_reader->path(),
67 file_reader->range_offset(),
68 file_reader->range_length(),
69 file_reader->expected_modification_time());
70 } else {
71 NOTIMPLEMENTED();
72 }
73 }
[email protected]b2d26cfd2012-12-11 10:36:0674 upload_data->set_identifier(upload_data_stream->identifier());
75 upload_data->set_is_chunked(upload_data_stream->is_chunked());
76 upload_data->set_last_chunk_appended(
77 upload_data_stream->last_chunk_appended());
[email protected]0736d9e2012-11-28 19:50:4078 return upload_data;
79}
80
81} // namespace
82
[email protected]2e4633c2009-07-09 16:58:0683int URLRequestAutomationJob::instance_count_ = 0;
[email protected]b377fe852009-11-06 05:57:1784bool URLRequestAutomationJob::is_protocol_factory_registered_ = false;
85
[email protected]6981d9632010-11-30 21:34:0286net::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_http_factory_
[email protected]b377fe852009-11-06 05:57:1787 = NULL;
[email protected]6981d9632010-11-30 21:34:0288net::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_https_factory_
[email protected]b377fe852009-11-06 05:57:1789 = NULL;
[email protected]2e4633c2009-07-09 16:58:0690
[email protected]6981d9632010-11-30 21:34:0291URLRequestAutomationJob::URLRequestAutomationJob(
92 net::URLRequest* request,
[email protected]9f170462012-08-24 01:06:5893 net::NetworkDelegate* network_delegate,
[email protected]ee4c30d2012-11-07 15:08:4394 const net::HttpUserAgentSettings* http_user_agent_settings,
[email protected]6981d9632010-11-30 21:34:0295 int tab,
96 int request_id,
97 AutomationResourceMessageFilter* filter,
98 bool is_pending)
[email protected]9f170462012-08-24 01:06:5899 : net::URLRequestJob(request, network_delegate),
[email protected]ee4c30d2012-11-07 15:08:43100 http_user_agent_settings_(http_user_agent_settings),
[email protected]c33ea142010-07-24 13:13:04101 id_(0),
[email protected]fc6fb7fb2009-11-07 02:35:04102 tab_(tab),
103 message_filter_(filter),
104 pending_buf_size_(0),
[email protected]dda7d9c2009-11-11 23:01:47105 redirect_status_(0),
[email protected]18290eb2010-01-30 00:47:06106 request_id_(request_id),
[email protected]4630e5a2010-12-03 06:16:55107 is_pending_(is_pending),
[email protected]7335ab02012-08-30 22:30:42108 upload_size_(0),
[email protected]9c009092013-05-01 03:14:09109 weak_factory_(this) {
[email protected]5fb40dc2010-10-22 20:35:27110 DVLOG(1) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
[email protected]dda7d9c2009-11-11 23:01:47111 DCHECK(message_filter_ != NULL);
112
113 if (message_filter_) {
114 id_ = message_filter_->NewAutomationRequestId();
115 DCHECK_NE(id_, 0);
116 }
[email protected]2e4633c2009-07-09 16:58:06117}
118
119URLRequestAutomationJob::~URLRequestAutomationJob() {
[email protected]5fb40dc2010-10-22 20:35:27120 DVLOG(1) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
[email protected]2e4633c2009-07-09 16:58:06121 Cleanup();
122}
123
[email protected]8c6517e52011-10-17 01:20:36124void URLRequestAutomationJob::EnsureProtocolFactoryRegistered() {
[email protected]e0d586c2010-10-06 03:57:24125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]b377fe852009-11-06 05:57:17126
127 if (!is_protocol_factory_registered_) {
128 old_http_factory_ =
[email protected]e3539402011-07-19 09:31:08129 net::URLRequest::Deprecated::RegisterProtocolFactory(
[email protected]6981d9632010-11-30 21:34:02130 "http", &URLRequestAutomationJob::Factory);
[email protected]b377fe852009-11-06 05:57:17131 old_https_factory_ =
[email protected]e3539402011-07-19 09:31:08132 net::URLRequest::Deprecated::RegisterProtocolFactory(
[email protected]6981d9632010-11-30 21:34:02133 "https", &URLRequestAutomationJob::Factory);
[email protected]b377fe852009-11-06 05:57:17134 is_protocol_factory_registered_ = true;
135 }
[email protected]b377fe852009-11-06 05:57:17136}
137
[email protected]9acd869e2010-12-11 10:18:59138net::URLRequestJob* URLRequestAutomationJob::Factory(
139 net::URLRequest* request,
[email protected]9f170462012-08-24 01:06:58140 net::NetworkDelegate* network_delegate,
[email protected]9acd869e2010-12-11 10:18:59141 const std::string& scheme) {
[email protected]b377fe852009-11-06 05:57:17142 bool scheme_is_http = request->url().SchemeIs("http");
143 bool scheme_is_https = request->url().SchemeIs("https");
144
145 // Returning null here just means that the built-in handler will be used.
146 if (scheme_is_http || scheme_is_https) {
[email protected]60cf2db2012-03-07 21:24:18147 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
148 if (info) {
149 int child_id = info->GetChildID();
150 int route_id = info->GetRouteID();
[email protected]b377fe852009-11-06 05:57:17151 AutomationResourceMessageFilter::AutomationDetails details;
152 if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
[email protected]2799c02a2009-11-07 15:39:55153 child_id, route_id, &details)) {
[email protected]9f170462012-08-24 01:06:58154 URLRequestAutomationJob* job = new URLRequestAutomationJob(
155 request, network_delegate,
[email protected]ee4c30d2012-11-07 15:08:43156 request->context()->http_user_agent_settings(),
[email protected]60cf2db2012-03-07 21:24:18157 details.tab_handle, info->GetRequestID(), details.filter,
[email protected]18290eb2010-01-30 00:47:06158 details.is_pending_render_view);
[email protected]b377fe852009-11-06 05:57:17159 return job;
160 }
161 }
162
163 if (scheme_is_http && old_http_factory_)
[email protected]9f170462012-08-24 01:06:58164 return old_http_factory_(request, network_delegate, scheme);
[email protected]b377fe852009-11-06 05:57:17165 else if (scheme_is_https && old_https_factory_)
[email protected]9f170462012-08-24 01:06:58166 return old_https_factory_(request, network_delegate, scheme);
[email protected]b377fe852009-11-06 05:57:17167 }
168 return NULL;
[email protected]2e4633c2009-07-09 16:58:06169}
170
[email protected]9acd869e2010-12-11 10:18:59171// net::URLRequestJob Implementation.
[email protected]2e4633c2009-07-09 16:58:06172void URLRequestAutomationJob::Start() {
[email protected]18290eb2010-01-30 00:47:06173 if (!is_pending()) {
174 // Start reading asynchronously so that all error reporting and data
175 // callbacks happen as they would for network requests.
[email protected]4630e5a2010-12-03 06:16:55176 MessageLoop::current()->PostTask(
177 FROM_HERE,
[email protected]8c6517e52011-10-17 01:20:36178 base::Bind(&URLRequestAutomationJob::StartAsync,
179 weak_factory_.GetWeakPtr()));
[email protected]18290eb2010-01-30 00:47:06180 } else {
181 // If this is a pending job, then register it immediately with the message
182 // filter so it can be serviced later when we receive a request from the
183 // external host to connect to the corresponding external tab.
184 message_filter_->RegisterRequest(this);
185 }
[email protected]2e4633c2009-07-09 16:58:06186}
187
188void URLRequestAutomationJob::Kill() {
[email protected]8fdf93932010-02-15 00:47:25189 if (message_filter_.get()) {
190 if (!is_pending()) {
[email protected]f5494d42010-12-23 22:15:34191 message_filter_->Send(new AutomationMsg_RequestEnd(tab_, id_,
[email protected]f90bf0d92011-01-13 02:12:44192 net::URLRequestStatus(net::URLRequestStatus::CANCELED,
193 net::ERR_ABORTED)));
[email protected]18290eb2010-01-30 00:47:06194 }
[email protected]b0a7fc62009-07-28 22:04:22195 }
[email protected]2e4633c2009-07-09 16:58:06196 DisconnectFromMessageFilter();
[email protected]9acd869e2010-12-11 10:18:59197 net::URLRequestJob::Kill();
[email protected]2e4633c2009-07-09 16:58:06198}
199
200bool URLRequestAutomationJob::ReadRawData(
201 net::IOBuffer* buf, int buf_size, int* bytes_read) {
[email protected]5fb40dc2010-10-22 20:35:27202 DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
203 << " - read pending: " << buf_size;
[email protected]18290eb2010-01-30 00:47:06204
205 // We should not receive a read request for a pending job.
206 DCHECK(!is_pending());
207
[email protected]2e4633c2009-07-09 16:58:06208 pending_buf_ = buf;
209 pending_buf_size_ = buf_size;
210
[email protected]3927f812010-02-10 06:41:02211 if (message_filter_) {
[email protected]f5494d42010-12-23 22:15:34212 message_filter_->Send(new AutomationMsg_RequestRead(tab_, id_, buf_size));
[email protected]f90bf0d92011-01-13 02:12:44213 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
[email protected]3927f812010-02-10 06:41:02214 } else {
[email protected]4630e5a2010-12-03 06:16:55215 MessageLoop::current()->PostTask(
216 FROM_HERE,
[email protected]8c6517e52011-10-17 01:20:36217 base::Bind(&URLRequestAutomationJob::NotifyJobCompletionTask,
218 weak_factory_.GetWeakPtr()));
[email protected]3927f812010-02-10 06:41:02219 }
[email protected]2e4633c2009-07-09 16:58:06220 return false;
221}
222
223bool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
224 if (!mime_type_.empty()) {
225 *mime_type = mime_type_;
226 } else if (headers_) {
227 headers_->GetMimeType(mime_type);
228 }
229
230 return (!mime_type->empty());
231}
232
233bool URLRequestAutomationJob::GetCharset(std::string* charset) {
234 if (headers_)
235 return headers_->GetCharset(charset);
236 return false;
237}
238
239void URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
240 if (headers_)
241 info->headers = headers_;
242 if (request_->url().SchemeIsSecure()) {
[email protected]7c46ef72009-08-07 20:52:58243 // Make up a fake certificate for this response since we don't have
244 // access to the real SSL info.
245 const char* kCertIssuer = "Chrome Internal";
246 const int kLifetimeDays = 100;
247
248 info->ssl_info.cert =
249 new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
250 kCertIssuer,
251 Time::Now(),
252 Time::Now() +
253 TimeDelta::FromDays(kLifetimeDays));
254 info->ssl_info.cert_status = 0;
[email protected]89af3d92010-10-15 20:31:37255 info->ssl_info.security_bits = -1;
[email protected]2e4633c2009-07-09 16:58:06256 }
257}
258
259int URLRequestAutomationJob::GetResponseCode() const {
260 if (headers_)
261 return headers_->response_code();
262
263 static const int kDefaultResponseCode = 200;
264 return kDefaultResponseCode;
265}
266
267bool URLRequestAutomationJob::IsRedirectResponse(
268 GURL* location, int* http_status_code) {
[email protected]86de13d2009-11-24 01:21:35269 if (!net::HttpResponseHeaders::IsRedirectResponseCode(redirect_status_))
270 return false;
[email protected]2e4633c2009-07-09 16:58:06271
[email protected]86de13d2009-11-24 01:21:35272 *http_status_code = redirect_status_;
273 *location = GURL(redirect_url_);
274 return true;
[email protected]2e4633c2009-07-09 16:58:06275}
276
[email protected]7335ab02012-08-30 22:30:42277net::UploadProgress URLRequestAutomationJob::GetUploadProgress() const {
278 uint64 progress = 0;
[email protected]029226072011-02-08 00:00:16279 if (request_ && request_->status().is_success()) {
280 // We don't support incremental progress notifications in ChromeFrame. When
281 // we receive a response for the POST request from Chromeframe, it means
282 // that the upload is fully complete.
[email protected]7335ab02012-08-30 22:30:42283 progress = upload_size_;
[email protected]029226072011-02-08 00:00:16284 }
[email protected]7335ab02012-08-30 22:30:42285 return net::UploadProgress(progress, upload_size_);
[email protected]029226072011-02-08 00:00:16286}
287
[email protected]0d282c2e2011-02-24 20:42:51288net::HostPortPair URLRequestAutomationJob::GetSocketAddress() const {
289 return socket_address_;
290}
291
[email protected]fc6fb7fb2009-11-07 02:35:04292bool URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message,
293 int* request_id) {
[email protected]2e4633c2009-07-09 16:58:06294 switch (message.type()) {
295 case AutomationMsg_RequestStarted::ID:
296 case AutomationMsg_RequestData::ID:
297 case AutomationMsg_RequestEnd::ID: {
[email protected]ce208f872012-03-07 20:42:56298 PickleIterator iter(message);
[email protected]f5494d42010-12-23 22:15:34299 if (message.ReadInt(&iter, request_id))
[email protected]fc6fb7fb2009-11-07 02:35:04300 return true;
[email protected]2e4633c2009-07-09 16:58:06301 break;
302 }
303 }
304
[email protected]fc6fb7fb2009-11-07 02:35:04305 return false;
[email protected]2e4633c2009-07-09 16:58:06306}
307
308void URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
[email protected]2cf5fd6f2009-12-11 19:21:48309 if (!request_) {
310 NOTREACHED() << __FUNCTION__
311 << ": Unexpected request received for job:"
312 << id();
313 return;
314 }
315
[email protected]c7fd73292011-07-29 16:45:43316 bool deserialize_success = false;
317 IPC_BEGIN_MESSAGE_MAP_EX(URLRequestAutomationJob,
318 message,
319 deserialize_success)
[email protected]2e4633c2009-07-09 16:58:06320 IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
321 IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
322 IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
[email protected]c7fd73292011-07-29 16:45:43323 IPC_END_MESSAGE_MAP_EX()
324
325 if (!deserialize_success) {
326 LOG(ERROR) << "Failed to deserialize IPC message.";
327 }
[email protected]2e4633c2009-07-09 16:58:06328}
329
[email protected]f5494d42010-12-23 22:15:34330void URLRequestAutomationJob::OnRequestStarted(
331 int id, const AutomationURLResponse& response) {
[email protected]5fb40dc2010-10-22 20:35:27332 DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
333 << " - response started.";
[email protected]2e4633c2009-07-09 16:58:06334 set_expected_content_size(response.content_length);
335 mime_type_ = response.mime_type;
336
[email protected]a7659312009-08-12 22:21:10337 redirect_url_ = response.redirect_url;
[email protected]b4cdb69c2009-08-31 23:29:13338 redirect_status_ = response.redirect_status;
339 DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
340 (redirect_status_ >= 300 && redirect_status_ < 400));
[email protected]a7659312009-08-12 22:21:10341
[email protected]5f450e52009-07-28 13:28:11342 if (!response.headers.empty()) {
[email protected]382d276d2009-08-20 23:23:03343 headers_ = new net::HttpResponseHeaders(
344 net::HttpUtil::AssembleRawHeaders(response.headers.data(),
345 response.headers.size()));
[email protected]5f450e52009-07-28 13:28:11346 }
[email protected]0d282c2e2011-02-24 20:42:51347 socket_address_ = response.socket_address;
[email protected]7335ab02012-08-30 22:30:42348 upload_size_ = response.upload_size;
[email protected]2e4633c2009-07-09 16:58:06349 NotifyHeadersComplete();
350}
351
352void URLRequestAutomationJob::OnDataAvailable(
[email protected]f5494d42010-12-23 22:15:34353 int id, const std::string& bytes) {
[email protected]5fb40dc2010-10-22 20:35:27354 DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
355 << " - data available, Size: " << bytes.size();
[email protected]2e4633c2009-07-09 16:58:06356 DCHECK(!bytes.empty());
357
358 // The request completed, and we have all the data.
359 // Clear any IO pending status.
[email protected]f90bf0d92011-01-13 02:12:44360 SetStatus(net::URLRequestStatus());
[email protected]2e4633c2009-07-09 16:58:06361
362 if (pending_buf_ && pending_buf_->data()) {
363 DCHECK_GE(pending_buf_size_, bytes.size());
364 const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
365 memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);
366
367 pending_buf_ = NULL;
368 pending_buf_size_ = 0;
369
370 NotifyReadComplete(bytes_to_copy);
[email protected]3927f812010-02-10 06:41:02371 } else {
372 NOTREACHED() << "Received unexpected data of length:" << bytes.size();
[email protected]2e4633c2009-07-09 16:58:06373 }
374}
375
376void URLRequestAutomationJob::OnRequestEnd(
[email protected]f90bf0d92011-01-13 02:12:44377 int id, const net::URLRequestStatus& status) {
[email protected]0c814762009-09-17 22:56:00378#ifndef NDEBUG
379 std::string url;
380 if (request_)
381 url = request_->url().spec();
[email protected]5fb40dc2010-10-22 20:35:27382 DVLOG(1) << "URLRequestAutomationJob: " << url << " - request end. Status: "
383 << status.status();
[email protected]0c814762009-09-17 22:56:00384#endif
[email protected]2e4633c2009-07-09 16:58:06385
[email protected]fab404202009-09-10 17:19:06386 // TODO(tommi): When we hit certificate errors, notify the delegate via
387 // OnSSLCertificateError(). Right now we don't have the certificate
388 // so we don't. We could possibly call OnSSLCertificateError with a NULL
389 // certificate, but I'm not sure if all implementations expect it.
[email protected]f90bf0d92011-01-13 02:12:44390 // if (status.status() == net::URLRequestStatus::FAILED &&
[email protected]d0cc35b2011-09-08 12:02:05391 // net::IsCertificateError(status.error()) && request_->delegate()) {
392 // request_->delegate()->OnSSLCertificateError(request_, status.error());
[email protected]fab404202009-09-10 17:19:06393 // }
394
[email protected]2e4633c2009-07-09 16:58:06395 DisconnectFromMessageFilter();
[email protected]eb834fb2009-10-23 16:09:41396 // NotifyDone may have been called on the job if the original request was
397 // redirected.
[email protected]3927f812010-02-10 06:41:02398 if (!is_done()) {
399 // We can complete the job if we have a valid response or a pending read.
400 // An end request can be received in the following cases
401 // 1. We failed to connect to the server, in which case we did not receive
402 // a valid response.
403 // 2. In response to a read request.
[email protected]fafc7502011-04-27 04:37:56404 if (!has_response_started()) {
405 NotifyStartError(status);
406 } else if (pending_buf_) {
[email protected]732adca12011-05-11 02:26:40407 pending_buf_ = NULL;
408 pending_buf_size_ = 0;
[email protected]3927f812010-02-10 06:41:02409 NotifyDone(status);
[email protected]732adca12011-05-11 02:26:40410 NotifyReadComplete(0);
[email protected]3927f812010-02-10 06:41:02411 } else {
412 // Wait for the http stack to issue a Read request where we will notify
413 // that the job has completed.
414 request_status_ = status;
[email protected]3927f812010-02-10 06:41:02415 }
416 }
[email protected]732adca12011-05-11 02:26:40417 // Note
418 // The job could have been destroyed above. Please don't attempt to access
419 // member variables here.
[email protected]2e4633c2009-07-09 16:58:06420}
421
422void URLRequestAutomationJob::Cleanup() {
423 headers_ = NULL;
424 mime_type_.erase();
425
426 id_ = 0;
427 tab_ = 0;
428
[email protected]cbfd6e112011-02-17 22:09:18429 DCHECK(!message_filter_);
[email protected]2e4633c2009-07-09 16:58:06430 DisconnectFromMessageFilter();
431
432 pending_buf_ = NULL;
433 pending_buf_size_ = 0;
434}
435
436void URLRequestAutomationJob::StartAsync() {
[email protected]5fb40dc2010-10-22 20:35:27437 DVLOG(1) << "URLRequestAutomationJob: start request: "
438 << (request_ ? request_->url().spec() : "NULL request");
[email protected]2e4633c2009-07-09 16:58:06439
440 // If the job is cancelled before we got a chance to start it
441 // we have nothing much to do here.
442 if (is_done())
443 return;
444
[email protected]18290eb2010-01-30 00:47:06445 // We should not receive a Start request for a pending job.
446 DCHECK(!is_pending());
447
[email protected]2e4633c2009-07-09 16:58:06448 if (!request_) {
[email protected]f90bf0d92011-01-13 02:12:44449 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
450 net::ERR_FAILED));
[email protected]2e4633c2009-07-09 16:58:06451 return;
452 }
453
454 // Register this request with automation message filter.
455 message_filter_->RegisterRequest(this);
456
[email protected]fa0cf1a2009-07-31 00:20:08457 // Strip unwanted headers.
[email protected]ee1a29b02010-05-06 20:42:12458 net::HttpRequestHeaders new_request_headers;
459 new_request_headers.MergeFrom(request_->extra_request_headers());
460 for (size_t i = 0; i < arraysize(kFilteredHeaderStrings); ++i)
461 new_request_headers.RemoveHeader(kFilteredHeaderStrings[i]);
[email protected]fa0cf1a2009-07-31 00:20:08462
[email protected]84f05432013-03-15 01:00:12463 // Only add default Accept-Language if the request didn't have it specified.
[email protected]81293f482012-08-13 19:35:45464 if (!new_request_headers.HasHeader(
465 net::HttpRequestHeaders::kAcceptLanguage) &&
[email protected]ee4c30d2012-11-07 15:08:43466 http_user_agent_settings_) {
467 std::string accept_language =
468 http_user_agent_settings_->GetAcceptLanguage();
469 if (!accept_language.empty()) {
470 new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage,
471 accept_language);
472 }
[email protected]81293f482012-08-13 19:35:45473 }
[email protected]eb834fb2009-10-23 16:09:41474
[email protected]99ecf6e2013-04-10 22:46:13475 // URLRequest::SetReferrer() ensures that we do not send username and
476 // password fields in the referrer.
477 GURL referrer(request_->referrer());
[email protected]fab404202009-09-10 17:19:06478
479 // The referrer header must be suppressed if the preceding URL was
[email protected]e600c822009-08-31 16:57:08480 // a secure one and the new one is not.
481 if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
[email protected]5fb40dc2010-10-22 20:35:27482 DVLOG(1) << "Suppressing referrer header since going from secure to "
483 "non-secure";
[email protected]fab404202009-09-10 17:19:06484 referrer = GURL();
[email protected]e600c822009-08-31 16:57:08485 }
[email protected]e600c822009-08-31 16:57:08486
[email protected]60633402010-10-01 16:33:37487 // Get the resource type (main_frame/script/image/stylesheet etc.
[email protected]60cf2db2012-03-07 21:24:18488 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
[email protected]60633402010-10-01 16:33:37489 ResourceType::Type resource_type = ResourceType::MAIN_FRAME;
[email protected]60cf2db2012-03-07 21:24:18490 if (info) {
491 resource_type = info->GetResourceType();
[email protected]60633402010-10-01 16:33:37492 }
493
[email protected]0736d9e2012-11-28 19:50:40494 // Construct UploadData from UploadDataStream.
495 scoped_refptr<net::UploadData> upload_data;
496 if (request_->get_upload())
497 upload_data = CreateUploadData(request_->get_upload());
498
[email protected]2e4633c2009-07-09 16:58:06499 // Ask automation to start this request.
[email protected]3b3ec7212011-10-21 17:35:08500 AutomationURLRequest automation_request;
501 automation_request.url = request_->url().spec();
502 automation_request.method = request_->method();
503 automation_request.referrer = referrer.spec();
504 automation_request.extra_request_headers = new_request_headers.ToString();
[email protected]0736d9e2012-11-28 19:50:40505 automation_request.upload_data = upload_data;
[email protected]3b3ec7212011-10-21 17:35:08506 automation_request.resource_type = resource_type;
507 automation_request.load_flags = request_->load_flags();
[email protected]2e4633c2009-07-09 16:58:06508
509 DCHECK(message_filter_);
[email protected]f5494d42010-12-23 22:15:34510 message_filter_->Send(new AutomationMsg_RequestStart(
511 tab_, id_, automation_request));
[email protected]2e4633c2009-07-09 16:58:06512}
513
514void URLRequestAutomationJob::DisconnectFromMessageFilter() {
515 if (message_filter_) {
516 message_filter_->UnRegisterRequest(this);
517 message_filter_ = NULL;
518 }
519}
[email protected]aeb9efc2010-01-08 05:55:50520
[email protected]18290eb2010-01-30 00:47:06521void URLRequestAutomationJob::StartPendingJob(
522 int new_tab_handle,
523 AutomationResourceMessageFilter* new_filter) {
524 DCHECK(new_filter != NULL);
525 tab_ = new_tab_handle;
526 message_filter_ = new_filter;
527 is_pending_ = false;
528 Start();
529}
530
[email protected]3927f812010-02-10 06:41:02531void URLRequestAutomationJob::NotifyJobCompletionTask() {
532 if (!is_done()) {
533 NotifyDone(request_status_);
534 }
535 // Reset any pending reads.
536 if (pending_buf_) {
537 pending_buf_ = NULL;
538 pending_buf_size_ = 0;
539 NotifyReadComplete(0);
540 }
541}