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/common/resource_messages.h"
12#include "content/public/browser/global_request_id.h"
13#include "content/public/browser/resource_dispatcher_host_delegate.h"
14#include "net/base/io_buffer.h"
15#include "net/http/http_response_headers.h"
16
17namespace content {
18
19SyncResourceHandler::SyncResourceHandler(
20    ResourceMessageFilter* filter,
21    net::URLRequest* request,
22    IPC::Message* result_message,
23    ResourceDispatcherHostImpl* resource_dispatcher_host)
24    : read_buffer_(new net::IOBuffer(kReadBufSize)),
25      filter_(filter),
26      request_(request),
27      result_message_(result_message),
28      rdh_(resource_dispatcher_host) {
29  result_.final_url = request_->url();
30}
31
32SyncResourceHandler::~SyncResourceHandler() {
33  if (result_message_) {
34    result_message_->set_reply_error();
35    filter_->Send(result_message_);
36  }
37}
38
39bool SyncResourceHandler::OnUploadProgress(int request_id,
40                                           uint64 position,
41                                           uint64 size) {
42  return true;
43}
44
45bool SyncResourceHandler::OnRequestRedirected(
46    int request_id,
47    const GURL& new_url,
48    ResourceResponse* response,
49    bool* defer) {
50  if (rdh_->delegate()) {
51    rdh_->delegate()->OnRequestRedirected(new_url, request_,
52                                          filter_->resource_context(),
53                                          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  return true;
66}
67
68bool SyncResourceHandler::OnResponseStarted(
69    int request_id,
70    ResourceResponse* response,
71    bool* defer) {
72  if (rdh_->delegate()) {
73    rdh_->delegate()->OnResponseStarted(
74        request_, filter_->resource_context(), response, filter_.get());
75  }
76
77  DevToolsNetLogObserver::PopulateResponseInfo(request_, response);
78
79  // We don't care about copying the status here.
80  result_.headers = response->head.headers;
81  result_.mime_type = response->head.mime_type;
82  result_.charset = response->head.charset;
83  result_.download_file_path = response->head.download_file_path;
84  result_.request_time = response->head.request_time;
85  result_.response_time = response->head.response_time;
86  result_.load_timing = response->head.load_timing;
87  result_.devtools_info = response->head.devtools_info;
88  return true;
89}
90
91bool SyncResourceHandler::OnWillStart(int request_id,
92                                      const GURL& url,
93                                      bool* defer) {
94  return true;
95}
96
97bool SyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
98                                     int* buf_size, int min_size) {
99  DCHECK(min_size == -1);
100  *buf = read_buffer_.get();
101  *buf_size = kReadBufSize;
102  return true;
103}
104
105bool SyncResourceHandler::OnReadCompleted(int request_id, int bytes_read,
106                                          bool* defer) {
107  if (!bytes_read)
108    return true;
109  result_.data.append(read_buffer_->data(), bytes_read);
110  return true;
111}
112
113bool SyncResourceHandler::OnResponseCompleted(
114    int request_id,
115    const net::URLRequestStatus& status,
116    const std::string& security_info) {
117  result_.error_code = status.error();
118
119  result_.encoded_data_length =
120      DevToolsNetLogObserver::GetAndResetEncodedDataLength(request_);
121
122  ResourceHostMsg_SyncLoad::WriteReplyParams(result_message_, result_);
123  filter_->Send(result_message_);
124  result_message_ = NULL;
125  return true;
126}
127
128void SyncResourceHandler::OnDataDownloaded(
129    int request_id,
130    int bytes_downloaded) {
131  // Sync requests don't involve ResourceMsg_DataDownloaded messages
132  // being sent back to renderers as progress is made.
133}
134
135}  // namespace content
136