OLD | NEW |
---|---|
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" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 scoped_ptr<InputStreamReader> input_stream_reader_; | 83 scoped_ptr<InputStreamReader> input_stream_reader_; |
84 | 84 |
85 DISALLOW_COPY_AND_ASSIGN(InputStreamReaderWrapper); | 85 DISALLOW_COPY_AND_ASSIGN(InputStreamReaderWrapper); |
86 }; | 86 }; |
87 | 87 |
88 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( | 88 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( |
89 net::URLRequest* request, | 89 net::URLRequest* request, |
90 net::NetworkDelegate* network_delegate, | 90 net::NetworkDelegate* network_delegate, |
91 scoped_ptr<Delegate> delegate) | 91 scoped_ptr<Delegate> delegate) |
92 : URLRequestJob(request, network_delegate), | 92 : URLRequestJob(request, network_delegate), |
93 range_parse_result_(net::OK), | |
93 delegate_(delegate.Pass()), | 94 delegate_(delegate.Pass()), |
94 weak_factory_(this) { | 95 weak_factory_(this) { |
95 DCHECK(delegate_); | 96 DCHECK(delegate_); |
96 } | 97 } |
97 | 98 |
98 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( | 99 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( |
99 net::URLRequest* request, | 100 net::URLRequest* request, |
100 net::NetworkDelegate* network_delegate, | 101 net::NetworkDelegate* network_delegate, |
101 scoped_ptr<DelegateObtainer> delegate_obtainer, | 102 scoped_ptr<DelegateObtainer> delegate_obtainer, |
102 bool) | 103 bool) |
103 : URLRequestJob(request, network_delegate), | 104 : URLRequestJob(request, network_delegate), |
105 range_parse_result_(net::OK), | |
104 delegate_obtainer_(delegate_obtainer.Pass()), | 106 delegate_obtainer_(delegate_obtainer.Pass()), |
105 weak_factory_(this) { | 107 weak_factory_(this) { |
106 DCHECK(delegate_obtainer_); | 108 DCHECK(delegate_obtainer_); |
107 } | 109 } |
108 | 110 |
109 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { | 111 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { |
110 } | 112 } |
111 | 113 |
112 namespace { | 114 namespace { |
113 | 115 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 } | 197 } |
196 | 198 |
197 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) { | 199 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) { |
198 DCHECK(thread_checker_.CalledOnValidThread()); | 200 DCHECK(thread_checker_.CalledOnValidThread()); |
199 // Clear the IO_PENDING status set in Start(). | 201 // Clear the IO_PENDING status set in Start(). |
200 SetStatus(net::URLRequestStatus()); | 202 SetStatus(net::URLRequestStatus()); |
201 if (result >= 0) { | 203 if (result >= 0) { |
202 set_expected_content_size(result); | 204 set_expected_content_size(result); |
203 HeadersComplete(kHTTPOk, kHTTPOkText); | 205 HeadersComplete(kHTTPOk, kHTTPOkText); |
204 } else { | 206 } else { |
205 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); | 207 NotifyStartError( |
208 net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); | |
206 } | 209 } |
207 } | 210 } |
208 | 211 |
209 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) { | 212 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) { |
210 DCHECK(thread_checker_.CalledOnValidThread()); | 213 DCHECK(thread_checker_.CalledOnValidThread()); |
211 // The URLRequest API contract requires that: | 214 |
212 // * NotifyDone be called once, to set the status code, indicate the job is | 215 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 } | 216 } |
229 | 217 |
230 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { | 218 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { |
231 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); | 219 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); |
232 } | 220 } |
233 | 221 |
234 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, | 222 int AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, |
235 int dest_size, | 223 int dest_size) { |
236 int* bytes_read) { | |
237 DCHECK(thread_checker_.CalledOnValidThread()); | 224 DCHECK(thread_checker_.CalledOnValidThread()); |
238 if (!input_stream_reader_wrapper_.get()) { | 225 if (!input_stream_reader_wrapper_.get()) { |
239 // This will happen if opening the InputStream fails in which case the | 226 // This will happen if opening the InputStream fails in which case the |
240 // error is communicated by setting the HTTP response status header rather | 227 // error is communicated by setting the HTTP response status header rather |
241 // than failing the request during the header fetch phase. | 228 // than failing the request during the header fetch phase. |
242 *bytes_read = 0; | 229 return 0; |
243 return true; | |
244 } | 230 } |
245 | 231 |
246 PostTaskAndReplyWithResult( | 232 PostTaskAndReplyWithResult( |
247 GetWorkerThreadRunner(), | 233 GetWorkerThreadRunner(), FROM_HERE, |
248 FROM_HERE, | |
249 base::Bind(&InputStreamReaderWrapper::ReadRawData, | 234 base::Bind(&InputStreamReaderWrapper::ReadRawData, |
250 input_stream_reader_wrapper_, | 235 input_stream_reader_wrapper_, make_scoped_refptr(dest), |
251 make_scoped_refptr(dest), | |
252 dest_size), | 236 dest_size), |
253 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, | 237 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, |
254 weak_factory_.GetWeakPtr())); | 238 weak_factory_.GetWeakPtr())); |
255 | 239 |
256 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, | 240 return net::ERR_IO_PENDING; |
257 net::ERR_IO_PENDING)); | |
258 return false; | |
259 } | 241 } |
260 | 242 |
261 bool AndroidStreamReaderURLRequestJob::GetMimeType( | 243 bool AndroidStreamReaderURLRequestJob::GetMimeType( |
262 std::string* mime_type) const { | 244 std::string* mime_type) const { |
263 DCHECK(thread_checker_.CalledOnValidThread()); | 245 DCHECK(thread_checker_.CalledOnValidThread()); |
264 JNIEnv* env = AttachCurrentThread(); | 246 JNIEnv* env = AttachCurrentThread(); |
265 DCHECK(env); | 247 DCHECK(env); |
266 | 248 |
267 if (!input_stream_reader_wrapper_.get()) | 249 if (!input_stream_reader_wrapper_.get()) |
268 return false; | 250 return false; |
(...skipping 29 matching lines...) Expand all Loading... | |
298 if (delegate) { | 280 if (delegate) { |
299 delegate_.swap(delegate); | 281 delegate_.swap(delegate); |
300 DoStart(); | 282 DoStart(); |
301 } else { | 283 } else { |
302 NotifyRestartRequired(); | 284 NotifyRestartRequired(); |
303 } | 285 } |
304 } | 286 } |
305 | 287 |
306 void AndroidStreamReaderURLRequestJob::DoStart() { | 288 void AndroidStreamReaderURLRequestJob::DoStart() { |
307 DCHECK(thread_checker_.CalledOnValidThread()); | 289 DCHECK(thread_checker_.CalledOnValidThread()); |
290 if (range_parse_result_ != net::OK) { | |
291 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | |
292 range_parse_result_)); | |
mmenke
2015/10/27 19:41:07
It's not really safe to call NotifyStartError sync
xunjieli
2015/10/27 21:24:06
Done. Good to know. Thanks!
| |
293 return; | |
294 } | |
308 // Start reading asynchronously so that all error reporting and data | 295 // Start reading asynchronously so that all error reporting and data |
309 // callbacks happen as they would for network requests. | 296 // callbacks happen as they would for network requests. |
310 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, | 297 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, |
311 net::ERR_IO_PENDING)); | 298 net::ERR_IO_PENDING)); |
312 | 299 |
313 // This could be done in the InputStreamReader but would force more | 300 // This could be done in the InputStreamReader but would force more |
314 // complex synchronization in the delegate. | 301 // complex synchronization in the delegate. |
315 GetWorkerThreadRunner()->PostTask( | 302 GetWorkerThreadRunner()->PostTask( |
316 FROM_HERE, | 303 FROM_HERE, |
317 base::Bind( | 304 base::Bind( |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 return response_info_->headers->response_code(); | 361 return response_info_->headers->response_code(); |
375 return URLRequestJob::GetResponseCode(); | 362 return URLRequestJob::GetResponseCode(); |
376 } | 363 } |
377 | 364 |
378 void AndroidStreamReaderURLRequestJob::GetResponseInfo( | 365 void AndroidStreamReaderURLRequestJob::GetResponseInfo( |
379 net::HttpResponseInfo* info) { | 366 net::HttpResponseInfo* info) { |
380 if (response_info_) | 367 if (response_info_) |
381 *info = *response_info_; | 368 *info = *response_info_; |
382 } | 369 } |
383 | 370 |
371 // Extracts headers that this job cares about from the supplied request headers. | |
372 // Currently this job only cares about the Range header. Note that validation is | |
373 // deferred to DoStart(), because NotifyStartError is not legal to call since | |
374 // the job has not started. | |
mmenke
2015/10/27 19:41:07
See comment in other file (*file_dir_job.cc?)
xunjieli
2015/10/27 21:24:06
Done.
| |
384 void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders( | 375 void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders( |
385 const net::HttpRequestHeaders& headers) { | 376 const net::HttpRequestHeaders& headers) { |
386 std::string range_header; | 377 std::string range_header; |
387 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { | 378 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { |
388 // We only extract the "Range" header so that we know how many bytes in the | 379 // We only extract the "Range" header so that we know how many bytes in the |
389 // stream to skip and how many to read after that. | 380 // stream to skip and how many to read after that. |
390 std::vector<net::HttpByteRange> ranges; | 381 std::vector<net::HttpByteRange> ranges; |
391 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { | 382 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { |
392 if (ranges.size() == 1) { | 383 if (ranges.size() == 1) |
393 byte_range_ = ranges[0]; | 384 byte_range_ = ranges[0]; |
394 } else { | 385 } else { |
395 // 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, |
396 // because we need to do multipart encoding here. | 387 // because we need to do multipart encoding here. |
397 NotifyDone(net::URLRequestStatus( | 388 // Saves the failure which will be reported in DoStart(). |
398 net::URLRequestStatus::FAILED, | 389 range_parse_result_ = net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; |
399 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); | |
400 } | |
401 } | 390 } |
402 } | 391 } |
403 } | 392 } |
404 | 393 |
405 } // namespace android_webview | 394 } // namespace android_webview |
OLD | NEW |