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 |