Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Side by Side Diff: android_webview/browser/net/android_stream_reader_url_request_job.cc

Issue 1439953006: Reland: URLRequestJob: change ReadRawData contract (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address David's comment Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "android_webview/browser/net/android_stream_reader_url_request_job.h" 5 #include "android_webview/browser/net/android_stream_reader_url_request_job.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "android_webview/browser/input_stream.h" 9 #include "android_webview/browser/input_stream.h"
10 #include "android_webview/browser/net/input_stream_reader.h" 10 #include "android_webview/browser/net/input_stream_reader.h"
11 #include "base/android/jni_android.h" 11 #include "base/android/jni_android.h"
12 #include "base/android/jni_string.h" 12 #include "base/android/jni_string.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/task_runner.h" 18 #include "base/task_runner.h"
19 #include "base/threading/sequenced_worker_pool.h" 19 #include "base/threading/sequenced_worker_pool.h"
20 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
21 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
22 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
23 #include "net/base/mime_util.h" 23 #include "net/base/mime_util.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/net_util.h" 24 #include "net/base/net_util.h"
26 #include "net/http/http_response_headers.h" 25 #include "net/http/http_response_headers.h"
27 #include "net/http/http_response_info.h" 26 #include "net/http/http_response_info.h"
28 #include "net/http/http_util.h" 27 #include "net/http/http_util.h"
29 #include "net/url_request/url_request.h" 28 #include "net/url_request/url_request.h"
30 #include "net/url_request/url_request_job_manager.h" 29 #include "net/url_request/url_request_job_manager.h"
31 30
32 using base::android::AttachCurrentThread; 31 using base::android::AttachCurrentThread;
33 using base::PostTaskAndReplyWithResult; 32 using base::PostTaskAndReplyWithResult;
34 using content::BrowserThread; 33 using content::BrowserThread;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 scoped_ptr<InputStreamReader> input_stream_reader_; 82 scoped_ptr<InputStreamReader> input_stream_reader_;
84 83
85 DISALLOW_COPY_AND_ASSIGN(InputStreamReaderWrapper); 84 DISALLOW_COPY_AND_ASSIGN(InputStreamReaderWrapper);
86 }; 85 };
87 86
88 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( 87 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob(
89 net::URLRequest* request, 88 net::URLRequest* request,
90 net::NetworkDelegate* network_delegate, 89 net::NetworkDelegate* network_delegate,
91 scoped_ptr<Delegate> delegate) 90 scoped_ptr<Delegate> delegate)
92 : URLRequestJob(request, network_delegate), 91 : URLRequestJob(request, network_delegate),
92 range_parse_result_(net::OK),
93 delegate_(delegate.Pass()), 93 delegate_(delegate.Pass()),
94 weak_factory_(this) { 94 weak_factory_(this) {
95 DCHECK(delegate_); 95 DCHECK(delegate_);
96 } 96 }
97 97
98 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( 98 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob(
99 net::URLRequest* request, 99 net::URLRequest* request,
100 net::NetworkDelegate* network_delegate, 100 net::NetworkDelegate* network_delegate,
101 scoped_ptr<DelegateObtainer> delegate_obtainer, 101 scoped_ptr<DelegateObtainer> delegate_obtainer,
102 bool) 102 bool)
103 : URLRequestJob(request, network_delegate), 103 : URLRequestJob(request, network_delegate),
104 range_parse_result_(net::OK),
104 delegate_obtainer_(delegate_obtainer.Pass()), 105 delegate_obtainer_(delegate_obtainer.Pass()),
105 weak_factory_(this) { 106 weak_factory_(this) {
106 DCHECK(delegate_obtainer_); 107 DCHECK(delegate_obtainer_);
107 } 108 }
108 109
109 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { 110 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() {
110 } 111 }
111 112
112 namespace { 113 namespace {
113 114
(...skipping 20 matching lines...) Expand all
134 135
135 void AndroidStreamReaderURLRequestJob::Start() { 136 void AndroidStreamReaderURLRequestJob::Start() {
136 DCHECK(thread_checker_.CalledOnValidThread()); 137 DCHECK(thread_checker_.CalledOnValidThread());
137 if (!delegate_) { 138 if (!delegate_) {
138 DCHECK(delegate_obtainer_); 139 DCHECK(delegate_obtainer_);
139 delegate_obtainer_->ObtainDelegate( 140 delegate_obtainer_->ObtainDelegate(
140 request(), 141 request(),
141 base::Bind(&AndroidStreamReaderURLRequestJob::DelegateObtained, 142 base::Bind(&AndroidStreamReaderURLRequestJob::DelegateObtained,
142 weak_factory_.GetWeakPtr())); 143 weak_factory_.GetWeakPtr()));
143 } else { 144 } else {
144 DoStart(); 145 // Run DoStart asynchronously to avoid re-entering the delegate.
146 base::ThreadTaskRunnerHandle::Get()->PostTask(
147 FROM_HERE, base::Bind(&AndroidStreamReaderURLRequestJob::DoStart,
148 weak_factory_.GetWeakPtr()));
145 } 149 }
146 } 150 }
147 151
148 void AndroidStreamReaderURLRequestJob::Kill() { 152 void AndroidStreamReaderURLRequestJob::Kill() {
149 DCHECK(thread_checker_.CalledOnValidThread()); 153 DCHECK(thread_checker_.CalledOnValidThread());
150 weak_factory_.InvalidateWeakPtrs(); 154 weak_factory_.InvalidateWeakPtrs();
151 URLRequestJob::Kill(); 155 URLRequestJob::Kill();
152 } 156 }
153 157
154 scoped_ptr<InputStreamReader> 158 scoped_ptr<InputStreamReader>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 199 }
196 200
197 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) { 201 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) {
198 DCHECK(thread_checker_.CalledOnValidThread()); 202 DCHECK(thread_checker_.CalledOnValidThread());
199 // Clear the IO_PENDING status set in Start(). 203 // Clear the IO_PENDING status set in Start().
200 SetStatus(net::URLRequestStatus()); 204 SetStatus(net::URLRequestStatus());
201 if (result >= 0) { 205 if (result >= 0) {
202 set_expected_content_size(result); 206 set_expected_content_size(result);
203 HeadersComplete(kHTTPOk, kHTTPOkText); 207 HeadersComplete(kHTTPOk, kHTTPOkText);
204 } else { 208 } else {
205 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 209 NotifyStartError(
210 net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
206 } 211 }
207 } 212 }
208 213
209 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) { 214 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) {
210 DCHECK(thread_checker_.CalledOnValidThread()); 215 DCHECK(thread_checker_.CalledOnValidThread());
211 // The URLRequest API contract requires that: 216
212 // * NotifyDone be called once, to set the status code, indicate the job is 217 ReadRawDataComplete(result);
213 // finished (there will be no further IO),
214 // * NotifyReadComplete be called if false is returned from ReadRawData to
215 // indicate that the IOBuffer will not be used by the job anymore.
216 // There might be multiple calls to ReadRawData (and thus multiple calls to
217 // NotifyReadComplete), which is why NotifyDone is called only on errors
218 // (result < 0) and end of data (result == 0).
219 if (result == 0) {
220 NotifyDone(net::URLRequestStatus());
221 } else if (result < 0) {
222 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
223 } else {
224 // Clear the IO_PENDING status.
225 SetStatus(net::URLRequestStatus());
226 }
227 NotifyReadComplete(result);
228 } 218 }
229 219
230 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { 220 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() {
231 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); 221 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool());
232 } 222 }
233 223
234 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, 224 int AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest,
235 int dest_size, 225 int dest_size) {
236 int* bytes_read) {
237 DCHECK(thread_checker_.CalledOnValidThread()); 226 DCHECK(thread_checker_.CalledOnValidThread());
238 if (!input_stream_reader_wrapper_.get()) { 227 if (!input_stream_reader_wrapper_.get()) {
239 // This will happen if opening the InputStream fails in which case the 228 // This will happen if opening the InputStream fails in which case the
240 // error is communicated by setting the HTTP response status header rather 229 // error is communicated by setting the HTTP response status header rather
241 // than failing the request during the header fetch phase. 230 // than failing the request during the header fetch phase.
242 *bytes_read = 0; 231 return 0;
243 return true;
244 } 232 }
245 233
246 PostTaskAndReplyWithResult( 234 PostTaskAndReplyWithResult(
247 GetWorkerThreadRunner(), FROM_HERE, 235 GetWorkerThreadRunner(), FROM_HERE,
248 base::Bind(&InputStreamReaderWrapper::ReadRawData, 236 base::Bind(&InputStreamReaderWrapper::ReadRawData,
249 input_stream_reader_wrapper_, make_scoped_refptr(dest), 237 input_stream_reader_wrapper_, make_scoped_refptr(dest),
250 dest_size), 238 dest_size),
251 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, 239 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted,
252 weak_factory_.GetWeakPtr())); 240 weak_factory_.GetWeakPtr()));
253 241
254 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 242 return net::ERR_IO_PENDING;
255 net::ERR_IO_PENDING));
256 return false;
257 } 243 }
258 244
259 bool AndroidStreamReaderURLRequestJob::GetMimeType( 245 bool AndroidStreamReaderURLRequestJob::GetMimeType(
260 std::string* mime_type) const { 246 std::string* mime_type) const {
261 DCHECK(thread_checker_.CalledOnValidThread()); 247 DCHECK(thread_checker_.CalledOnValidThread());
262 JNIEnv* env = AttachCurrentThread(); 248 JNIEnv* env = AttachCurrentThread();
263 DCHECK(env); 249 DCHECK(env);
264 250
265 if (!input_stream_reader_wrapper_.get()) 251 if (!input_stream_reader_wrapper_.get())
266 return false; 252 return false;
(...skipping 29 matching lines...) Expand all
296 if (delegate) { 282 if (delegate) {
297 delegate_.swap(delegate); 283 delegate_.swap(delegate);
298 DoStart(); 284 DoStart();
299 } else { 285 } else {
300 NotifyRestartRequired(); 286 NotifyRestartRequired();
301 } 287 }
302 } 288 }
303 289
304 void AndroidStreamReaderURLRequestJob::DoStart() { 290 void AndroidStreamReaderURLRequestJob::DoStart() {
305 DCHECK(thread_checker_.CalledOnValidThread()); 291 DCHECK(thread_checker_.CalledOnValidThread());
292 if (range_parse_result_ != net::OK) {
293 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
294 range_parse_result_));
295 return;
296 }
306 // Start reading asynchronously so that all error reporting and data 297 // Start reading asynchronously so that all error reporting and data
307 // callbacks happen as they would for network requests. 298 // callbacks happen as they would for network requests.
308 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 299 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING,
309 net::ERR_IO_PENDING)); 300 net::ERR_IO_PENDING));
310 301
311 // This could be done in the InputStreamReader but would force more 302 // This could be done in the InputStreamReader but would force more
312 // complex synchronization in the delegate. 303 // complex synchronization in the delegate.
313 GetWorkerThreadRunner()->PostTask( 304 GetWorkerThreadRunner()->PostTask(
314 FROM_HERE, 305 FROM_HERE,
315 base::Bind( 306 base::Bind(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 void AndroidStreamReaderURLRequestJob::GetResponseInfo( 367 void AndroidStreamReaderURLRequestJob::GetResponseInfo(
377 net::HttpResponseInfo* info) { 368 net::HttpResponseInfo* info) {
378 if (response_info_) 369 if (response_info_)
379 *info = *response_info_; 370 *info = *response_info_;
380 } 371 }
381 372
382 void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders( 373 void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders(
383 const net::HttpRequestHeaders& headers) { 374 const net::HttpRequestHeaders& headers) {
384 std::string range_header; 375 std::string range_header;
385 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { 376 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) {
386 // We only extract the "Range" header so that we know how many bytes in the 377 // This job only cares about the Range header so that we know how many bytes
387 // stream to skip and how many to read after that. 378 // in the stream to skip and how many to read after that. Note that
379 // validation is deferred to DoStart(), because NotifyStartError() is not
380 // legal to call since the job has not started.
388 std::vector<net::HttpByteRange> ranges; 381 std::vector<net::HttpByteRange> ranges;
389 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { 382 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
390 if (ranges.size() == 1) { 383 if (ranges.size() == 1)
391 byte_range_ = ranges[0]; 384 byte_range_ = ranges[0];
392 } else { 385 } else {
393 // We don't support multiple range requests in one single URL request, 386 // We don't support multiple range requests in one single URL request,
394 // because we need to do multipart encoding here. 387 // because we need to do multipart encoding here.
395 NotifyDone( 388 range_parse_result_ = net::ERR_REQUEST_RANGE_NOT_SATISFIABLE;
396 net::URLRequestStatus(net::URLRequestStatus::FAILED,
397 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
398 }
399 } 389 }
400 } 390 }
401 } 391 }
402 392
403 } // namespace android_webview 393 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698