Home | History | Annotate | Download | only in loader
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/loader/sync_resource_handler.h"
      6 
      7 #include "base/logging.h"
      8 #include "content/browser/devtools/devtools_netlog_observer.h"
      9 #include "content/browser/loader/resource_dispatcher_host_impl.h"
     10 #include "content/browser/loader/resource_message_filter.h"
     11 #include "content/browser/loader/resource_request_info_impl.h"
     12 #include "content/common/resource_messages.h"
     13 #include "content/public/browser/resource_dispatcher_host_delegate.h"
     14 #include "content/public/browser/resource_request_info.h"
     15 #include "net/base/io_buffer.h"
     16 #include "net/http/http_response_headers.h"
     17 #include "net/url_request/redirect_info.h"
     18 
     19 namespace content {
     20 
     21 SyncResourceHandler::SyncResourceHandler(
     22     net::URLRequest* request,
     23     IPC::Message* result_message,
     24     ResourceDispatcherHostImpl* resource_dispatcher_host)
     25     : ResourceHandler(request),
     26       read_buffer_(new net::IOBuffer(kReadBufSize)),
     27       result_message_(result_message),
     28       rdh_(resource_dispatcher_host),
     29       total_transfer_size_(0) {
     30   result_.final_url = request->url();
     31 }
     32 
     33 SyncResourceHandler::~SyncResourceHandler() {
     34   if (result_message_) {
     35     result_message_->set_reply_error();
     36     ResourceMessageFilter* filter = GetFilter();
     37     // If the filter doesn't exist at this point, the process has died and isn't
     38     // waiting for the result message anymore.
     39     if (filter)
     40       filter->Send(result_message_);
     41   }
     42 }
     43 
     44 bool SyncResourceHandler::OnUploadProgress(uint64 position, uint64 size) {
     45   return true;
     46 }
     47 
     48 bool SyncResourceHandler::OnRequestRedirected(
     49     const net::RedirectInfo& redirect_info,
     50     ResourceResponse* response,
     51     bool* defer) {
     52   if (rdh_->delegate()) {
     53     rdh_->delegate()->OnRequestRedirected(
     54         redirect_info.new_url, request(), GetRequestInfo()->GetContext(),
     55         response);
     56   }
     57 
     58   DevToolsNetLogObserver::PopulateResponseInfo(request(), response);
     59   // TODO(darin): It would be much better if this could live in WebCore, but
     60   // doing so requires API changes at all levels.  Similar code exists in
     61   // WebCore/platform/network/cf/ResourceHandleCFNet.cpp :-(
     62   if (redirect_info.new_url.GetOrigin() != result_.final_url.GetOrigin()) {
     63     LOG(ERROR) << "Cross origin redirect denied";
     64     return false;
     65   }
     66   result_.final_url = redirect_info.new_url;
     67 
     68   total_transfer_size_ += request()->GetTotalReceivedBytes();
     69   return true;
     70 }
     71 
     72 bool SyncResourceHandler::OnResponseStarted(
     73     ResourceResponse* response,
     74     bool* defer) {
     75   const ResourceRequestInfoImpl* info = GetRequestInfo();
     76   if (!info->filter())
     77     return false;
     78 
     79   if (rdh_->delegate()) {
     80     rdh_->delegate()->OnResponseStarted(
     81         request(), info->GetContext(), response, info->filter());
     82   }
     83 
     84   DevToolsNetLogObserver::PopulateResponseInfo(request(), response);
     85 
     86   // We don't care about copying the status here.
     87   result_.headers = response->head.headers;
     88   result_.mime_type = response->head.mime_type;
     89   result_.charset = response->head.charset;
     90   result_.download_file_path = response->head.download_file_path;
     91   result_.request_time = response->head.request_time;
     92   result_.response_time = response->head.response_time;
     93   result_.load_timing = response->head.load_timing;
     94   result_.devtools_info = response->head.devtools_info;
     95   return true;
     96 }
     97 
     98 bool SyncResourceHandler::OnWillStart(const GURL& url, bool* defer) {
     99   return true;
    100 }
    101 
    102 bool SyncResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) {
    103   return true;
    104 }
    105 
    106 bool SyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
    107                                      int* buf_size,
    108                                      int min_size) {
    109   DCHECK(min_size == -1);
    110   *buf = read_buffer_.get();
    111   *buf_size = kReadBufSize;
    112   return true;
    113 }
    114 
    115 bool SyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
    116   if (!bytes_read)
    117     return true;
    118   result_.data.append(read_buffer_->data(), bytes_read);
    119   return true;
    120 }
    121 
    122 void SyncResourceHandler::OnResponseCompleted(
    123     const net::URLRequestStatus& status,
    124     const std::string& security_info,
    125     bool* defer) {
    126   ResourceMessageFilter* filter = GetFilter();
    127   if (!filter)
    128     return;
    129 
    130   result_.error_code = status.error();
    131 
    132   int total_transfer_size = request()->GetTotalReceivedBytes();
    133   result_.encoded_data_length = total_transfer_size_ + total_transfer_size;
    134 
    135   ResourceHostMsg_SyncLoad::WriteReplyParams(result_message_, result_);
    136   filter->Send(result_message_);
    137   result_message_ = NULL;
    138   return;
    139 }
    140 
    141 void SyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
    142   // Sync requests don't involve ResourceMsg_DataDownloaded messages
    143   // being sent back to renderers as progress is made.
    144 }
    145 
    146 }  // namespace content
    147