1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/renderer_host/download_throttling_resource_handler.h"
#include "base/logging.h"
#include "chrome/browser/renderer_host/download_resource_handler.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/common/resource_response.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_sniffer.h"
DownloadThrottlingResourceHandler::DownloadThrottlingResourceHandler(
ResourceDispatcherHost* host,
URLRequest* request,
const GURL& url,
int render_process_host_id,
int render_view_id,
int request_id,
bool in_complete)
: host_(host),
request_(request),
url_(url),
render_process_host_id_(render_process_host_id),
render_view_id_(render_view_id),
request_id_(request_id),
tmp_buffer_length_(0),
ignore_on_read_complete_(in_complete) {
// Pause the request.
host_->PauseRequest(render_process_host_id_, request_id_, true);
host_->download_request_limiter()->CanDownloadOnIOThread(
render_process_host_id_, render_view_id, this);
}
DownloadThrottlingResourceHandler::~DownloadThrottlingResourceHandler() {
}
bool DownloadThrottlingResourceHandler::OnUploadProgress(int request_id,
uint64 position,
uint64 size) {
if (download_handler_.get())
return download_handler_->OnUploadProgress(request_id, position, size);
return true;
}
bool DownloadThrottlingResourceHandler::OnRequestRedirected(
int request_id,
const GURL& url,
ResourceResponse* response,
bool* defer) {
if (download_handler_.get()) {
return download_handler_->OnRequestRedirected(
request_id, url, response, defer);
}
url_ = url;
return true;
}
bool DownloadThrottlingResourceHandler::OnResponseStarted(
int request_id,
ResourceResponse* response) {
if (download_handler_.get())
return download_handler_->OnResponseStarted(request_id, response);
response_ = response;
return true;
}
bool DownloadThrottlingResourceHandler::OnWillStart(int request_id,
const GURL& url,
bool* defer) {
if (download_handler_.get())
return download_handler_->OnWillStart(request_id, url, defer);
return true;
}
bool DownloadThrottlingResourceHandler::OnWillRead(int request_id,
net::IOBuffer** buf,
int* buf_size,
int min_size) {
if (download_handler_.get())
return download_handler_->OnWillRead(request_id, buf, buf_size, min_size);
// We should only have this invoked once, as such we only deal with one
// tmp buffer.
DCHECK(!tmp_buffer_.get());
// If the caller passed a negative |min_size| then chose an appropriate
// default. The BufferedResourceHandler requires this to be at least 2 times
// the size required for mime detection.
if (min_size < 0)
min_size = 2 * net::kMaxBytesToSniff;
tmp_buffer_ = new net::IOBuffer(min_size);
*buf = tmp_buffer_.get();
*buf_size = min_size;
return true;
}
bool DownloadThrottlingResourceHandler::OnReadCompleted(int request_id,
int* bytes_read) {
if (ignore_on_read_complete_) {
// See comments above definition for details on this.
ignore_on_read_complete_ = false;
return true;
}
if (!*bytes_read)
return true;
if (tmp_buffer_.get()) {
DCHECK(!tmp_buffer_length_);
tmp_buffer_length_ = *bytes_read;
if (download_handler_.get())
CopyTmpBufferToDownloadHandler();
return true;
}
if (download_handler_.get())
return download_handler_->OnReadCompleted(request_id, bytes_read);
return true;
}
bool DownloadThrottlingResourceHandler::OnResponseCompleted(
int request_id,
const URLRequestStatus& status,
const std::string& security_info) {
if (download_handler_.get())
return download_handler_->OnResponseCompleted(request_id, status,
security_info);
// For a download, if ResourceDispatcher::Read() fails,
// ResourceDispatcher::OnresponseStarted() will call
// OnResponseCompleted(), and we will end up here with an error
// status.
if (!status.is_success())
return false;
NOTREACHED();
return true;
}
void DownloadThrottlingResourceHandler::OnRequestClosed() {
if (download_handler_.get())
download_handler_->OnRequestClosed();
}
void DownloadThrottlingResourceHandler::CancelDownload() {
host_->CancelRequest(render_process_host_id_, request_id_, false);
}
void DownloadThrottlingResourceHandler::ContinueDownload() {
DCHECK(!download_handler_.get());
download_handler_ =
new DownloadResourceHandler(host_,
render_process_host_id_,
render_view_id_,
request_id_,
url_,
host_->download_file_manager(),
request_,
false,
DownloadSaveInfo());
if (response_.get())
download_handler_->OnResponseStarted(request_id_, response_.get());
if (tmp_buffer_length_)
CopyTmpBufferToDownloadHandler();
// And let the request continue.
host_->PauseRequest(render_process_host_id_, request_id_, false);
}
int DownloadThrottlingResourceHandler::GetRequestId() {
return request_id_;
}
void DownloadThrottlingResourceHandler::CopyTmpBufferToDownloadHandler() {
// Copy over the tmp buffer.
net::IOBuffer* buffer;
int buf_size;
if (download_handler_->OnWillRead(request_id_, &buffer, &buf_size,
tmp_buffer_length_)) {
CHECK(buf_size >= tmp_buffer_length_);
memcpy(buffer->data(), tmp_buffer_->data(), tmp_buffer_length_);
download_handler_->OnReadCompleted(request_id_, &tmp_buffer_length_);
}
tmp_buffer_length_ = 0;
tmp_buffer_ = NULL;
}
|