| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 response_header_start_offset_(-1), | 74 response_header_start_offset_(-1), |
| 75 response_body_length_(-1), | 75 response_body_length_(-1), |
| 76 response_body_read_(0), | 76 response_body_read_(0), |
| 77 chunked_decoder_(NULL), | 77 chunked_decoder_(NULL), |
| 78 user_read_buf_(NULL), | 78 user_read_buf_(NULL), |
| 79 user_read_buf_len_(0), | 79 user_read_buf_len_(0), |
| 80 user_callback_(NULL), | 80 user_callback_(NULL), |
| 81 connection_(connection), | 81 connection_(connection), |
| 82 net_log_(net_log), | 82 net_log_(net_log), |
| 83 ALLOW_THIS_IN_INITIALIZER_LIST( | 83 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 84 io_callback_(this, &HttpStreamParser::OnIOComplete)), | 84 io_callback_( |
| 85 base::Bind(&HttpStreamParser::OnIOComplete, |
| 86 base::Unretained(this)))), |
| 85 chunk_length_(0), | 87 chunk_length_(0), |
| 86 chunk_length_without_encoding_(0), | 88 chunk_length_without_encoding_(0), |
| 87 sent_last_chunk_(false) { | 89 sent_last_chunk_(false) { |
| 88 } | 90 } |
| 89 | 91 |
| 90 HttpStreamParser::~HttpStreamParser() { | 92 HttpStreamParser::~HttpStreamParser() { |
| 91 if (request_body_ != NULL && request_body_->is_chunked()) | 93 if (request_body_ != NULL && request_body_->is_chunked()) |
| 92 request_body_->set_chunk_callback(NULL); | 94 request_body_->set_chunk_callback(NULL); |
| 93 } | 95 } |
| 94 | 96 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 coalesce = static_cast<size_t>(header_packets + body_packets); | 309 coalesce = static_cast<size_t>(header_packets + body_packets); |
| 308 } else { | 310 } else { |
| 309 coalesce = NO_ADVANTAGE; | 311 coalesce = NO_ADVANTAGE; |
| 310 } | 312 } |
| 311 } | 313 } |
| 312 UMA_HISTOGRAM_ENUMERATION("Net.CoalescePotential", coalesce, | 314 UMA_HISTOGRAM_ENUMERATION("Net.CoalescePotential", coalesce, |
| 313 COALESCE_POTENTIAL_MAX); | 315 COALESCE_POTENTIAL_MAX); |
| 314 } | 316 } |
| 315 result = connection_->socket()->Write(request_headers_, | 317 result = connection_->socket()->Write(request_headers_, |
| 316 bytes_remaining, | 318 bytes_remaining, |
| 317 &io_callback_); | 319 io_callback_); |
| 318 } else if (request_body_ != NULL && | 320 } else if (request_body_ != NULL && |
| 319 (request_body_->is_chunked() || request_body_->size())) { | 321 (request_body_->is_chunked() || request_body_->size())) { |
| 320 io_state_ = STATE_SENDING_BODY; | 322 io_state_ = STATE_SENDING_BODY; |
| 321 result = OK; | 323 result = OK; |
| 322 } else { | 324 } else { |
| 323 io_state_ = STATE_REQUEST_SENT; | 325 io_state_ = STATE_REQUEST_SENT; |
| 324 } | 326 } |
| 325 return result; | 327 return result; |
| 326 } | 328 } |
| 327 | 329 |
| 328 int HttpStreamParser::DoSendBody(int result) { | 330 int HttpStreamParser::DoSendBody(int result) { |
| 329 if (request_body_->is_chunked()) { | 331 if (request_body_->is_chunked()) { |
| 330 chunk_length_ -= result; | 332 chunk_length_ -= result; |
| 331 if (chunk_length_) { | 333 if (chunk_length_) { |
| 332 memmove(chunk_buf_->data(), chunk_buf_->data() + result, chunk_length_); | 334 memmove(chunk_buf_->data(), chunk_buf_->data() + result, chunk_length_); |
| 333 return connection_->socket()->Write(chunk_buf_, chunk_length_, | 335 return connection_->socket()->Write(chunk_buf_, chunk_length_, |
| 334 &io_callback_); | 336 io_callback_); |
| 335 } | 337 } |
| 336 | 338 |
| 337 if (sent_last_chunk_) { | 339 if (sent_last_chunk_) { |
| 338 io_state_ = STATE_REQUEST_SENT; | 340 io_state_ = STATE_REQUEST_SENT; |
| 339 return OK; | 341 return OK; |
| 340 } | 342 } |
| 341 | 343 |
| 342 request_body_->MarkConsumedAndFillBuffer(chunk_length_without_encoding_); | 344 request_body_->MarkConsumedAndFillBuffer(chunk_length_without_encoding_); |
| 343 chunk_length_without_encoding_ = 0; | 345 chunk_length_without_encoding_ = 0; |
| 344 chunk_length_ = 0; | 346 chunk_length_ = 0; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 359 chunk_ptr += buf_len; | 361 chunk_ptr += buf_len; |
| 360 memcpy(chunk_ptr, "\r\n", 2); | 362 memcpy(chunk_ptr, "\r\n", 2); |
| 361 chunk_length_without_encoding_ = buf_len; | 363 chunk_length_without_encoding_ = buf_len; |
| 362 chunk_length_ = chunk_header.length() + buf_len + 2; | 364 chunk_length_ = chunk_header.length() + buf_len + 2; |
| 363 } | 365 } |
| 364 | 366 |
| 365 if (!chunk_length_) // More POST data is yet to come? | 367 if (!chunk_length_) // More POST data is yet to come? |
| 366 return ERR_IO_PENDING; | 368 return ERR_IO_PENDING; |
| 367 | 369 |
| 368 return connection_->socket()->Write(chunk_buf_, chunk_length_, | 370 return connection_->socket()->Write(chunk_buf_, chunk_length_, |
| 369 &io_callback_); | 371 io_callback_); |
| 370 } | 372 } |
| 371 | 373 |
| 372 // Non-chunked request body. | 374 // Non-chunked request body. |
| 373 request_body_->MarkConsumedAndFillBuffer(result); | 375 request_body_->MarkConsumedAndFillBuffer(result); |
| 374 | 376 |
| 375 if (!request_body_->eof()) { | 377 if (!request_body_->eof()) { |
| 376 int buf_len = static_cast<int>(request_body_->buf_len()); | 378 int buf_len = static_cast<int>(request_body_->buf_len()); |
| 377 result = connection_->socket()->Write(request_body_->buf(), buf_len, | 379 result = connection_->socket()->Write(request_body_->buf(), buf_len, |
| 378 &io_callback_); | 380 io_callback_); |
| 379 } else { | 381 } else { |
| 380 io_state_ = STATE_REQUEST_SENT; | 382 io_state_ = STATE_REQUEST_SENT; |
| 381 } | 383 } |
| 382 return result; | 384 return result; |
| 383 } | 385 } |
| 384 | 386 |
| 385 int HttpStreamParser::DoReadHeaders() { | 387 int HttpStreamParser::DoReadHeaders() { |
| 386 io_state_ = STATE_READ_HEADERS_COMPLETE; | 388 io_state_ = STATE_READ_HEADERS_COMPLETE; |
| 387 | 389 |
| 388 // Grow the read buffer if necessary. | 390 // Grow the read buffer if necessary. |
| 389 if (read_buf_->RemainingCapacity() == 0) | 391 if (read_buf_->RemainingCapacity() == 0) |
| 390 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize); | 392 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize); |
| 391 | 393 |
| 392 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. | 394 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. |
| 393 // See if the user is passing in an IOBuffer with a NULL |data_|. | 395 // See if the user is passing in an IOBuffer with a NULL |data_|. |
| 394 CHECK(read_buf_->data()); | 396 CHECK(read_buf_->data()); |
| 395 | 397 |
| 396 return connection_->socket()->Read(read_buf_, | 398 return connection_->socket()->Read(read_buf_, |
| 397 read_buf_->RemainingCapacity(), | 399 read_buf_->RemainingCapacity(), |
| 398 &io_callback_); | 400 io_callback_); |
| 399 } | 401 } |
| 400 | 402 |
| 401 int HttpStreamParser::DoReadHeadersComplete(int result) { | 403 int HttpStreamParser::DoReadHeadersComplete(int result) { |
| 402 if (result == 0) | 404 if (result == 0) |
| 403 result = ERR_CONNECTION_CLOSED; | 405 result = ERR_CONNECTION_CLOSED; |
| 404 | 406 |
| 405 if (result < 0 && result != ERR_CONNECTION_CLOSED) { | 407 if (result < 0 && result != ERR_CONNECTION_CLOSED) { |
| 406 io_state_ = STATE_DONE; | 408 io_state_ = STATE_DONE; |
| 407 return result; | 409 return result; |
| 408 } | 410 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 read_buf_unused_offset_ = 0; | 521 read_buf_unused_offset_ = 0; |
| 520 } | 522 } |
| 521 } | 523 } |
| 522 | 524 |
| 523 // Check to see if we're done reading. | 525 // Check to see if we're done reading. |
| 524 if (IsResponseBodyComplete()) | 526 if (IsResponseBodyComplete()) |
| 525 return 0; | 527 return 0; |
| 526 | 528 |
| 527 DCHECK_EQ(0, read_buf_->offset()); | 529 DCHECK_EQ(0, read_buf_->offset()); |
| 528 return connection_->socket()->Read(user_read_buf_, user_read_buf_len_, | 530 return connection_->socket()->Read(user_read_buf_, user_read_buf_len_, |
| 529 &io_callback_); | 531 io_callback_); |
| 530 } | 532 } |
| 531 | 533 |
| 532 int HttpStreamParser::DoReadBodyComplete(int result) { | 534 int HttpStreamParser::DoReadBodyComplete(int result) { |
| 533 // If we didn't get a Content-Length and aren't using a chunked encoding, | 535 // If we didn't get a Content-Length and aren't using a chunked encoding, |
| 534 // the only way to signal the end of a stream is to close the connection, | 536 // the only way to signal the end of a stream is to close the connection, |
| 535 // so we don't treat that as an error, though in some cases we may not | 537 // so we don't treat that as an error, though in some cases we may not |
| 536 // have completely received the resource. | 538 // have completely received the resource. |
| 537 if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse()) | 539 if (result == 0 && !IsResponseBodyComplete() && CanFindEndOfResponse()) |
| 538 result = ERR_CONNECTION_CLOSED; | 540 result = ERR_CONNECTION_CLOSED; |
| 539 | 541 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 void HttpStreamParser::GetSSLCertRequestInfo( | 761 void HttpStreamParser::GetSSLCertRequestInfo( |
| 760 SSLCertRequestInfo* cert_request_info) { | 762 SSLCertRequestInfo* cert_request_info) { |
| 761 if (request_->url.SchemeIs("https") && connection_->socket()) { | 763 if (request_->url.SchemeIs("https") && connection_->socket()) { |
| 762 SSLClientSocket* ssl_socket = | 764 SSLClientSocket* ssl_socket = |
| 763 static_cast<SSLClientSocket*>(connection_->socket()); | 765 static_cast<SSLClientSocket*>(connection_->socket()); |
| 764 ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 766 ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| 765 } | 767 } |
| 766 } | 768 } |
| 767 | 769 |
| 768 } // namespace net | 770 } // namespace net |
| OLD | NEW |