| 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 "android_webview/browser/input_stream.h" | 7 #include "android_webview/browser/input_stream.h" |
| 8 #include "android_webview/browser/net/input_stream_reader.h" | 8 #include "android_webview/browser/net/input_stream_reader.h" |
| 9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
| 10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "net/http/http_util.h" | 23 #include "net/http/http_util.h" |
| 24 #include "net/url_request/url_request.h" | 24 #include "net/url_request/url_request.h" |
| 25 #include "net/url_request/url_request_job_manager.h" | 25 #include "net/url_request/url_request_job_manager.h" |
| 26 | 26 |
| 27 using android_webview::InputStream; | 27 using android_webview::InputStream; |
| 28 using android_webview::InputStreamReader; | 28 using android_webview::InputStreamReader; |
| 29 using base::android::AttachCurrentThread; | 29 using base::android::AttachCurrentThread; |
| 30 using base::PostTaskAndReplyWithResult; | 30 using base::PostTaskAndReplyWithResult; |
| 31 using content::BrowserThread; | 31 using content::BrowserThread; |
| 32 | 32 |
| 33 AndroidStreamReaderURLRequestJob::InputStreamReaderWrapper:: |
| 34 InputStreamReaderWrapper( |
| 35 scoped_ptr<InputStream> input_stream, |
| 36 scoped_ptr<InputStreamReader> input_stream_reader) |
| 37 : input_stream_(input_stream.Pass()), |
| 38 input_stream_reader_(input_stream_reader.Pass()) { |
| 39 DCHECK(input_stream_); |
| 40 DCHECK(input_stream_reader_); |
| 41 } |
| 42 |
| 43 AndroidStreamReaderURLRequestJob::InputStreamReaderWrapper:: |
| 44 ~InputStreamReaderWrapper() { |
| 45 } |
| 46 |
| 47 int AndroidStreamReaderURLRequestJob::InputStreamReaderWrapper::Seek( |
| 48 const net::HttpByteRange& byte_range) { |
| 49 return input_stream_reader_->Seek(byte_range); |
| 50 } |
| 51 |
| 52 int AndroidStreamReaderURLRequestJob::InputStreamReaderWrapper::ReadRawData( |
| 53 net::IOBuffer* buffer, int buffer_size) { |
| 54 return input_stream_reader_->ReadRawData(buffer, buffer_size); |
| 55 } |
| 56 |
| 33 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( | 57 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( |
| 34 net::URLRequest* request, | 58 net::URLRequest* request, |
| 35 net::NetworkDelegate* network_delegate, | 59 net::NetworkDelegate* network_delegate, |
| 36 scoped_ptr<Delegate> delegate) | 60 scoped_ptr<Delegate> delegate) |
| 37 : URLRequestJob(request, network_delegate), | 61 : URLRequestJob(request, network_delegate), |
| 38 delegate_(delegate.Pass()), | 62 delegate_(delegate.Pass()), |
| 39 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 63 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 40 DCHECK(delegate_.get()); | 64 DCHECK(delegate_.get()); |
| 41 } | 65 } |
| 42 | 66 |
| 43 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { | 67 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { |
| 44 } | 68 } |
| 45 | 69 |
| 46 void AndroidStreamReaderURLRequestJob::Start() { | 70 void AndroidStreamReaderURLRequestJob::Start() { |
| 47 // Start reading asynchronously so that all error reporting and data | 71 // Start reading asynchronously so that all error reporting and data |
| 48 // callbacks happen as they would for network requests. | 72 // callbacks happen as they would for network requests. |
| 49 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); | 73 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); |
| 50 MessageLoop::current()->PostTask( | 74 MessageLoop::current()->PostTask( |
| 51 FROM_HERE, | 75 FROM_HERE, |
| 52 base::Bind( | 76 base::Bind( |
| 53 &AndroidStreamReaderURLRequestJob::StartAsync, | 77 &AndroidStreamReaderURLRequestJob::StartAsync, |
| 54 weak_factory_.GetWeakPtr())); | 78 weak_factory_.GetWeakPtr())); |
| 55 } | 79 } |
| 56 | 80 |
| 57 void AndroidStreamReaderURLRequestJob::Kill() { | 81 void AndroidStreamReaderURLRequestJob::Kill() { |
| 58 weak_factory_.InvalidateWeakPtrs(); | 82 weak_factory_.InvalidateWeakPtrs(); |
| 59 URLRequestJob::Kill(); | 83 URLRequestJob::Kill(); |
| 60 } | 84 } |
| 61 | 85 |
| 62 scoped_refptr<InputStreamReader> | 86 scoped_ptr<InputStreamReader> |
| 63 AndroidStreamReaderURLRequestJob::CreateStreamReader(InputStream* stream) { | 87 AndroidStreamReaderURLRequestJob::CreateStreamReader(InputStream* stream) { |
| 64 return make_scoped_refptr(new InputStreamReader(stream)); | 88 return make_scoped_ptr(new InputStreamReader(stream)); |
| 65 } | 89 } |
| 66 | 90 |
| 67 void AndroidStreamReaderURLRequestJob::StartAsync() { | 91 void AndroidStreamReaderURLRequestJob::StartAsync() { |
| 68 JNIEnv* env = AttachCurrentThread(); | 92 JNIEnv* env = AttachCurrentThread(); |
| 69 DCHECK(env); | 93 DCHECK(env); |
| 70 | 94 |
| 71 // This could be done in the InputStreamReader but would force more | 95 // This could be done in the InputStreamReader but would force more |
| 72 // complex synchronization in the delegate. | 96 // complex synchronization in the delegate. |
| 73 stream_ = delegate_->OpenInputStream(env, request()); | 97 scoped_ptr<android_webview::InputStream> stream( |
| 74 if (!stream_) { | 98 delegate_->OpenInputStream(env, request())); |
| 75 NotifyDone( | 99 |
| 76 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); | 100 if (!stream) { |
| 101 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| 102 net::ERR_FAILED)); |
| 77 return; | 103 return; |
| 78 } | 104 } |
| 79 | 105 |
| 80 DCHECK(!input_stream_reader_); | 106 scoped_ptr<InputStreamReader> input_stream_reader( |
| 81 input_stream_reader_ = CreateStreamReader(stream_.get()); | 107 CreateStreamReader(stream.get())); |
| 82 CHECK(input_stream_reader_); | 108 DCHECK(input_stream_reader); |
| 109 |
| 110 DCHECK(!input_stream_reader_wrapper_); |
| 111 input_stream_reader_wrapper_ = |
| 112 new InputStreamReaderWrapper(stream.Pass(), input_stream_reader.Pass()); |
| 83 | 113 |
| 84 PostTaskAndReplyWithResult( | 114 PostTaskAndReplyWithResult( |
| 85 GetWorkerThreadRunner(), | 115 GetWorkerThreadRunner(), |
| 86 FROM_HERE, | 116 FROM_HERE, |
| 87 base::Bind(&InputStreamReader::Seek, input_stream_reader_, byte_range_), | 117 base::Bind(&InputStreamReaderWrapper::Seek, |
| 118 input_stream_reader_wrapper_, |
| 119 byte_range_), |
| 88 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted, | 120 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted, |
| 89 weak_factory_.GetWeakPtr())); | 121 weak_factory_.GetWeakPtr())); |
| 90 } | 122 } |
| 91 | 123 |
| 92 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted( | 124 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) { |
| 93 int result) { | |
| 94 // Clear the IO_PENDING status set in Start(). | 125 // Clear the IO_PENDING status set in Start(). |
| 95 SetStatus(net::URLRequestStatus()); | 126 SetStatus(net::URLRequestStatus()); |
| 96 if (result >= 0) { | 127 if (result >= 0) { |
| 97 set_expected_content_size(result); | 128 set_expected_content_size(result); |
| 98 NotifyHeadersComplete(); | 129 NotifyHeadersComplete(); |
| 99 } else { | 130 } else { |
| 100 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); | 131 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); |
| 101 } | 132 } |
| 102 } | 133 } |
| 103 | 134 |
| 104 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted( | 135 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) { |
| 105 int result) { | |
| 106 // The URLRequest API contract requires that: | 136 // The URLRequest API contract requires that: |
| 107 // * NotifyDone be called once, to set the status code, indicate the job is | 137 // * NotifyDone be called once, to set the status code, indicate the job is |
| 108 // finished (there will be no further IO), | 138 // finished (there will be no further IO), |
| 109 // * NotifyReadComplete be called if false is returned from ReadRawData to | 139 // * NotifyReadComplete be called if false is returned from ReadRawData to |
| 110 // indicate that the IOBuffer will not be used by the job anymore. | 140 // indicate that the IOBuffer will not be used by the job anymore. |
| 111 // There might be multiple calls to ReadRawData (and thus multiple calls to | 141 // There might be multiple calls to ReadRawData (and thus multiple calls to |
| 112 // NotifyReadComplete), which is why NotifyDone is called only on errors | 142 // NotifyReadComplete), which is why NotifyDone is called only on errors |
| 113 // (result < 0) and end of data (result == 0). | 143 // (result < 0) and end of data (result == 0). |
| 114 if (result == 0) { | 144 if (result == 0) { |
| 115 NotifyDone(net::URLRequestStatus()); | 145 NotifyDone(net::URLRequestStatus()); |
| 116 } else if (result < 0) { | 146 } else if (result < 0) { |
| 117 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); | 147 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); |
| 118 } else { | 148 } else { |
| 119 // Clear the IO_PENDING status. | 149 // Clear the IO_PENDING status. |
| 120 SetStatus(net::URLRequestStatus()); | 150 SetStatus(net::URLRequestStatus()); |
| 121 } | 151 } |
| 122 NotifyReadComplete(result); | 152 NotifyReadComplete(result); |
| 123 } | 153 } |
| 124 | 154 |
| 125 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { | 155 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { |
| 126 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); | 156 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); |
| 127 } | 157 } |
| 128 | 158 |
| 129 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, | 159 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, |
| 130 int dest_size, | 160 int dest_size, |
| 131 int* bytes_read) { | 161 int* bytes_read) { |
| 132 DCHECK(input_stream_reader_); | 162 DCHECK(input_stream_reader_wrapper_); |
| 133 | 163 |
| 134 PostTaskAndReplyWithResult( | 164 PostTaskAndReplyWithResult( |
| 135 GetWorkerThreadRunner(), | 165 GetWorkerThreadRunner(), |
| 136 FROM_HERE, | 166 FROM_HERE, |
| 137 base::Bind(&InputStreamReader::ReadRawData, | 167 base::Bind(&InputStreamReaderWrapper::ReadRawData, |
| 138 input_stream_reader_, | 168 input_stream_reader_wrapper_, |
| 139 base::Unretained(dest), | 169 base::Unretained(dest), |
| 140 dest_size), | 170 dest_size), |
| 141 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, | 171 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, |
| 142 weak_factory_.GetWeakPtr())); | 172 weak_factory_.GetWeakPtr())); |
| 143 | 173 |
| 144 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); | 174 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); |
| 145 return false; | 175 return false; |
| 146 } | 176 } |
| 147 | 177 |
| 148 bool AndroidStreamReaderURLRequestJob::GetMimeType( | 178 bool AndroidStreamReaderURLRequestJob::GetMimeType( |
| 149 std::string* mime_type) const { | 179 std::string* mime_type) const { |
| 150 JNIEnv* env = AttachCurrentThread(); | 180 JNIEnv* env = AttachCurrentThread(); |
| 151 DCHECK(env); | 181 DCHECK(env); |
| 152 | 182 |
| 153 if (!stream_) | 183 if (!input_stream_reader_wrapper_) |
| 154 return false; | 184 return false; |
| 155 | 185 |
| 156 return delegate_->GetMimeType(env, request(), *stream_, mime_type); | 186 return delegate_->GetMimeType( |
| 187 env, request(), input_stream_reader_wrapper_->input_stream(), mime_type); |
| 157 } | 188 } |
| 158 | 189 |
| 159 bool AndroidStreamReaderURLRequestJob::GetCharset( | 190 bool AndroidStreamReaderURLRequestJob::GetCharset(std::string* charset) { |
| 160 std::string* charset) { | |
| 161 JNIEnv* env = AttachCurrentThread(); | 191 JNIEnv* env = AttachCurrentThread(); |
| 162 DCHECK(env); | 192 DCHECK(env); |
| 163 | 193 |
| 164 if (!stream_) | 194 if (!input_stream_reader_wrapper_) |
| 165 return false; | 195 return false; |
| 166 | 196 |
| 167 return delegate_->GetCharset(env, request(), *stream_, charset); | 197 return delegate_->GetCharset( |
| 198 env, request(), input_stream_reader_wrapper_->input_stream(), charset); |
| 168 } | 199 } |
| 169 | 200 |
| 170 void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders( | 201 void AndroidStreamReaderURLRequestJob::SetExtraRequestHeaders( |
| 171 const net::HttpRequestHeaders& headers) { | 202 const net::HttpRequestHeaders& headers) { |
| 172 std::string range_header; | 203 std::string range_header; |
| 173 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { | 204 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { |
| 174 // We only extract the "Range" header so that we know how many bytes in the | 205 // We only extract the "Range" header so that we know how many bytes in the |
| 175 // stream to skip and how many to read after that. | 206 // stream to skip and how many to read after that. |
| 176 std::vector<net::HttpByteRange> ranges; | 207 std::vector<net::HttpByteRange> ranges; |
| 177 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { | 208 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { |
| 178 if (ranges.size() == 1) { | 209 if (ranges.size() == 1) { |
| 179 byte_range_ = ranges[0]; | 210 byte_range_ = ranges[0]; |
| 180 } else { | 211 } else { |
| 181 // We don't support multiple range requests in one single URL request, | 212 // We don't support multiple range requests in one single URL request, |
| 182 // because we need to do multipart encoding here. | 213 // because we need to do multipart encoding here. |
| 183 NotifyDone(net::URLRequestStatus( | 214 NotifyDone(net::URLRequestStatus( |
| 184 net::URLRequestStatus::FAILED, | 215 net::URLRequestStatus::FAILED, |
| 185 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); | 216 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); |
| 186 } | 217 } |
| 187 } | 218 } |
| 188 } | 219 } |
| 189 } | 220 } |
| OLD | NEW |