172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/url_request_automation_job.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/compiler_specific.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/automation_resource_message_filter.h"
114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/automation_messages.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_monster.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/base/host_port_pair.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/io_buffer.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_response_headers.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_request_headers.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_util.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The list of filtered headers that are removed from requests sent via
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// StartAsync(). These must be lower case.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* const kFilteredHeaderStrings[] = {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "connection",
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "cookie",
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "expect",
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "max-forwards",
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "proxy-authorization",
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "te",
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "upgrade",
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "via"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint URLRequestAutomationJob::instance_count_ = 0;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::is_protocol_factory_registered_ = false;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_http_factory_
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    = NULL;
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_https_factory_
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    = NULL;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenURLRequestAutomationJob::URLRequestAutomationJob(
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    net::URLRequest* request,
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int tab,
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int request_id,
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    AutomationResourceMessageFilter* filter,
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bool is_pending)
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    : net::URLRequestJob(request),
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      id_(0),
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_(tab),
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      message_filter_(filter),
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pending_buf_size_(0),
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      redirect_status_(0),
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_id_(request_id),
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      is_pending_(is_pending),
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(message_filter_ != NULL);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (message_filter_) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    id_ = message_filter_->NewAutomationRequestId();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_NE(id_, 0);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochURLRequestAutomationJob::~URLRequestAutomationJob() {
74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Cleanup();
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::EnsureProtocolFactoryRegistered() {
79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_protocol_factory_registered_) {
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    old_http_factory_ =
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        net::URLRequest::RegisterProtocolFactory(
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            "http", &URLRequestAutomationJob::Factory);
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    old_https_factory_ =
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        net::URLRequest::RegisterProtocolFactory(
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            "https", &URLRequestAutomationJob::Factory);
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    is_protocol_factory_registered_ = true;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::URLRequestJob* URLRequestAutomationJob::Factory(
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    net::URLRequest* request,
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const std::string& scheme) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool scheme_is_http = request->url().SchemeIs("http");
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool scheme_is_https = request->url().SchemeIs("https");
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returning null here just means that the built-in handler will be used.
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (scheme_is_http || scheme_is_https) {
102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ResourceDispatcherHostRequestInfo* request_info = NULL;
103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (request->GetUserData(NULL))
104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      request_info = ResourceDispatcherHost::InfoForRequest(request);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (request_info) {
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int child_id = request_info->child_id();
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int route_id = request_info->route_id();
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AutomationResourceMessageFilter::AutomationDetails details;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              child_id, route_id, &details)) {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            details.tab_handle, request_info->request_id(), details.filter,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            details.is_pending_render_view);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return job;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (scheme_is_http && old_http_factory_)
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return old_http_factory_(request, scheme);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else if (scheme_is_https && old_https_factory_)
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return old_https_factory_(request, scheme);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// net::URLRequestJob Implementation.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::Start() {
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_pending()) {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Start reading asynchronously so that all error reporting and data
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // callbacks happen as they would for network requests.
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    MessageLoop::current()->PostTask(
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        FROM_HERE,
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        method_factory_.NewRunnableMethod(
13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            &URLRequestAutomationJob::StartAsync));
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If this is a pending job, then register it immediately with the message
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // filter so it can be serviced later when we receive a request from the
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // external host to connect to the corresponding external tab.
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_filter_->RegisterRequest(this);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::Kill() {
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (message_filter_.get()) {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!is_pending()) {
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      message_filter_->Send(new AutomationMsg_RequestEnd(tab_, id_,
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          net::URLRequestStatus(net::URLRequestStatus::CANCELED,
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                net::ERR_ABORTED)));
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DisconnectFromMessageFilter();
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::URLRequestJob::Kill();
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::ReadRawData(
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::IOBuffer* buf, int buf_size, int* bytes_read) {
157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch           << " - read pending: " << buf_size;
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We should not receive a read request for a pending job.
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!is_pending());
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_buf_ = buf;
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_buf_size_ = buf_size;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (message_filter_) {
16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    message_filter_->Send(new AutomationMsg_RequestRead(tab_, id_, buf_size));
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    MessageLoop::current()->PostTask(
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        FROM_HERE,
17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        method_factory_.NewRunnableMethod(
17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            &URLRequestAutomationJob::NotifyJobCompletionTask));
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!mime_type_.empty()) {
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *mime_type = mime_type_;
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (headers_) {
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    headers_->GetMimeType(mime_type);
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return (!mime_type->empty());
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::GetCharset(std::string* charset) {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (headers_)
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return headers_->GetCharset(charset);
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (headers_)
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->headers = headers_;
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (request_->url().SchemeIsSecure()) {
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make up a fake certificate for this response since we don't have
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // access to the real SSL info.
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char* kCertIssuer = "Chrome Internal";
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int kLifetimeDays = 100;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->ssl_info.cert =
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 kCertIssuer,
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 Time::Now(),
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 Time::Now() +
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     TimeDelta::FromDays(kLifetimeDays));
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->ssl_info.cert_status = 0;
210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    info->ssl_info.security_bits = -1;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint URLRequestAutomationJob::GetResponseCode() const {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (headers_)
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return headers_->response_code();
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kDefaultResponseCode = 200;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return kDefaultResponseCode;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::IsRedirectResponse(
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL* location, int* http_status_code) {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!net::HttpResponseHeaders::IsRedirectResponseCode(redirect_status_))
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *http_status_code = redirect_status_;
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *location = GURL(redirect_url_);
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenuint64 URLRequestAutomationJob::GetUploadProgress() const {
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (request_ && request_->status().is_success()) {
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // We don't support incremental progress notifications in ChromeFrame. When
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // we receive a response for the POST request from Chromeframe, it means
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // that the upload is fully complete.
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ResourceDispatcherHostRequestInfo* request_info =
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        ResourceDispatcherHost::InfoForRequest(request_);
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (request_info) {
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return request_info->upload_size();
24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return 0;
24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennet::HostPortPair URLRequestAutomationJob::GetSocketAddress() const {
247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return socket_address_;
248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message,
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               int* request_id) {
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (message.type()) {
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case AutomationMsg_RequestStarted::ID:
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case AutomationMsg_RequestData::ID:
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case AutomationMsg_RequestEnd::ID: {
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      void* iter = NULL;
25721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (message.ReadInt(&iter, request_id))
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return true;
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!request_) {
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << __FUNCTION__
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 << ": Unexpected request received for job:"
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 << id();
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IPC_BEGIN_MESSAGE_MAP(URLRequestAutomationJob, message)
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IPC_END_MESSAGE_MAP()
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid URLRequestAutomationJob::OnRequestStarted(
28221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int id, const AutomationURLResponse& response) {
283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch           << " - response started.";
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_expected_content_size(response.content_length);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  mime_type_ = response.mime_type;
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  redirect_url_ = response.redirect_url;
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  redirect_status_ = response.redirect_status;
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         (redirect_status_ >= 300 && redirect_status_ < 400));
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!response.headers.empty()) {
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    headers_ = new net::HttpResponseHeaders(
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        net::HttpUtil::AssembleRawHeaders(response.headers.data(),
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          response.headers.size()));
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  socket_address_ = response.socket_address;
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotifyHeadersComplete();
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::OnDataAvailable(
30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int id, const std::string& bytes) {
304513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch           << " - data available, Size: " << bytes.size();
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!bytes.empty());
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The request completed, and we have all the data.
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clear any IO pending status.
31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  SetStatus(net::URLRequestStatus());
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pending_buf_ && pending_buf_->data()) {
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_GE(pending_buf_size_, bytes.size());
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_buf_ = NULL;
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_buf_size_ = 0;
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyReadComplete(bytes_to_copy);
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "Received unexpected data of length:" << bytes.size();
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::OnRequestEnd(
32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    int id, const net::URLRequestStatus& status) {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NDEBUG
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string url;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (request_)
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url = request_->url().spec();
332513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob: " << url << " - request end. Status: "
333513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch           << status.status();
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(tommi): When we hit certificate errors, notify the delegate via
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // OnSSLCertificateError().  Right now we don't have the certificate
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so we don't.  We could possibly call OnSSLCertificateError with a NULL
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // certificate, but I'm not sure if all implementations expect it.
34072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // if (status.status() == net::URLRequestStatus::FAILED &&
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    net::IsCertificateError(status.os_error()) && request_->delegate()) {
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //  request_->delegate()->OnSSLCertificateError(request_, status.os_error());
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // }
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DisconnectFromMessageFilter();
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NotifyDone may have been called on the job if the original request was
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // redirected.
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_done()) {
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We can complete the job if we have a valid response or a pending read.
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // An end request can be received in the following cases
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 1. We failed to connect to the server, in which case we did not receive
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    a valid response.
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 2. In response to a read request.
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!has_response_started() || pending_buf_) {
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotifyDone(status);
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Wait for the http stack to issue a Read request where we will notify
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // that the job has completed.
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_status_ = status;
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset any pending reads.
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pending_buf_) {
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_buf_ = NULL;
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_buf_size_ = 0;
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyReadComplete(0);
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::Cleanup() {
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  headers_ = NULL;
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  mime_type_.erase();
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  id_ = 0;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_ = 0;
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(!message_filter_);
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DisconnectFromMessageFilter();
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_buf_ = NULL;
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_buf_size_ = 0;
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::StartAsync() {
387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "URLRequestAutomationJob: start request: "
388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch           << (request_ ? request_->url().spec() : "NULL request");
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the job is cancelled before we got a chance to start it
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we have nothing much to do here.
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_done())
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We should not receive a Start request for a pending job.
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!is_pending());
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!request_) {
39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                           net::ERR_FAILED));
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Register this request with automation message filter.
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  message_filter_->RegisterRequest(this);
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Strip unwanted headers.
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HttpRequestHeaders new_request_headers;
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  new_request_headers.MergeFrom(request_->extra_request_headers());
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < arraysize(kFilteredHeaderStrings); ++i)
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_request_headers.RemoveHeader(kFilteredHeaderStrings[i]);
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (request_->context()) {
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Only add default Accept-Language and Accept-Charset if the request
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // didn't have them specified.
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!new_request_headers.HasHeader(
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        net::HttpRequestHeaders::kAcceptLanguage) &&
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        !request_->context()->accept_language().empty()) {
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage,
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    request_->context()->accept_language());
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!new_request_headers.HasHeader(
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        net::HttpRequestHeaders::kAcceptCharset) &&
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        !request_->context()->accept_charset().empty()) {
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptCharset,
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    request_->context()->accept_charset());
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ensure that we do not send username and password fields in the referrer.
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL referrer(request_->GetSanitizedReferrer());
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The referrer header must be suppressed if the preceding URL was
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a secure one and the new one is not.
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
436513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    DVLOG(1) << "Suppressing referrer header since going from secure to "
437513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                "non-secure";
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    referrer = GURL();
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Get the resource type (main_frame/script/image/stylesheet etc.
442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ResourceDispatcherHostRequestInfo* request_info =
443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ResourceDispatcherHost::InfoForRequest(request_);
444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ResourceType::Type resource_type = ResourceType::MAIN_FRAME;
445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (request_info) {
446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    resource_type = request_info->resource_type();
447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ask automation to start this request.
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  AutomationURLRequest automation_request(
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      request_->url().spec(),
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      request_->method(),
45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      referrer.spec(),
45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      new_request_headers.ToString(),
45521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      request_->get_upload(),
45621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      resource_type,
45721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      request_->load_flags());
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(message_filter_);
46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  message_filter_->Send(new AutomationMsg_RequestStart(
46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      tab_, id_, automation_request));
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::DisconnectFromMessageFilter() {
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (message_filter_) {
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_filter_->UnRegisterRequest(this);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_filter_ = NULL;
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::StartPendingJob(
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int new_tab_handle,
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutomationResourceMessageFilter* new_filter) {
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(new_filter != NULL);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_ = new_tab_handle;
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  message_filter_ = new_filter;
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_pending_ = false;
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Start();
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestAutomationJob::NotifyJobCompletionTask() {
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_done()) {
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyDone(request_status_);
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset any pending reads.
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pending_buf_) {
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_buf_ = NULL;
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_buf_size_ = 0;
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyReadComplete(0);
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
492