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

Side by Side Diff: net/http/http_stream_parser.cc

Issue 2007013003: Introduce error handling in HttpStreamParser on UploadDataStream::Read() failure. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 "net/http/http_stream_parser.h" 5 #include "net/http/http_stream_parser.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // large enough to hold the encoded chunk. 266 // large enough to hold the encoded chunk.
267 request_body_read_buf_ = 267 request_body_read_buf_ =
268 new SeekableIOBuffer(kRequestBodyBufferSize - kChunkHeaderFooterSize); 268 new SeekableIOBuffer(kRequestBodyBufferSize - kChunkHeaderFooterSize);
269 } else { 269 } else {
270 // No need to encode request body, just send the raw data. 270 // No need to encode request body, just send the raw data.
271 request_body_read_buf_ = request_body_send_buf_; 271 request_body_read_buf_ = request_body_send_buf_;
272 } 272 }
273 } 273 }
274 274
275 io_state_ = STATE_SEND_HEADERS; 275 io_state_ = STATE_SEND_HEADERS;
276
277 // If we have a small request body, then we'll merge with the headers into a 276 // If we have a small request body, then we'll merge with the headers into a
278 // single write. 277 // single write.
279 bool did_merge = false; 278 bool did_merge = false;
280 if (ShouldMergeRequestHeadersAndBody(request, request_->upload_data_stream)) { 279 if (ShouldMergeRequestHeadersAndBody(request, request_->upload_data_stream)) {
281 int merged_size = static_cast<int>( 280 int merged_size = static_cast<int>(
282 request_headers_length_ + request_->upload_data_stream->size()); 281 request_headers_length_ + request_->upload_data_stream->size());
283 scoped_refptr<IOBuffer> merged_request_headers_and_body( 282 scoped_refptr<IOBuffer> merged_request_headers_and_body(
284 new IOBuffer(merged_size)); 283 new IOBuffer(merged_size));
285 // We'll repurpose |request_headers_| to store the merged headers and 284 // We'll repurpose |request_headers_| to store the merged headers and
286 // body. 285 // body.
287 request_headers_ = new DrainableIOBuffer( 286 request_headers_ = new DrainableIOBuffer(
288 merged_request_headers_and_body.get(), merged_size); 287 merged_request_headers_and_body.get(), merged_size);
289
290 memcpy(request_headers_->data(), request.data(), request_headers_length_); 288 memcpy(request_headers_->data(), request.data(), request_headers_length_);
291 request_headers_->DidConsume(request_headers_length_); 289 request_headers_->DidConsume(request_headers_length_);
292 290
293 uint64_t todo = request_->upload_data_stream->size(); 291 uint64_t todo = request_->upload_data_stream->size();
294 while (todo) { 292 while (todo) {
295 int consumed = request_->upload_data_stream->Read( 293 int result = request_->upload_data_stream->Read(
296 request_headers_.get(), static_cast<int>(todo), CompletionCallback()); 294 request_headers_.get(), static_cast<int>(todo), CompletionCallback());
297 DCHECK_GT(consumed, 0); // Read() won't fail if not chunked. 295 if (result == ERR_FILE_READ_FAIL)
298 request_headers_->DidConsume(consumed); 296 return result;
mmenke 2016/05/24 17:13:47 I think we can actually just keep the DCHECK here,
maksims (do not use this acc) 2016/05/25 07:13:38 Done.
299 todo -= consumed; 297 request_headers_->DidConsume(result);
298 todo -= result;
300 } 299 }
301 DCHECK(request_->upload_data_stream->IsEOF()); 300 DCHECK(request_->upload_data_stream->IsEOF());
302 // Reset the offset, so the buffer can be read from the beginning. 301 // Reset the offset, so the buffer can be read from the beginning.
303 request_headers_->SetOffset(0); 302 request_headers_->SetOffset(0);
304 did_merge = true; 303 did_merge = true;
305 304
306 net_log_.AddEvent( 305 net_log_.AddEvent(
307 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY, 306 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY,
308 base::Bind(&NetLogSendRequestBodyCallback, 307 base::Bind(&NetLogSendRequestBodyCallback,
309 request_->upload_data_stream->size(), 308 request_->upload_data_stream->size(),
310 false, /* not chunked */ 309 false, /* not chunked */
311 true /* merged */)); 310 true /* merged */));
312 } 311 }
313 312
314 if (!did_merge) { 313 if (!did_merge) {
315 // If we didn't merge the body with the headers, then |request_headers_| 314 // If we didn't merge the body with the headers, then |request_headers_|
316 // contains just the HTTP headers. 315 // contains just the HTTP headers.
317 scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request)); 316 scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request));
318 request_headers_ = 317 request_headers_ =
319 new DrainableIOBuffer(headers_io_buf.get(), headers_io_buf->size()); 318 new DrainableIOBuffer(headers_io_buf.get(), headers_io_buf->size());
320 } 319 }
321
322 result = DoLoop(OK); 320 result = DoLoop(OK);
mmenke 2016/05/24 17:13:47 Should keep these line break, for readability.
maksims (do not use this acc) 2016/05/25 07:13:38 Done.
323 if (result == ERR_IO_PENDING) 321 if (result == ERR_IO_PENDING)
324 callback_ = callback; 322 callback_ = callback;
325
326 return result > 0 ? OK : result; 323 return result > 0 ? OK : result;
327 } 324 }
328 325
329 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) { 326 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) {
330 DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE); 327 DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE);
331 DCHECK(callback_.is_null()); 328 DCHECK(callback_.is_null());
332 DCHECK(!callback.is_null()); 329 DCHECK(!callback.is_null());
333 DCHECK_EQ(0, read_buf_unused_offset_); 330 DCHECK_EQ(0, read_buf_unused_offset_);
334 331
335 // This function can be called with io_state_ == STATE_DONE if the 332 // This function can be called with io_state_ == STATE_DONE if the
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 sent_bytes_ += result; 539 sent_bytes_ += result;
543 request_body_send_buf_->DidConsume(result); 540 request_body_send_buf_->DidConsume(result);
544 541
545 io_state_ = STATE_SEND_BODY; 542 io_state_ = STATE_SEND_BODY;
546 return OK; 543 return OK;
547 } 544 }
548 545
549 int HttpStreamParser::DoSendRequestReadBodyComplete(int result) { 546 int HttpStreamParser::DoSendRequestReadBodyComplete(int result) {
550 // |result| is the result of read from the request body from the last call to 547 // |result| is the result of read from the request body from the last call to
551 // DoSendBody(). 548 // DoSendBody().
552 DCHECK_GE(result, 0); // There won't be errors. 549 if (result == ERR_FILE_READ_FAIL)
mmenke 2016/05/24 17:13:47 This should be "if (result < 0)" - if we see any r
maksims (do not use this acc) 2016/05/25 07:13:38 Done. Or should it be DCHECK_NE(result, ERR_IO_PEN
mmenke 2016/05/25 15:13:30 We already have that DCHECK in HttpStreamParser::D
550 return result;
553 551
554 // Chunked data needs to be encoded. 552 // Chunked data needs to be encoded.
555 if (request_->upload_data_stream->is_chunked()) { 553 if (request_->upload_data_stream->is_chunked()) {
556 if (result == 0) { // Reached the end. 554 if (result == 0) { // Reached the end.
557 DCHECK(request_->upload_data_stream->IsEOF()); 555 DCHECK(request_->upload_data_stream->IsEOF());
558 sent_last_chunk_ = true; 556 sent_last_chunk_ = true;
559 } 557 }
560 // Encode the buffer as 1 chunk. 558 // Encode the buffer as 1 chunk.
561 const base::StringPiece payload(request_body_read_buf_->data(), result); 559 const base::StringPiece payload(request_body_read_buf_->data(), result);
562 request_body_send_buf_->Clear(); 560 request_body_send_buf_->Clear();
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 } 1158 }
1161 1159
1162 void HttpStreamParser::ValidateStatusLine(const std::string& status_line) { 1160 void HttpStreamParser::ValidateStatusLine(const std::string& status_line) {
1163 HttpStatusLineValidator::StatusLineStatus status = 1161 HttpStatusLineValidator::StatusLineStatus status =
1164 HttpStatusLineValidator::ValidateStatusLine(status_line); 1162 HttpStatusLineValidator::ValidateStatusLine(status_line);
1165 UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status, 1163 UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status,
1166 HttpStatusLineValidator::STATUS_LINE_MAX); 1164 HttpStatusLineValidator::STATUS_LINE_MAX);
1167 } 1165 }
1168 1166
1169 } // namespace net 1167 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698