| 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 // When the connection is closed, there are numerous ways to interpret it. | 535 // When the connection is closed, there are numerous ways to interpret it. |
| 534 // | 536 // |
| 535 // - If a Content-Length header is present and the body contains exactly that | 537 // - If a Content-Length header is present and the body contains exactly that |
| 536 // number of bytes at connection close, the response is successful. | 538 // number of bytes at connection close, the response is successful. |
| 537 // | 539 // |
| 538 // - If a Content-Length header is present and the body contains fewer bytes | 540 // - If a Content-Length header is present and the body contains fewer bytes |
| 539 // than promised by the header at connection close, it may indicate that | 541 // than promised by the header at connection close, it may indicate that |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 void HttpStreamParser::GetSSLCertRequestInfo( | 787 void HttpStreamParser::GetSSLCertRequestInfo( |
| 786 SSLCertRequestInfo* cert_request_info) { | 788 SSLCertRequestInfo* cert_request_info) { |
| 787 if (request_->url.SchemeIs("https") && connection_->socket()) { | 789 if (request_->url.SchemeIs("https") && connection_->socket()) { |
| 788 SSLClientSocket* ssl_socket = | 790 SSLClientSocket* ssl_socket = |
| 789 static_cast<SSLClientSocket*>(connection_->socket()); | 791 static_cast<SSLClientSocket*>(connection_->socket()); |
| 790 ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 792 ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| 791 } | 793 } |
| 792 } | 794 } |
| 793 | 795 |
| 794 } // namespace net | 796 } // namespace net |
| OLD | NEW |