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

Side by Side Diff: storage/browser/blob/blob_url_request_job.cc

Issue 2906543002: Add support for reading blobs when using the network service. (Closed)
Patch Set: fix threading issue with weakptr Created 3 years, 6 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
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 "storage/browser/blob/blob_url_request_job.h" 5 #include "storage/browser/blob/blob_url_request_job.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <limits> 10 #include <limits>
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 } else { 136 } else {
137 // We don't support multiple range requests in one single URL request, 137 // We don't support multiple range requests in one single URL request,
138 // because we need to do multipart encoding here. 138 // because we need to do multipart encoding here.
139 // TODO(jianli): Support multipart byte range requests. 139 // TODO(jianli): Support multipart byte range requests.
140 NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); 140 NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE);
141 } 141 }
142 } 142 }
143 } 143 }
144 } 144 }
145 145
146 scoped_refptr<net::HttpResponseHeaders> BlobURLRequestJob::GenerateHeaders(
147 net::HttpStatusCode status_code,
148 BlobDataHandle* blob_handle,
149 BlobReader* blob_reader,
150 net::HttpByteRange* byte_range,
151 int64_t* content_size) {
152 std::string status("HTTP/1.1 ");
153 status.append(base::IntToString(status_code));
154 status.append(" ");
155 status.append(net::GetHttpReasonPhrase(status_code));
156 status.append("\0\0", 2);
157 scoped_refptr<net::HttpResponseHeaders> headers =
158 new net::HttpResponseHeaders(status);
159
160 if (status_code == net::HTTP_OK || status_code == net::HTTP_PARTIAL_CONTENT) {
161 *content_size = blob_reader->remaining_bytes();
162 std::string content_length_header(net::HttpRequestHeaders::kContentLength);
163 content_length_header.append(": ");
164 content_length_header.append(base::Int64ToString(*content_size));
165 headers->AddHeader(content_length_header);
166 if (status_code == net::HTTP_PARTIAL_CONTENT) {
167 DCHECK(byte_range->IsValid());
168 std::string content_range_header(net::HttpResponseHeaders::kContentRange);
169 content_range_header.append(": bytes ");
170 content_range_header.append(base::StringPrintf(
171 "%" PRId64 "-%" PRId64, byte_range->first_byte_position(),
172 byte_range->last_byte_position()));
173 content_range_header.append("/");
174 content_range_header.append(
175 base::StringPrintf("%" PRId64, blob_reader->total_size()));
176 headers->AddHeader(content_range_header);
177 }
178 if (!blob_handle->content_type().empty()) {
179 std::string content_type_header(net::HttpRequestHeaders::kContentType);
180 content_type_header.append(": ");
181 content_type_header.append(blob_handle->content_type());
182 headers->AddHeader(content_type_header);
183 }
184 if (!blob_handle->content_disposition().empty()) {
185 std::string content_disposition_header("Content-Disposition: ");
186 content_disposition_header.append(blob_handle->content_disposition());
187 headers->AddHeader(content_disposition_header);
188 }
189 }
190
191 return headers;
192 }
193
194 net::HttpStatusCode BlobURLRequestJob::NetErrorToHttpStatusCode(
195 int error_code) {
196 net::HttpStatusCode status_code = net::HTTP_INTERNAL_SERVER_ERROR;
197 switch (error_code) {
198 case net::ERR_ACCESS_DENIED:
199 status_code = net::HTTP_FORBIDDEN;
200 break;
201 case net::ERR_FILE_NOT_FOUND:
202 status_code = net::HTTP_NOT_FOUND;
203 break;
204 case net::ERR_METHOD_NOT_SUPPORTED:
205 status_code = net::HTTP_METHOD_NOT_ALLOWED;
206 break;
207 case net::ERR_REQUEST_RANGE_NOT_SATISFIABLE:
208 status_code = net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE;
209 break;
210 case net::ERR_INVALID_ARGUMENT:
211 status_code = net::HTTP_BAD_REQUEST;
212 break;
213 case net::ERR_CACHE_READ_FAILURE:
214 case net::ERR_CACHE_CHECKSUM_READ_FAILURE:
215 case net::ERR_UNEXPECTED:
216 case net::ERR_FAILED:
217 break;
218 default:
219 DCHECK(false) << "Error code not supported: " << error_code;
220 break;
221 }
222 return status_code;
223 }
224
146 BlobURLRequestJob::~BlobURLRequestJob() { 225 BlobURLRequestJob::~BlobURLRequestJob() {
147 TRACE_EVENT_ASYNC_END1("Blob", "BlobRequest", this, "uuid", 226 TRACE_EVENT_ASYNC_END1("Blob", "BlobRequest", this, "uuid",
148 blob_handle_ ? blob_handle_->uuid() : "NotFound"); 227 blob_handle_ ? blob_handle_->uuid() : "NotFound");
149 } 228 }
150 229
151 void BlobURLRequestJob::DidStart() { 230 void BlobURLRequestJob::DidStart() {
152 error_ = false; 231 error_ = false;
153 232
154 // We only support GET request per the spec. 233 // We only support GET request per the spec.
155 if (request()->method() != "GET") { 234 if (request()->method() != "GET") {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 ReadRawDataComplete(result); 316 ReadRawDataComplete(result);
238 } 317 }
239 318
240 void BlobURLRequestJob::NotifyFailure(int error_code) { 319 void BlobURLRequestJob::NotifyFailure(int error_code) {
241 error_ = true; 320 error_ = true;
242 321
243 // If we already return the headers on success, we can't change the headers 322 // If we already return the headers on success, we can't change the headers
244 // now. Instead, we just error out. 323 // now. Instead, we just error out.
245 DCHECK(!response_info_) << "Cannot NotifyFailure after headers."; 324 DCHECK(!response_info_) << "Cannot NotifyFailure after headers.";
246 325
247 net::HttpStatusCode status_code = net::HTTP_INTERNAL_SERVER_ERROR; 326 HeadersCompleted(NetErrorToHttpStatusCode(error_code));
248 switch (error_code) {
249 case net::ERR_ACCESS_DENIED:
250 status_code = net::HTTP_FORBIDDEN;
251 break;
252 case net::ERR_FILE_NOT_FOUND:
253 status_code = net::HTTP_NOT_FOUND;
254 break;
255 case net::ERR_METHOD_NOT_SUPPORTED:
256 status_code = net::HTTP_METHOD_NOT_ALLOWED;
257 break;
258 case net::ERR_REQUEST_RANGE_NOT_SATISFIABLE:
259 status_code = net::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE;
260 break;
261 case net::ERR_INVALID_ARGUMENT:
262 status_code = net::HTTP_BAD_REQUEST;
263 break;
264 case net::ERR_CACHE_READ_FAILURE:
265 case net::ERR_CACHE_CHECKSUM_READ_FAILURE:
266 case net::ERR_UNEXPECTED:
267 case net::ERR_FAILED:
268 break;
269 default:
270 DCHECK(false) << "Error code not supported: " << error_code;
271 break;
272 }
273 HeadersCompleted(status_code);
274 } 327 }
275 328
276 void BlobURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) { 329 void BlobURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) {
277 std::string status("HTTP/1.1 "); 330 int64_t content_size = 0;
278 status.append(base::IntToString(status_code));
279 status.append(" ");
280 status.append(net::GetHttpReasonPhrase(status_code));
281 status.append("\0\0", 2);
282 net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
283
284 set_expected_content_size(0);
285
286 if (status_code == net::HTTP_OK || status_code == net::HTTP_PARTIAL_CONTENT) {
287 set_expected_content_size(blob_reader_->remaining_bytes());
288 std::string content_length_header(net::HttpRequestHeaders::kContentLength);
289 content_length_header.append(": ");
290 content_length_header.append(
291 base::Int64ToString(blob_reader_->remaining_bytes()));
292 headers->AddHeader(content_length_header);
293 if (status_code == net::HTTP_PARTIAL_CONTENT) {
294 DCHECK(byte_range_set_);
295 DCHECK(byte_range_.IsValid());
296 std::string content_range_header(net::HttpResponseHeaders::kContentRange);
297 content_range_header.append(": bytes ");
298 content_range_header.append(base::StringPrintf(
299 "%" PRId64 "-%" PRId64, byte_range_.first_byte_position(),
300 byte_range_.last_byte_position()));
301 content_range_header.append("/");
302 content_range_header.append(
303 base::StringPrintf("%" PRId64, blob_reader_->total_size()));
304 headers->AddHeader(content_range_header);
305 }
306 if (!blob_handle_->content_type().empty()) {
307 std::string content_type_header(net::HttpRequestHeaders::kContentType);
308 content_type_header.append(": ");
309 content_type_header.append(blob_handle_->content_type());
310 headers->AddHeader(content_type_header);
311 }
312 if (!blob_handle_->content_disposition().empty()) {
313 std::string content_disposition_header("Content-Disposition: ");
314 content_disposition_header.append(blob_handle_->content_disposition());
315 headers->AddHeader(content_disposition_header);
316 }
317 }
318
319 response_info_.reset(new net::HttpResponseInfo()); 331 response_info_.reset(new net::HttpResponseInfo());
320 response_info_->headers = headers; 332 response_info_->headers =
333 GenerateHeaders(status_code, blob_handle_.get(), blob_reader_.get(),
334 &byte_range_, &content_size);
335 set_expected_content_size(content_size);
321 if (blob_reader_) 336 if (blob_reader_)
322 response_info_->metadata = blob_reader_->side_data(); 337 response_info_->metadata = blob_reader_->side_data();
323 338
324 NotifyHeadersComplete(); 339 NotifyHeadersComplete();
325 } 340 }
326 341
327 } // namespace storage 342 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/blob/blob_url_request_job.h ('k') | storage/browser/blob/blob_url_request_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698