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