| 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 "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 Loading... |
| 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 |
| 146 BlobURLRequestJob::~BlobURLRequestJob() { | 194 BlobURLRequestJob::~BlobURLRequestJob() { |
| 147 TRACE_EVENT_ASYNC_END1("Blob", "BlobRequest", this, "uuid", | 195 TRACE_EVENT_ASYNC_END1("Blob", "BlobRequest", this, "uuid", |
| 148 blob_handle_ ? blob_handle_->uuid() : "NotFound"); | 196 blob_handle_ ? blob_handle_->uuid() : "NotFound"); |
| 149 } | 197 } |
| 150 | 198 |
| 151 void BlobURLRequestJob::DidStart() { | 199 void BlobURLRequestJob::DidStart() { |
| 152 error_ = false; | 200 error_ = false; |
| 153 | 201 |
| 154 // We only support GET request per the spec. | 202 // We only support GET request per the spec. |
| 155 if (request()->method() != "GET") { | 203 if (request()->method() != "GET") { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 case net::ERR_FAILED: | 315 case net::ERR_FAILED: |
| 268 break; | 316 break; |
| 269 default: | 317 default: |
| 270 DCHECK(false) << "Error code not supported: " << error_code; | 318 DCHECK(false) << "Error code not supported: " << error_code; |
| 271 break; | 319 break; |
| 272 } | 320 } |
| 273 HeadersCompleted(status_code); | 321 HeadersCompleted(status_code); |
| 274 } | 322 } |
| 275 | 323 |
| 276 void BlobURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) { | 324 void BlobURLRequestJob::HeadersCompleted(net::HttpStatusCode status_code) { |
| 277 std::string status("HTTP/1.1 "); | 325 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()); | 326 response_info_.reset(new net::HttpResponseInfo()); |
| 320 response_info_->headers = headers; | 327 response_info_->headers = |
| 328 GenerateHeaders(status_code, blob_handle_.get(), blob_reader_.get(), |
| 329 &byte_range_, &content_size); |
| 330 set_expected_content_size(content_size); |
| 321 if (blob_reader_) | 331 if (blob_reader_) |
| 322 response_info_->metadata = blob_reader_->side_data(); | 332 response_info_->metadata = blob_reader_->side_data(); |
| 323 | 333 |
| 324 NotifyHeadersComplete(); | 334 NotifyHeadersComplete(); |
| 325 } | 335 } |
| 326 | 336 |
| 327 } // namespace storage | 337 } // namespace storage |
| OLD | NEW |