15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/url_request_automation_job.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_resource_message_filter.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_file_element_reader.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_request_headers.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/http_user_agent_settings.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ResourceRequestInfo;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The list of filtered headers that are removed from requests sent via
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// StartAsync(). These must be lower case.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* const kFilteredHeaderStrings[] = {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "connection",
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "cookie",
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "expect",
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "max-forwards",
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "proxy-authorization",
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "referer",
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "te",
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "upgrade",
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "via"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Creates UploadData from UploadDataStream.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::UploadData* CreateUploadData(
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const net::UploadDataStream* upload_data_stream) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::UploadData* upload_data = new net::UploadData();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ScopedVector<net::UploadElementReader>& element_readers =
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      upload_data_stream->element_readers();
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < element_readers.size(); ++i) {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const net::UploadElementReader* reader = element_readers[i];
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (reader->AsBytesReader()) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const net::UploadBytesElementReader* bytes_reader =
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reader->AsBytesReader();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      upload_data->AppendBytes(bytes_reader->bytes(), bytes_reader->length());
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (reader->AsFileReader()) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const net::UploadFileElementReader* file_reader =
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reader->AsFileReader();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      upload_data->AppendFileRange(file_reader->path(),
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   file_reader->range_offset(),
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   file_reader->range_length(),
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   file_reader->expected_modification_time());
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTIMPLEMENTED();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  upload_data->set_identifier(upload_data_stream->identifier());
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  upload_data->set_is_chunked(upload_data_stream->is_chunked());
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  upload_data->set_last_chunk_appended(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      upload_data_stream->last_chunk_appended());
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return upload_data;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestAutomationJob::instance_count_ = 0;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestAutomationJob::is_protocol_factory_registered_ = false;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_http_factory_
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    = NULL;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequest::ProtocolFactory* URLRequestAutomationJob::old_https_factory_
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    = NULL;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestAutomationJob::URLRequestAutomationJob(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::NetworkDelegate* network_delegate,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HttpUserAgentSettings* http_user_agent_settings,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tab,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationResourceMessageFilter* filter,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_pending)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : net::URLRequestJob(request, network_delegate),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_user_agent_settings_(http_user_agent_settings),
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id_(0),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_(tab),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_filter_(filter),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_buf_size_(0),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      redirect_status_(0),
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_id_(request_id),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_pending_(is_pending),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      upload_size_(0),
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(message_filter_.get() != NULL);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (message_filter_.get()) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id_ = message_filter_->NewAutomationRequestId();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(id_, 0);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestAutomationJob::~URLRequestAutomationJob() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cleanup();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::EnsureProtocolFactoryRegistered() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_protocol_factory_registered_) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_http_factory_ =
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::URLRequest::Deprecated::RegisterProtocolFactory(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "http", &URLRequestAutomationJob::Factory);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_https_factory_ =
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::URLRequest::Deprecated::RegisterProtocolFactory(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "https", &URLRequestAutomationJob::Factory);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_protocol_factory_registered_ = true;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJob* URLRequestAutomationJob::Factory(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::NetworkDelegate* network_delegate,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& scheme) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool scheme_is_http = request->url().SchemeIs("http");
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool scheme_is_https = request->url().SchemeIs("https");
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returning null here just means that the built-in handler will be used.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (scheme_is_http || scheme_is_https) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int child_id = info->GetChildID();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int route_id = info->GetRouteID();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AutomationResourceMessageFilter::AutomationDetails details;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              child_id, route_id, &details)) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        URLRequestAutomationJob* job = new URLRequestAutomationJob(
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            request,
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            network_delegate,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request->context()->http_user_agent_settings(),
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            details.tab_handle,
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            info->GetRequestID(),
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            details.filter.get(),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            details.is_pending_render_view);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return job;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (scheme_is_http && old_http_factory_)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return old_http_factory_(request, network_delegate, scheme);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (scheme_is_https && old_https_factory_)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return old_https_factory_(request, network_delegate, scheme);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// net::URLRequestJob Implementation.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::Start() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_pending()) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start reading asynchronously so that all error reporting and data
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // callbacks happen as they would for network requests.
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLRequestAutomationJob::StartAsync,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If this is a pending job, then register it immediately with the message
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // filter so it can be serviced later when we receive a request from the
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // external host to connect to the corresponding external tab.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_filter_->RegisterRequest(this);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::Kill() {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message_filter_.get()) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_pending()) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_filter_->Send(new AutomationMsg_RequestEnd(tab_, id_,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::URLRequestStatus(net::URLRequestStatus::CANCELED,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                net::ERR_ABORTED)));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisconnectFromMessageFilter();
200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  receive_headers_end_ = base::TimeTicks();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestJob::Kill();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestAutomationJob::ReadRawData(
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::IOBuffer* buf, int buf_size, int* bytes_read) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " - read pending: " << buf_size;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not receive a read request for a pending job.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_buf_ = buf;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_buf_size_ = buf_size;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (message_filter_.get()) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_filter_->Send(new AutomationMsg_RequestRead(tab_, id_, buf_size));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&URLRequestAutomationJob::NotifyJobCompletionTask,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mime_type_.empty()) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mime_type = mime_type_;
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (headers_.get()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers_->GetMimeType(mime_type);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (!mime_type->empty());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestAutomationJob::GetCharset(std::string* charset) {
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (headers_.get())
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return headers_->GetCharset(charset);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (headers_.get())
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->headers = headers_;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_->url().SchemeIsSecure()) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make up a fake certificate for this response since we don't have
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // access to the real SSL info.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* kCertIssuer = "Chrome Internal";
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kLifetimeDays = 100;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->ssl_info.cert =
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kCertIssuer,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 Time::Now(),
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 Time::Now() +
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     TimeDelta::FromDays(kLifetimeDays));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->ssl_info.cert_status = 0;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->ssl_info.security_bits = -1;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void URLRequestAutomationJob::GetLoadTimingInfo(
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    net::LoadTimingInfo* load_timing_info) const {
265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!receive_headers_end_.is_null()) {
266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    load_timing_info->send_start = request_start_;
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // The send ended some time ago, but that information is not available on
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // this side of the automation channel. Consider the send to have ended at
269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // the same time we received the response headers.
270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    load_timing_info->send_end = receive_headers_end_;
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    load_timing_info->receive_headers_end = receive_headers_end_;
272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestAutomationJob::GetResponseCode() const {
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (headers_.get())
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return headers_->response_code();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDefaultResponseCode = 200;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kDefaultResponseCode;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestAutomationJob::IsRedirectResponse(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL* location, int* http_status_code) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!net::HttpResponseHeaders::IsRedirectResponseCode(redirect_status_))
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *http_status_code = redirect_status_;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *location = GURL(redirect_url_);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::UploadProgress URLRequestAutomationJob::GetUploadProgress() const {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 progress = 0;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_ && request_->status().is_success()) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't support incremental progress notifications in ChromeFrame. When
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we receive a response for the POST request from Chromeframe, it means
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that the upload is fully complete.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    progress = upload_size_;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return net::UploadProgress(progress, upload_size_);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::HostPortPair URLRequestAutomationJob::GetSocketAddress() const {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return socket_address_;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int* request_id) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (message.type()) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AutomationMsg_RequestStarted::ID:
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AutomationMsg_RequestData::ID:
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AutomationMsg_RequestEnd::ID: {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PickleIterator iter(message);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (message.ReadInt(&iter, request_id))
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request_) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << __FUNCTION__
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << ": Unexpected request received for job:"
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << id();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deserialize_success = false;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(URLRequestAutomationJob,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           message,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           deserialize_success)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP_EX()
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!deserialize_success) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to deserialize IPC message.";
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::OnRequestStarted(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id, const AutomationURLResponse& response) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " - response started.";
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_expected_content_size(response.content_length);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mime_type_ = response.mime_type;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  receive_headers_end_ = base::TimeTicks::Now();
354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_url_ = response.redirect_url;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  redirect_status_ = response.redirect_status;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (redirect_status_ >= 300 && redirect_status_ < 400));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!response.headers.empty()) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers_ = new net::HttpResponseHeaders(
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpUtil::AssembleRawHeaders(response.headers.data(),
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          response.headers.size()));
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socket_address_ = response.socket_address;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_size_ = response.upload_size;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyHeadersComplete();
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::OnDataAvailable(
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id, const std::string& bytes) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob: " << request_->url().spec()
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << " - data available, Size: " << bytes.size();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!bytes.empty());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The request completed, and we have all the data.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear any IO pending status.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetStatus(net::URLRequestStatus());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (pending_buf_.get() && pending_buf_->data()) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_GE(pending_buf_size_, bytes.size());
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_buf_ = NULL;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_buf_size_ = 0;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyReadComplete(bytes_to_copy);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Received unexpected data of length:" << bytes.size();
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::OnRequestEnd(
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id, const net::URLRequestStatus& status) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request_)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url = request_->url().spec();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob: " << url << " - request end. Status: "
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << status.status();
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tommi): When we hit certificate errors, notify the delegate via
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OnSSLCertificateError().  Right now we don't have the certificate
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so we don't.  We could possibly call OnSSLCertificateError with a NULL
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, but I'm not sure if all implementations expect it.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if (status.status() == net::URLRequestStatus::FAILED &&
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    net::IsCertificateError(status.error()) && request_->delegate()) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  request_->delegate()->OnSSLCertificateError(request_, status.error());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisconnectFromMessageFilter();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NotifyDone may have been called on the job if the original request was
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // redirected.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_done()) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can complete the job if we have a valid response or a pending read.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // An end request can be received in the following cases
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1. We failed to connect to the server, in which case we did not receive
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    a valid response.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2. In response to a read request.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!has_response_started()) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NotifyStartError(status);
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (pending_buf_.get()) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_buf_ = NULL;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_buf_size_ = 0;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NotifyDone(status);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NotifyReadComplete(0);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Wait for the http stack to issue a Read request where we will notify
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // that the job has completed.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_status_ = status;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The job could have been destroyed above. Please don't attempt to access
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // member variables here.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::Cleanup() {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers_ = NULL;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mime_type_.erase();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_ = 0;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_ = 0;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!message_filter_.get());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisconnectFromMessageFilter();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_buf_ = NULL;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_buf_size_ = 0;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::StartAsync() {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "URLRequestAutomationJob: start request: "
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << (request_ ? request_->url().spec() : "NULL request");
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the job is cancelled before we got a chance to start it
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we have nothing much to do here.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_done())
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not receive a Start request for a pending job.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_pending());
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request_) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           net::ERR_FAILED));
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register this request with automation message filter.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_filter_->RegisterRequest(this);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Strip unwanted headers.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestHeaders new_request_headers;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_request_headers.MergeFrom(request_->extra_request_headers());
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kFilteredHeaderStrings); ++i)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_request_headers.RemoveHeader(kFilteredHeaderStrings[i]);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only add default Accept-Language if the request didn't have it specified.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!new_request_headers.HasHeader(
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpRequestHeaders::kAcceptLanguage) &&
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_user_agent_settings_) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string accept_language =
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        http_user_agent_settings_->GetAcceptLanguage();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!accept_language.empty()) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_request_headers.SetHeader(net::HttpRequestHeaders::kAcceptLanguage,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    accept_language);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // URLRequest::SetReferrer() ensures that we do not send username and
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // password fields in the referrer.
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL referrer(request_->referrer());
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The referrer header must be suppressed if the preceding URL was
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a secure one and the new one is not.
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Suppressing referrer header since going from secure to "
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "non-secure";
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    referrer = GURL();
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the resource type (main_frame/script/image/stylesheet etc.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceType::Type resource_type = ResourceType::MAIN_FRAME;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info) {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource_type = info->GetResourceType();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Construct UploadData from UploadDataStream.
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::UploadData> upload_data;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request_->get_upload())
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    upload_data = CreateUploadData(request_->get_upload());
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  request_start_ = base::TimeTicks::Now();
518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ask automation to start this request.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationURLRequest automation_request;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation_request.url = request_->url().spec();
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation_request.method = request_->method();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation_request.referrer = referrer.spec();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation_request.extra_request_headers = new_request_headers.ToString();
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  automation_request.upload_data = upload_data;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation_request.resource_type = resource_type;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation_request.load_flags = request_->load_flags();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(message_filter_.get());
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  message_filter_->Send(
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new AutomationMsg_RequestStart(tab_, id_, automation_request));
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::DisconnectFromMessageFilter() {
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (message_filter_.get()) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_filter_->UnRegisterRequest(this);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_filter_ = NULL;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::StartPendingJob(
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int new_tab_handle,
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationResourceMessageFilter* new_filter) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(new_filter != NULL);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_ = new_tab_handle;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_filter_ = new_filter;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_pending_ = false;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Start();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestAutomationJob::NotifyJobCompletionTask() {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_done()) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyDone(request_status_);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset any pending reads.
556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (pending_buf_.get()) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_buf_ = NULL;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_buf_size_ = 0;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyReadComplete(0);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
562