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

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: use request restart to fall-through to other handlers 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"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 private: 61 private:
62 friend class base::RefCountedThreadSafe<InputStreamReaderWrapper>; 62 friend class base::RefCountedThreadSafe<InputStreamReaderWrapper>;
63 ~InputStreamReaderWrapper() {} 63 ~InputStreamReaderWrapper() {}
64 64
65 scoped_ptr<android_webview::InputStream> input_stream_; 65 scoped_ptr<android_webview::InputStream> input_stream_;
66 scoped_ptr<android_webview::InputStreamReader> input_stream_reader_; 66 scoped_ptr<android_webview::InputStreamReader> input_stream_reader_;
67 67
68 DISALLOW_COPY_AND_ASSIGN(InputStreamReaderWrapper); 68 DISALLOW_COPY_AND_ASSIGN(InputStreamReaderWrapper);
69 }; 69 };
70 70
71 // In unittests the Job isn't created on the IO thread making it slightly
72 // harder to post back to the job's thread. We use a helper data structure to
73 // be able to use PostTaskAndReplyWithResult with OpenInputStreamOnWorkerThread
74 // which will take care of posting back to the Job's thread.
75 struct AndroidStreamReaderURLRequestJob::OpenInputStreamResult {
mnaganov (inactive) 2013/03/06 09:26:47 Is this about C++ or Java unittests? If C++, perha
mkosiba (inactive) 2013/03/06 19:05:27 C++ unittests. So it looks all of the remaining jo
76 scoped_ptr<InputStream> input_stream;
77 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate> delegate;
78 };
79
71 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob( 80 AndroidStreamReaderURLRequestJob::AndroidStreamReaderURLRequestJob(
72 net::URLRequest* request, 81 net::URLRequest* request,
73 net::NetworkDelegate* network_delegate, 82 net::NetworkDelegate* network_delegate,
74 scoped_ptr<Delegate> delegate) 83 scoped_ptr<Delegate> delegate)
75 : URLRequestJob(request, network_delegate), 84 : URLRequestJob(request, network_delegate),
76 delegate_(delegate.Pass()), 85 delegate_(delegate.Pass()),
77 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 86 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
78 DCHECK(delegate_); 87 DCHECK(delegate_);
79 } 88 }
80 89
81 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() { 90 AndroidStreamReaderURLRequestJob::~AndroidStreamReaderURLRequestJob() {
82 } 91 }
83 92
93 // static
94 scoped_ptr<AndroidStreamReaderURLRequestJob::OpenInputStreamResult>
95 AndroidStreamReaderURLRequestJob::OpenInputStreamOnWorkerThread(
96 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate> delegate,
97 const GURL& url) {
98 JNIEnv* env = AttachCurrentThread();
99 DCHECK(env);
100
101 scoped_ptr<AndroidStreamReaderURLRequestJob::OpenInputStreamResult> result(
102 new AndroidStreamReaderURLRequestJob::OpenInputStreamResult());
103 result->input_stream = delegate->OpenInputStream(env, url);
104 result->delegate = delegate.Pass();
105 return result.Pass();
106 }
107
84 void AndroidStreamReaderURLRequestJob::Start() { 108 void AndroidStreamReaderURLRequestJob::Start() {
109 DCHECK(thread_checker_.CalledOnValidThread());
85 // Start reading asynchronously so that all error reporting and data 110 // Start reading asynchronously so that all error reporting and data
86 // callbacks happen as they would for network requests. 111 // callbacks happen as they would for network requests.
87 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 112 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING,
88 net::ERR_IO_PENDING)); 113 net::ERR_IO_PENDING));
89 MessageLoop::current()->PostTask( 114
115 // This could be done in the InputStreamReader but would force more
116 // complex synchronization in the delegate.
117 PostTaskAndReplyWithResult(
118 GetWorkerThreadRunner(),
90 FROM_HERE, 119 FROM_HERE,
91 base::Bind( 120 base::Bind(
92 &AndroidStreamReaderURLRequestJob::StartAsync, 121 &OpenInputStreamOnWorkerThread,
93 weak_factory_.GetWeakPtr())); 122 // This is intentional - the job could be deleted while the callback
123 // is executing on the background thread.
124 // The delegate will be "returned" to the job once the InputStream
125 // open attempt is completed.
126 base::Passed(&delegate_),
boliu 2013/03/06 02:30:18 How bad is it to make delegate RefCountedThreadSaf
mkosiba (inactive) 2013/03/06 19:05:27 but the delegate _isn't_ thread safe. I actually l
127 request()->url()),
128 base::Bind(&AndroidStreamReaderURLRequestJob::OnInputStreamOpened,
129 weak_factory_.GetWeakPtr()));
94 } 130 }
95 131
96 void AndroidStreamReaderURLRequestJob::Kill() { 132 void AndroidStreamReaderURLRequestJob::Kill() {
133 DCHECK(thread_checker_.CalledOnValidThread());
97 weak_factory_.InvalidateWeakPtrs(); 134 weak_factory_.InvalidateWeakPtrs();
98 URLRequestJob::Kill(); 135 URLRequestJob::Kill();
99 } 136 }
100 137
101 scoped_ptr<InputStreamReader> 138 scoped_ptr<InputStreamReader>
102 AndroidStreamReaderURLRequestJob::CreateStreamReader(InputStream* stream) { 139 AndroidStreamReaderURLRequestJob::CreateStreamReader(InputStream* stream) {
103 return make_scoped_ptr(new InputStreamReader(stream)); 140 return make_scoped_ptr(new InputStreamReader(stream));
104 } 141 }
105 142
106 void AndroidStreamReaderURLRequestJob::StartAsync() { 143 void AndroidStreamReaderURLRequestJob::OnInputStreamOpened(
107 JNIEnv* env = AttachCurrentThread(); 144 scoped_ptr<OpenInputStreamResult> result) {
108 DCHECK(env); 145 DCHECK(thread_checker_.CalledOnValidThread());
146 DCHECK(result->delegate);
147 delegate_ = result->delegate.Pass();
148 scoped_ptr<InputStream> input_stream = result->input_stream.Pass();
109 149
110 // This could be done in the InputStreamReader but would force more 150 if (!input_stream) {
111 // complex synchronization in the delegate. 151 bool restart_required = false;
112 scoped_ptr<android_webview::InputStream> stream( 152 delegate_->OnInputStreamOpenFailed(request(), &restart_required);
113 delegate_->OpenInputStream(env, request())); 153 if (restart_required) {
114 154 NotifyRestartRequired();
115 if (!stream) { 155 } else {
116 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, 156 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
117 net::ERR_FAILED)); 157 net::ERR_FAILED));
158 }
118 return; 159 return;
119 } 160 }
120 161
121 scoped_ptr<InputStreamReader> input_stream_reader( 162 scoped_ptr<InputStreamReader> input_stream_reader(
122 CreateStreamReader(stream.get())); 163 CreateStreamReader(input_stream.get()));
123 DCHECK(input_stream_reader); 164 DCHECK(input_stream_reader);
124 165
125 DCHECK(!input_stream_reader_wrapper_); 166 DCHECK(!input_stream_reader_wrapper_);
126 input_stream_reader_wrapper_ = 167 input_stream_reader_wrapper_ = new InputStreamReaderWrapper(
127 new InputStreamReaderWrapper(stream.Pass(), input_stream_reader.Pass()); 168 input_stream.Pass(), input_stream_reader.Pass());
128 169
129 PostTaskAndReplyWithResult( 170 PostTaskAndReplyWithResult(
130 GetWorkerThreadRunner(), 171 GetWorkerThreadRunner(),
131 FROM_HERE, 172 FROM_HERE,
132 base::Bind(&InputStreamReaderWrapper::Seek, 173 base::Bind(&InputStreamReaderWrapper::Seek,
133 input_stream_reader_wrapper_, 174 input_stream_reader_wrapper_,
134 byte_range_), 175 byte_range_),
135 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted, 176 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted,
136 weak_factory_.GetWeakPtr())); 177 weak_factory_.GetWeakPtr()));
137 } 178 }
138 179
139 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) { 180 void AndroidStreamReaderURLRequestJob::OnReaderSeekCompleted(int result) {
181 DCHECK(thread_checker_.CalledOnValidThread());
140 // Clear the IO_PENDING status set in Start(). 182 // Clear the IO_PENDING status set in Start().
141 SetStatus(net::URLRequestStatus()); 183 SetStatus(net::URLRequestStatus());
142 if (result >= 0) { 184 if (result >= 0) {
143 set_expected_content_size(result); 185 set_expected_content_size(result);
144 NotifyHeadersComplete(); 186 NotifyHeadersComplete();
145 } else { 187 } else {
146 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 188 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
147 } 189 }
148 } 190 }
149 191
150 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) { 192 void AndroidStreamReaderURLRequestJob::OnReaderReadCompleted(int result) {
193 DCHECK(thread_checker_.CalledOnValidThread());
151 // The URLRequest API contract requires that: 194 // The URLRequest API contract requires that:
152 // * NotifyDone be called once, to set the status code, indicate the job is 195 // * NotifyDone be called once, to set the status code, indicate the job is
153 // finished (there will be no further IO), 196 // finished (there will be no further IO),
154 // * NotifyReadComplete be called if false is returned from ReadRawData to 197 // * NotifyReadComplete be called if false is returned from ReadRawData to
155 // indicate that the IOBuffer will not be used by the job anymore. 198 // 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 199 // There might be multiple calls to ReadRawData (and thus multiple calls to
157 // NotifyReadComplete), which is why NotifyDone is called only on errors 200 // NotifyReadComplete), which is why NotifyDone is called only on errors
158 // (result < 0) and end of data (result == 0). 201 // (result < 0) and end of data (result == 0).
159 if (result == 0) { 202 if (result == 0) {
160 NotifyDone(net::URLRequestStatus()); 203 NotifyDone(net::URLRequestStatus());
161 } else if (result < 0) { 204 } else if (result < 0) {
162 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); 205 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
163 } else { 206 } else {
164 // Clear the IO_PENDING status. 207 // Clear the IO_PENDING status.
165 SetStatus(net::URLRequestStatus()); 208 SetStatus(net::URLRequestStatus());
166 } 209 }
167 NotifyReadComplete(result); 210 NotifyReadComplete(result);
168 } 211 }
169 212
170 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() { 213 base::TaskRunner* AndroidStreamReaderURLRequestJob::GetWorkerThreadRunner() {
171 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool()); 214 return static_cast<base::TaskRunner*>(BrowserThread::GetBlockingPool());
172 } 215 }
173 216
174 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest, 217 bool AndroidStreamReaderURLRequestJob::ReadRawData(net::IOBuffer* dest,
175 int dest_size, 218 int dest_size,
176 int* bytes_read) { 219 int* bytes_read) {
220 DCHECK(thread_checker_.CalledOnValidThread());
177 DCHECK(input_stream_reader_wrapper_); 221 DCHECK(input_stream_reader_wrapper_);
178 222
179 PostTaskAndReplyWithResult( 223 PostTaskAndReplyWithResult(
180 GetWorkerThreadRunner(), 224 GetWorkerThreadRunner(),
181 FROM_HERE, 225 FROM_HERE,
182 base::Bind(&InputStreamReaderWrapper::ReadRawData, 226 base::Bind(&InputStreamReaderWrapper::ReadRawData,
183 input_stream_reader_wrapper_, 227 input_stream_reader_wrapper_,
184 make_scoped_refptr(dest), 228 make_scoped_refptr(dest),
185 dest_size), 229 dest_size),
186 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted, 230 base::Bind(&AndroidStreamReaderURLRequestJob::OnReaderReadCompleted,
187 weak_factory_.GetWeakPtr())); 231 weak_factory_.GetWeakPtr()));
188 232
189 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 233 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING,
190 net::ERR_IO_PENDING)); 234 net::ERR_IO_PENDING));
191 return false; 235 return false;
192 } 236 }
193 237
194 bool AndroidStreamReaderURLRequestJob::GetMimeType( 238 bool AndroidStreamReaderURLRequestJob::GetMimeType(
195 std::string* mime_type) const { 239 std::string* mime_type) const {
240 DCHECK(thread_checker_.CalledOnValidThread());
196 JNIEnv* env = AttachCurrentThread(); 241 JNIEnv* env = AttachCurrentThread();
197 DCHECK(env); 242 DCHECK(env);
198 243
199 if (!input_stream_reader_wrapper_) 244 if (!input_stream_reader_wrapper_)
200 return false; 245 return false;
201 246
202 // Since it's possible for this call to alter the InputStream a 247 // Since it's possible for this call to alter the InputStream a
203 // Seek or ReadRawData operation running in the background is not permitted. 248 // Seek or ReadRawData operation running in the background is not permitted.
204 DCHECK(!request_->status().is_io_pending()); 249 DCHECK(!request_->status().is_io_pending());
205 250
206 return delegate_->GetMimeType( 251 return delegate_->GetMimeType(
207 env, request(), input_stream_reader_wrapper_->input_stream(), mime_type); 252 env, request(), input_stream_reader_wrapper_->input_stream(), mime_type);
208 } 253 }
209 254
210 bool AndroidStreamReaderURLRequestJob::GetCharset(std::string* charset) { 255 bool AndroidStreamReaderURLRequestJob::GetCharset(std::string* charset) {
256 DCHECK(thread_checker_.CalledOnValidThread());
211 JNIEnv* env = AttachCurrentThread(); 257 JNIEnv* env = AttachCurrentThread();
212 DCHECK(env); 258 DCHECK(env);
213 259
214 if (!input_stream_reader_wrapper_) 260 if (!input_stream_reader_wrapper_)
215 return false; 261 return false;
216 262
217 // Since it's possible for this call to alter the InputStream a 263 // Since it's possible for this call to alter the InputStream a
218 // Seek or ReadRawData operation running in the background is not permitted. 264 // Seek or ReadRawData operation running in the background is not permitted.
219 DCHECK(!request_->status().is_io_pending()); 265 DCHECK(!request_->status().is_io_pending());
220 266
(...skipping 14 matching lines...) Expand all
235 } else { 281 } else {
236 // We don't support multiple range requests in one single URL request, 282 // We don't support multiple range requests in one single URL request,
237 // because we need to do multipart encoding here. 283 // because we need to do multipart encoding here.
238 NotifyDone(net::URLRequestStatus( 284 NotifyDone(net::URLRequestStatus(
239 net::URLRequestStatus::FAILED, 285 net::URLRequestStatus::FAILED,
240 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); 286 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
241 } 287 }
242 } 288 }
243 } 289 }
244 } 290 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698