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/global_request_id.h"
14 #include "content/public/browser/resource_dispatcher_host_delegate.h"
15 #include "content/public/browser/resource_request_info.h"
16 #include "net/base/io_buffer.h"
17 #include "net/http/http_response_headers.h"
18
19 namespace content {
20
SyncResourceHandler(net::URLRequest * request,IPC::Message * result_message,ResourceDispatcherHostImpl * resource_dispatcher_host)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 result_.final_url = request->url();
30 }
31
~SyncResourceHandler()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
OnUploadProgress(int request_id,uint64 position,uint64 size)43 bool SyncResourceHandler::OnUploadProgress(int request_id,
44 uint64 position,
45 uint64 size) {
46 return true;
47 }
48
OnRequestRedirected(int request_id,const GURL & new_url,ResourceResponse * response,bool * defer)49 bool SyncResourceHandler::OnRequestRedirected(
50 int request_id,
51 const GURL& new_url,
52 ResourceResponse* response,
53 bool* defer) {
54 if (rdh_->delegate()) {
55 rdh_->delegate()->OnRequestRedirected(
56 new_url, request(), GetRequestInfo()->GetContext(), response);
57 }
58
59 DevToolsNetLogObserver::PopulateResponseInfo(request(), response);
60 // TODO(darin): It would be much better if this could live in WebCore, but
61 // doing so requires API changes at all levels. Similar code exists in
62 // WebCore/platform/network/cf/ResourceHandleCFNet.cpp :-(
63 if (new_url.GetOrigin() != result_.final_url.GetOrigin()) {
64 LOG(ERROR) << "Cross origin redirect denied";
65 return false;
66 }
67 result_.final_url = new_url;
68 return true;
69 }
70
OnResponseStarted(int request_id,ResourceResponse * response,bool * defer)71 bool SyncResourceHandler::OnResponseStarted(
72 int request_id,
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
OnWillStart(int request_id,const GURL & url,bool * defer)98 bool SyncResourceHandler::OnWillStart(int request_id,
99 const GURL& url,
100 bool* defer) {
101 return true;
102 }
103
OnWillRead(int request_id,scoped_refptr<net::IOBuffer> * buf,int * buf_size,int min_size)104 bool SyncResourceHandler::OnWillRead(int request_id,
105 scoped_refptr<net::IOBuffer>* buf,
106 int* buf_size,
107 int min_size) {
108 DCHECK(min_size == -1);
109 *buf = read_buffer_.get();
110 *buf_size = kReadBufSize;
111 return true;
112 }
113
OnReadCompleted(int request_id,int bytes_read,bool * defer)114 bool SyncResourceHandler::OnReadCompleted(int request_id, int bytes_read,
115 bool* defer) {
116 if (!bytes_read)
117 return true;
118 result_.data.append(read_buffer_->data(), bytes_read);
119 return true;
120 }
121
OnResponseCompleted(int request_id,const net::URLRequestStatus & status,const std::string & security_info,bool * defer)122 void SyncResourceHandler::OnResponseCompleted(
123 int request_id,
124 const net::URLRequestStatus& status,
125 const std::string& security_info,
126 bool* defer) {
127 ResourceMessageFilter* filter = GetFilter();
128 if (!filter)
129 return;
130
131 result_.error_code = status.error();
132
133 result_.encoded_data_length =
134 DevToolsNetLogObserver::GetAndResetEncodedDataLength(request());
135
136 ResourceHostMsg_SyncLoad::WriteReplyParams(result_message_, result_);
137 filter->Send(result_message_);
138 result_message_ = NULL;
139 return;
140 }
141
OnDataDownloaded(int request_id,int bytes_downloaded)142 void SyncResourceHandler::OnDataDownloaded(
143 int request_id,
144 int bytes_downloaded) {
145 // Sync requests don't involve ResourceMsg_DataDownloaded messages
146 // being sent back to renderers as progress is made.
147 }
148
149 } // namespace content
150