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

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

Issue 12377051: [android_webview] Don't intercept resource and asset URLRequests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 9 months 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 | Annotate | Revision Log
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 "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"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/message_loop_proxy.h"
15 #include "base/task_runner.h" 16 #include "base/task_runner.h"
16 #include "base/threading/sequenced_worker_pool.h" 17 #include "base/threading/sequenced_worker_pool.h"
17 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
18 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
19 #include "net/base/io_buffer.h" 20 #include "net/base/io_buffer.h"
20 #include "net/base/mime_util.h" 21 #include "net/base/mime_util.h"
21 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
22 #include "net/base/net_util.h" 23 #include "net/base/net_util.h"
23 #include "net/http/http_util.h" 24 #include "net/http/http_util.h"
24 #include "net/url_request/url_request.h" 25 #include "net/url_request/url_request.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 scoped_ptr<Delegate> delegate) 75 scoped_ptr<Delegate> delegate)
75 : URLRequestJob(request, network_delegate), 76 : URLRequestJob(request, network_delegate),
76 delegate_(delegate.Pass()), 77 delegate_(delegate.Pass()),
77 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 78 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
78 DCHECK(delegate_); 79 DCHECK(delegate_);
79 } 80 }
80 81
81 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { 82 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() {
82 } 83 }
83 84
85 namespace {
86
87 typedef base::Callback<
88 void(scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>,
89 scoped_ptr<InputStream>)> OnInputStreamOpenedCallback;
90
91 // static
92 void OpenInputStreamOnWorkerThread(
93 scoped_refptr<base::MessageLoopProxy> job_thread_proxy,
94 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate> delegate,
95 const GURL& url,
96 OnInputStreamOpenedCallback callback) {
97
98 JNIEnv* env = AttachCurrentThread();
99 DCHECK(env);
100
101 scoped_ptr<InputStream> input_stream = delegate->OpenInputStream(env, url);
102 job_thread_proxy->PostTask(FROM_HERE,
103 base::Bind(callback,
104 base::Passed(delegate.Pass()),
105 base::Passed(input_stream.Pass())));
106 }
107
108 } // namespace
109
84 void AndroidStreamReaderURLRequestJob::Start() { 110 void AndroidStreamReaderURLRequestJob::Start() {
111 DCHECK(thread_checker_.CalledOnValidThread());
85 // Start reading asynchronously so that all error reporting and data 112 // Start reading asynchronously so that all error reporting and data
86 // callbacks happen as they would for network requests. 113 // callbacks happen as they would for network requests.
87 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 114 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING,
88 net::ERR_IO_PENDING)); 115 net::ERR_IO_PENDING));
89 MessageLoop::current()->PostTask( 116
117 // This could be done in the InputStreamReader but would force more
118 // complex synchronization in the delegate.
119 GetWorkerThreadRunner()->PostTask(
90 FROM_HERE, 120 FROM_HERE,
91 base::Bind( 121 base::Bind(
92 &AndroidStreamReaderURLRequestJob::StartAsync, 122 &OpenInputStreamOnWorkerThread,
93 weak_factory_.GetWeakPtr())); 123 MessageLoop::current()->message_loop_proxy(),
124 // This is intentional - the job could be deleted while the callback
125 // is executing on the background thread.
126 // The delegate will be "returned" to the job once the InputStream
127 // open attempt is completed.
128 base::Passed(&delegate_),
129 request()->url(),
130 base::Bind(&AndroidStreamReaderURLRequestJob::OnInputStreamOpened,
131 weak_factory_.GetWeakPtr())));
94 } 132 }
95 133
96 void AndroidStreamReaderURLRequestJob::Kill() { 134 void AndroidStreamReaderURLRequestJob::Kill() {
135 DCHECK(thread_checker_.CalledOnValidThread());
97 weak_factory_.InvalidateWeakPtrs(); 136 weak_factory_.InvalidateWeakPtrs();
98 URLRequestJob::Kill(); 137 URLRequestJob::Kill();
99 } 138 }
100 139
101 scoped_ptr<InputStreamReader> 140 scoped_ptr<InputStreamReader>
102 AndroidStreamReaderURLRequestJob::CreateStreamReader(InputStream* stream) { 141 AndroidStreamReaderURLRequestJob::CreateStreamReader(InputStream* stream) {
103 return make_scoped_ptr(new InputStreamReader(stream)); 142 return make_scoped_ptr(new InputStreamReader(stream));
104 } 143 }
105 144
106 void AndroidStreamReaderURLRequestJob::StartAsync() { 145 void AndroidStreamReaderURLRequestJob::OnInputStreamOpened(
107 JNIEnv* env = AttachCurrentThread(); 146 scoped_ptr<Delegate> returned_delegate,
108 DCHECK(env); 147 scoped_ptr<android_webview::InputStream> input_stream) {
148 DCHECK(thread_checker_.CalledOnValidThread());
149 DCHECK(returned_delegate);
150 delegate_ = returned_delegate.Pass();
109 151
110 // This could be done in the InputStreamReader but would force more 152 if (!input_stream) {
111 // complex synchronization in the delegate. 153 bool restart_required = false;
112 scoped_ptr<android_webview::InputStream> stream( 154 delegate_->OnInputStreamOpenFailed(request(), &restart_required);
113 delegate_->OpenInputStream(env, request())); 155 if (restart_required) {
114 156 NotifyRestartRequired();
115 if (!stream) { 157 } else {
116 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, 158 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
117 net::ERR_FAILED)); 159 net::ERR_FAILED));
160 }
118 return; 161 return;
119 } 162 }
120 163
121 scoped_ptr<InputStreamReader> input_stream_reader( 164 scoped_ptr<InputStreamReader> input_stream_reader(
122 CreateStreamReader(stream.get())); 165 CreateStreamReader(input_stream.get()));
123 DCHECK(input_stream_reader); 166 DCHECK(input_stream_reader);
124 167
125 DCHECK(!input_stream_reader_wrapper_); 168 DCHECK(!input_stream_reader_wrapper_);
126 input_stream_reader_wrapper_ = 169 input_stream_reader_wrapper_ = new InputStreamReaderWrapper(
127 new InputStreamReaderWrapper(stream.Pass(), input_stream_reader.Pass()); 170 input_stream.Pass(), input_stream_reader.Pass());
128 171
129 PostTaskAndReplyWithResult( 172 PostTaskAndReplyWithResult(
130 GetWorkerThreadRunner(), 173 GetWorkerThreadRunner(),
131 FROM_HERE, 174 FROM_HERE,
132 base::Bind(&InputStreamReaderWrapper::Seek, 175 base::Bind(&InputStreamReaderWrapper::Seek,
133 input_stream_reader_wrapper_, 176 input_stream_reader_wrapper_,
134 byte_range_), 177 byte_range_),
135 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted, 178 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted,
136 weak_factory_.GetWeakPtr())); 179 weak_factory_.GetWeakPtr()));
137 } 180 }
138 181
139 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) { 182 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) {
183 DCHECK(thread_checker_.CalledOnValidThread());
140 // Clear the IO_PENDING status set in Start(). 184 // Clear the IO_PENDING status set in Start().
141 SetStatus(net::URLRequestStatus()); 185 SetStatus(net::URLRequestStatus());
142 if (result >= 0) { 186 if (result >= 0) {
143 set_expected_content_size(result); 187 set_expected_content_size(result);
144 NotifyHeadersComplete(); 188 NotifyHeadersComplete();
145 } else { 189 } else {
146 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 190 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
147 } 191 }
148 } 192 }
149 193
150 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) { 194 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) {
195 DCHECK(thread_checker_.CalledOnValidThread());
151 // The URLRequest API contract requires that: 196 // The URLRequest API contract requires that:
152 // * NotifyDone be called once, to set the status code, indicate the job is 197 // * NotifyDone be called once, to set the status code, indicate the job is
153 // finished (there will be no further IO), 198 // finished (there will be no further IO),
154 // * NotifyReadComplete be called if false is returned from ReadRawData to 199 // * NotifyReadComplete be called if false is returned from ReadRawData to
155 // indicate that the IOBuffer will not be used by the job anymore. 200 // indicate that the IOBuffer will not be used by the job anymore.
156 // There might be multiple calls to ReadRawData (and thus multiple calls to 201 // There might be multiple calls to ReadRawData (and thus multiple calls to
157 // NotifyReadComplete), which is why NotifyDone is called only on errors 202 // NotifyReadComplete), which is why NotifyDone is called only on errors
158 // (result < 0) and end of data (result == 0). 203 // (result < 0) and end of data (result == 0).
159 if (result == 0) { 204 if (result == 0) {
160 NotifyDone(net::URLRequestStatus()); 205 NotifyDone(net::URLRequestStatus());
161 } else if (result < 0) { 206 } else if (result < 0) {
162 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 207 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
163 } else { 208 } else {
164 // Clear the IO_PENDING status. 209 // Clear the IO_PENDING status.
165 SetStatus(net::URLRequestStatus()); 210 SetStatus(net::URLRequestStatus());
166 } 211 }
167 NotifyReadComplete(result); 212 NotifyReadComplete(result);
168 } 213 }
169 214
170 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { 215 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() {
171 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); 216 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool());
172 } 217 }
173 218
174 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, 219 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest,
175 int dest_size, 220 int dest_size,
176 int* bytes_read) { 221 int* bytes_read) {
222 DCHECK(thread_checker_.CalledOnValidThread());
177 DCHECK(input_stream_reader_wrapper_); 223 DCHECK(input_stream_reader_wrapper_);
178 224
179 PostTaskAndReplyWithResult( 225 PostTaskAndReplyWithResult(
180 GetWorkerThreadRunner(), 226 GetWorkerThreadRunner(),
181 FROM_HERE, 227 FROM_HERE,
182 base::Bind(&InputStreamReaderWrapper::ReadRawData, 228 base::Bind(&InputStreamReaderWrapper::ReadRawData,
183 input_stream_reader_wrapper_, 229 input_stream_reader_wrapper_,
184 make_scoped_refptr(dest), 230 make_scoped_refptr(dest),
185 dest_size), 231 dest_size),
186 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, 232 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted,
187 weak_factory_.GetWeakPtr())); 233 weak_factory_.GetWeakPtr()));
188 234
189 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 235 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING,
190 net::ERR_IO_PENDING)); 236 net::ERR_IO_PENDING));
191 return false; 237 return false;
192 } 238 }
193 239
194 bool AndroidStreamReaderURLRequestJob::GetMimeType( 240 bool AndroidStreamReaderURLRequestJob::GetMimeType(
195 std::string* mime_type) const { 241 std::string* mime_type) const {
242 DCHECK(thread_checker_.CalledOnValidThread());
196 JNIEnv* env = AttachCurrentThread(); 243 JNIEnv* env = AttachCurrentThread();
197 DCHECK(env); 244 DCHECK(env);
198 245
199 if (!input_stream_reader_wrapper_) 246 if (!input_stream_reader_wrapper_)
200 return false; 247 return false;
201 248
202 // Since it's possible for this call to alter the InputStream a 249 // Since it's possible for this call to alter the InputStream a
203 // Seek or ReadRawData operation running in the background is not permitted. 250 // Seek or ReadRawData operation running in the background is not permitted.
204 DCHECK(!request_->status().is_io_pending()); 251 DCHECK(!request_->status().is_io_pending());
205 252
206 return delegate_->GetMimeType( 253 return delegate_->GetMimeType(
207 env, request(), input_stream_reader_wrapper_->input_stream(), mime_type); 254 env, request(), input_stream_reader_wrapper_->input_stream(), mime_type);
208 } 255 }
209 256
210 bool AndroidStreamReaderURLRequestJob::GetCharset(std::string* charset) { 257 bool AndroidStreamReaderURLRequestJob::GetCharset(std::string* charset) {
258 DCHECK(thread_checker_.CalledOnValidThread());
211 JNIEnv* env = AttachCurrentThread(); 259 JNIEnv* env = AttachCurrentThread();
212 DCHECK(env); 260 DCHECK(env);
213 261
214 if (!input_stream_reader_wrapper_) 262 if (!input_stream_reader_wrapper_)
215 return false; 263 return false;
216 264
217 // Since it's possible for this call to alter the InputStream a 265 // Since it's possible for this call to alter the InputStream a
218 // Seek or ReadRawData operation running in the background is not permitted. 266 // Seek or ReadRawData operation running in the background is not permitted.
219 DCHECK(!request_->status().is_io_pending()); 267 DCHECK(!request_->status().is_io_pending());
220 268
(...skipping 14 matching lines...) Expand all
235 } else { 283 } else {
236 // We don't support multiple range requests in one single URL request, 284 // We don't support multiple range requests in one single URL request,
237 // because we need to do multipart encoding here. 285 // because we need to do multipart encoding here.
238 NotifyDone(net::URLRequestStatus( 286 NotifyDone(net::URLRequestStatus(
239 net::URLRequestStatus::FAILED, 287 net::URLRequestStatus::FAILED,
240 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); 288 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
241 } 289 }
242 } 290 }
243 } 291 }
244 } 292 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698