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