| Index: android_webview/browser/net/android_stream_reader_url_request_job.cc
|
| diff --git a/android_webview/browser/net/android_stream_reader_url_request_job.cc b/android_webview/browser/net/android_stream_reader_url_request_job.cc
|
| index 835758b9b5ec8cf82acbd3f4e8d379113431370f..c2c478362281a0b74bafa225ffc89c3d5c1d2b65 100644
|
| --- a/android_webview/browser/net/android_stream_reader_url_request_job.cc
|
| +++ b/android_webview/browser/net/android_stream_reader_url_request_job.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "android_webview/browser/net/android_stream_reader_url_request_job.h"
|
|
|
| +#include <string>
|
| +
|
| #include "android_webview/browser/input_stream.h"
|
| #include "android_webview/browser/net/input_stream_reader.h"
|
| #include "base/android/jni_android.h"
|
| @@ -13,6 +15,7 @@
|
| #include "base/lazy_instance.h"
|
| #include "base/message_loop.h"
|
| #include "base/message_loop_proxy.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "base/task_runner.h"
|
| #include "base/threading/sequenced_worker_pool.h"
|
| #include "base/threading/thread.h"
|
| @@ -21,6 +24,8 @@
|
| #include "net/base/mime_util.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/base/net_util.h"
|
| +#include "net/http/http_response_headers.h"
|
| +#include "net/http/http_response_info.h"
|
| #include "net/http/http_util.h"
|
| #include "net/url_request/url_request.h"
|
| #include "net/url_request/url_request_job_manager.h"
|
| @@ -31,6 +36,16 @@ using base::android::AttachCurrentThread;
|
| using base::PostTaskAndReplyWithResult;
|
| using content::BrowserThread;
|
|
|
| +namespace {
|
| +
|
| +const int kHTTPOk = 200;
|
| +const int kHTTPNotFound = 404;
|
| +
|
| +const char kHTTPOkText[] = "OK";
|
| +const char kHTTPNotFoundText[] = "Not Found";
|
| +
|
| +} // namespace
|
| +
|
| // The requests posted to the worker thread might outlive the job. Thread-safe
|
| // ref counting is used to ensure that the InputStream and InputStreamReader
|
| // members of this class are still there when the closure is run on the worker
|
| @@ -155,8 +170,9 @@ void AndroidStreamReaderURLRequestJob::OnInputStreamOpened(
|
| if (restart_required) {
|
| NotifyRestartRequired();
|
| } else {
|
| - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
|
| - net::ERR_FAILED));
|
| + // Clear the IO_PENDING status set in Start().
|
| + SetStatus(net::URLRequestStatus());
|
| + HeadersComplete(kHTTPNotFound, kHTTPNotFoundText);
|
| }
|
| return;
|
| }
|
| @@ -185,7 +201,7 @@ void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) {
|
| SetStatus(net::URLRequestStatus());
|
| if (result >= 0) {
|
| set_expected_content_size(result);
|
| - NotifyHeadersComplete();
|
| + HeadersComplete(kHTTPOk, kHTTPOkText);
|
| } else {
|
| NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
|
| }
|
| @@ -220,7 +236,13 @@ bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest,
|
| int dest_size,
|
| int* bytes_read) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(input_stream_reader_wrapper_);
|
| + if (!input_stream_reader_wrapper_) {
|
| + // This will happen if opening the InputStream fails in which case the
|
| + // error is communicated by setting the HTTP response status header rather
|
| + // than failing the request during the header fetch phase.
|
| + *bytes_read = 0;
|
| + return true;
|
| + }
|
|
|
| PostTaskAndReplyWithResult(
|
| GetWorkerThreadRunner(),
|
| @@ -270,6 +292,54 @@ bool AndroidStreamReaderURLRequestJob::GetCharset(std::string* charset) {
|
| env, request(), input_stream_reader_wrapper_->input_stream(), charset);
|
| }
|
|
|
| +void AndroidStreamReaderURLRequestJob::HeadersComplete(
|
| + int status_code,
|
| + const std::string& status_text) {
|
| + std::string status("HTTP/1.1 ");
|
| + status.append(base::IntToString(status_code));
|
| + status.append(" ");
|
| + status.append(status_text);
|
| + // HttpResponseHeaders expects its input string to be terminated by two NULs.
|
| + status.append("\0\0", 2);
|
| + net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
|
| +
|
| + if (status_code == kHTTPOk) {
|
| + if (expected_content_size() != -1) {
|
| + std::string content_length_header(
|
| + net::HttpRequestHeaders::kContentLength);
|
| + content_length_header.append(": ");
|
| + content_length_header.append(
|
| + base::Int64ToString(expected_content_size()));
|
| + headers->AddHeader(content_length_header);
|
| + }
|
| +
|
| + std::string mime_type;
|
| + if (GetMimeType(&mime_type) && !mime_type.empty()) {
|
| + std::string content_type_header(net::HttpRequestHeaders::kContentType);
|
| + content_type_header.append(": ");
|
| + content_type_header.append(mime_type);
|
| + headers->AddHeader(content_type_header);
|
| + }
|
| + }
|
| +
|
| + response_info_.reset(new net::HttpResponseInfo());
|
| + response_info_->headers = headers;
|
| +
|
| + NotifyHeadersComplete();
|
| +}
|
| +
|
| +int AndroidStreamReaderURLRequestJob::GetResponseCode() const {
|
| + if (response_info_)
|
| + return response_info_->headers->response_code();
|
| + return URLRequestJob::GetResponseCode();
|
| +}
|
| +
|
| +void AndroidStreamReaderURLRequestJob::GetResponseInfo(
|
| + net::HttpResponseInfo* info) {
|
| + if (response_info_)
|
| + *info = *response_info_;
|
| +}
|
| +
|
| void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders(
|
| const net::HttpRequestHeaders& headers) {
|
| std::string range_header;
|
|
|