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 18 namespace content { 19 20 SyncResourceHandler::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 32 SyncResourceHandler::~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 43 bool SyncResourceHandler::OnUploadProgress(uint64 position, uint64 size) { 44 return true; 45 } 46 47 bool 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 70 bool 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 96 bool SyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { 97 return true; 98 } 99 100 bool SyncResourceHandler::OnBeforeNetworkStart(const GURL& url, bool* defer) { 101 return true; 102 } 103 104 bool 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 113 bool 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 120 void 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 139 void 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