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

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

Issue 15829004: Update net/ to use scoped_refptr<T>::get() rather than implicit "operator T*" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: license twerk Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_stream_factory_impl_unittest.cc ('k') | net/http/http_stream_parser_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // If we have a small request body, then we'll merge with the headers into a 241 // If we have a small request body, then we'll merge with the headers into a
242 // single write. 242 // single write.
243 bool did_merge = false; 243 bool did_merge = false;
244 if (ShouldMergeRequestHeadersAndBody(request, request_->upload_data_stream)) { 244 if (ShouldMergeRequestHeadersAndBody(request, request_->upload_data_stream)) {
245 size_t merged_size = request.size() + request_->upload_data_stream->size(); 245 size_t merged_size = request.size() + request_->upload_data_stream->size();
246 scoped_refptr<IOBuffer> merged_request_headers_and_body( 246 scoped_refptr<IOBuffer> merged_request_headers_and_body(
247 new IOBuffer(merged_size)); 247 new IOBuffer(merged_size));
248 // We'll repurpose |request_headers_| to store the merged headers and 248 // We'll repurpose |request_headers_| to store the merged headers and
249 // body. 249 // body.
250 request_headers_ = new DrainableIOBuffer( 250 request_headers_ = new DrainableIOBuffer(
251 merged_request_headers_and_body, merged_size); 251 merged_request_headers_and_body.get(), merged_size);
252 252
253 memcpy(request_headers_->data(), request.data(), request.size()); 253 memcpy(request_headers_->data(), request.data(), request.size());
254 request_headers_->DidConsume(request.size()); 254 request_headers_->DidConsume(request.size());
255 255
256 size_t todo = request_->upload_data_stream->size(); 256 size_t todo = request_->upload_data_stream->size();
257 while (todo) { 257 while (todo) {
258 int consumed = request_->upload_data_stream->Read(request_headers_, todo, 258 int consumed = request_->upload_data_stream
259 CompletionCallback()); 259 ->Read(request_headers_.get(), todo, CompletionCallback());
260 DCHECK_GT(consumed, 0); // Read() won't fail if not chunked. 260 DCHECK_GT(consumed, 0); // Read() won't fail if not chunked.
261 request_headers_->DidConsume(consumed); 261 request_headers_->DidConsume(consumed);
262 todo -= consumed; 262 todo -= consumed;
263 } 263 }
264 DCHECK(request_->upload_data_stream->IsEOF()); 264 DCHECK(request_->upload_data_stream->IsEOF());
265 // Reset the offset, so the buffer can be read from the beginning. 265 // Reset the offset, so the buffer can be read from the beginning.
266 request_headers_->SetOffset(0); 266 request_headers_->SetOffset(0);
267 did_merge = true; 267 did_merge = true;
268 268
269 net_log_.AddEvent( 269 net_log_.AddEvent(
270 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY, 270 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY,
271 base::Bind(&NetLogSendRequestBodyCallback, 271 base::Bind(&NetLogSendRequestBodyCallback,
272 request_->upload_data_stream->size(), 272 request_->upload_data_stream->size(),
273 false, /* not chunked */ 273 false, /* not chunked */
274 true /* merged */)); 274 true /* merged */));
275 } 275 }
276 276
277 if (!did_merge) { 277 if (!did_merge) {
278 // If we didn't merge the body with the headers, then |request_headers_| 278 // If we didn't merge the body with the headers, then |request_headers_|
279 // contains just the HTTP headers. 279 // contains just the HTTP headers.
280 scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request)); 280 scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request));
281 request_headers_ = new DrainableIOBuffer(headers_io_buf, 281 request_headers_ =
282 headers_io_buf->size()); 282 new DrainableIOBuffer(headers_io_buf.get(), headers_io_buf->size());
283 } 283 }
284 284
285 result = DoLoop(OK); 285 result = DoLoop(OK);
286 if (result == ERR_IO_PENDING) 286 if (result == ERR_IO_PENDING)
287 callback_ = callback; 287 callback_ = callback;
288 288
289 return result > 0 ? OK : result; 289 return result > 0 ? OK : result;
290 } 290 }
291 291
292 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) { 292 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 415
416 int HttpStreamParser::DoSendHeaders(int result) { 416 int HttpStreamParser::DoSendHeaders(int result) {
417 request_headers_->DidConsume(result); 417 request_headers_->DidConsume(result);
418 int bytes_remaining = request_headers_->BytesRemaining(); 418 int bytes_remaining = request_headers_->BytesRemaining();
419 if (bytes_remaining > 0) { 419 if (bytes_remaining > 0) {
420 // Record our best estimate of the 'request time' as the time when we send 420 // Record our best estimate of the 'request time' as the time when we send
421 // out the first bytes of the request headers. 421 // out the first bytes of the request headers.
422 if (bytes_remaining == request_headers_->size()) { 422 if (bytes_remaining == request_headers_->size()) {
423 response_->request_time = base::Time::Now(); 423 response_->request_time = base::Time::Now();
424 } 424 }
425 result = connection_->socket()->Write(request_headers_, 425 result = connection_->socket()
426 bytes_remaining, 426 ->Write(request_headers_.get(), bytes_remaining, io_callback_);
427 io_callback_);
428 } else if (request_->upload_data_stream != NULL && 427 } else if (request_->upload_data_stream != NULL &&
429 (request_->upload_data_stream->is_chunked() || 428 (request_->upload_data_stream->is_chunked() ||
430 // !IsEOF() indicates that the body wasn't merged. 429 // !IsEOF() indicates that the body wasn't merged.
431 (request_->upload_data_stream->size() > 0 && 430 (request_->upload_data_stream->size() > 0 &&
432 !request_->upload_data_stream->IsEOF()))) { 431 !request_->upload_data_stream->IsEOF()))) {
433 net_log_.AddEvent( 432 net_log_.AddEvent(
434 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY, 433 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_BODY,
435 base::Bind(&NetLogSendRequestBodyCallback, 434 base::Bind(&NetLogSendRequestBodyCallback,
436 request_->upload_data_stream->size(), 435 request_->upload_data_stream->size(),
437 request_->upload_data_stream->is_chunked(), 436 request_->upload_data_stream->is_chunked(),
438 false /* not merged */)); 437 false /* not merged */));
439 io_state_ = STATE_SENDING_BODY; 438 io_state_ = STATE_SENDING_BODY;
440 result = OK; 439 result = OK;
441 } else { 440 } else {
442 io_state_ = STATE_REQUEST_SENT; 441 io_state_ = STATE_REQUEST_SENT;
443 } 442 }
444 return result; 443 return result;
445 } 444 }
446 445
447 int HttpStreamParser::DoSendBody(int result) { 446 int HttpStreamParser::DoSendBody(int result) {
448 // |result| is the number of bytes sent from the last call to 447 // |result| is the number of bytes sent from the last call to
449 // DoSendBody(), or 0 (i.e. OK). 448 // DoSendBody(), or 0 (i.e. OK).
450 449
451 // Send the remaining data in the request body buffer. 450 // Send the remaining data in the request body buffer.
452 request_body_send_buf_->DidConsume(result); 451 request_body_send_buf_->DidConsume(result);
453 if (request_body_send_buf_->BytesRemaining() > 0) { 452 if (request_body_send_buf_->BytesRemaining() > 0) {
454 return connection_->socket()->Write( 453 return connection_->socket()
455 request_body_send_buf_, 454 ->Write(request_body_send_buf_.get(),
456 request_body_send_buf_->BytesRemaining(), 455 request_body_send_buf_->BytesRemaining(),
457 io_callback_); 456 io_callback_);
458 } 457 }
459 458
460 if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) { 459 if (request_->upload_data_stream->is_chunked() && sent_last_chunk_) {
461 io_state_ = STATE_REQUEST_SENT; 460 io_state_ = STATE_REQUEST_SENT;
462 return OK; 461 return OK;
463 } 462 }
464 463
465 request_body_read_buf_->Clear(); 464 request_body_read_buf_->Clear();
466 io_state_ = STATE_SEND_REQUEST_READING_BODY; 465 io_state_ = STATE_SEND_REQUEST_READING_BODY;
467 return request_->upload_data_stream->Read(request_body_read_buf_, 466 return request_->upload_data_stream->Read(request_body_read_buf_.get(),
468 request_body_read_buf_->capacity(), 467 request_body_read_buf_->capacity(),
469 io_callback_); 468 io_callback_);
470 } 469 }
471 470
472 int HttpStreamParser::DoSendRequestReadingBody(int result) { 471 int HttpStreamParser::DoSendRequestReadingBody(int result) {
473 // |result| is the result of read from the request body from the last call to 472 // |result| is the result of read from the request body from the last call to
474 // DoSendBody(). 473 // DoSendBody().
475 DCHECK_GE(result, 0); // There won't be errors. 474 DCHECK_GE(result, 0); // There won't be errors.
476 475
477 // Chunked data needs to be encoded. 476 // Chunked data needs to be encoded.
(...skipping 28 matching lines...) Expand all
506 io_state_ = STATE_READ_HEADERS_COMPLETE; 505 io_state_ = STATE_READ_HEADERS_COMPLETE;
507 506
508 // Grow the read buffer if necessary. 507 // Grow the read buffer if necessary.
509 if (read_buf_->RemainingCapacity() == 0) 508 if (read_buf_->RemainingCapacity() == 0)
510 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize); 509 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize);
511 510
512 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. 511 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL.
513 // See if the user is passing in an IOBuffer with a NULL |data_|. 512 // See if the user is passing in an IOBuffer with a NULL |data_|.
514 CHECK(read_buf_->data()); 513 CHECK(read_buf_->data());
515 514
516 return connection_->socket()->Read(read_buf_, 515 return connection_->socket()
517 read_buf_->RemainingCapacity(), 516 ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_);
518 io_callback_);
519 } 517 }
520 518
521 int HttpStreamParser::DoReadHeadersComplete(int result) { 519 int HttpStreamParser::DoReadHeadersComplete(int result) {
522 if (result == 0) 520 if (result == 0)
523 result = ERR_CONNECTION_CLOSED; 521 result = ERR_CONNECTION_CLOSED;
524 522
525 if (result < 0 && result != ERR_CONNECTION_CLOSED) { 523 if (result < 0 && result != ERR_CONNECTION_CLOSED) {
526 io_state_ = STATE_DONE; 524 io_state_ = STATE_DONE;
527 return result; 525 return result;
528 } 526 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 read_buf_->SetCapacity(0); 641 read_buf_->SetCapacity(0);
644 read_buf_unused_offset_ = 0; 642 read_buf_unused_offset_ = 0;
645 } 643 }
646 } 644 }
647 645
648 // Check to see if we're done reading. 646 // Check to see if we're done reading.
649 if (IsResponseBodyComplete()) 647 if (IsResponseBodyComplete())
650 return 0; 648 return 0;
651 649
652 DCHECK_EQ(0, read_buf_->offset()); 650 DCHECK_EQ(0, read_buf_->offset());
653 return connection_->socket()->Read(user_read_buf_, user_read_buf_len_, 651 return connection_->socket()
654 io_callback_); 652 ->Read(user_read_buf_.get(), user_read_buf_len_, io_callback_);
655 } 653 }
656 654
657 int HttpStreamParser::DoReadBodyComplete(int result) { 655 int HttpStreamParser::DoReadBodyComplete(int result) {
658 // When the connection is closed, there are numerous ways to interpret it. 656 // When the connection is closed, there are numerous ways to interpret it.
659 // 657 //
660 // - If a Content-Length header is present and the body contains exactly that 658 // - If a Content-Length header is present and the body contains exactly that
661 // number of bytes at connection close, the response is successful. 659 // number of bytes at connection close, the response is successful.
662 // 660 //
663 // - If a Content-Length header is present and the body contains fewer bytes 661 // - If a Content-Length header is present and the body contains fewer bytes
664 // than promised by the header at connection close, it may indicate that 662 // than promised by the header at connection close, it may indicate that
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 read_buf_->StartOfBuffer() + read_buf_unused_offset_, end_offset)); 786 read_buf_->StartOfBuffer() + read_buf_unused_offset_, end_offset));
789 } else { 787 } else {
790 // Enough data was read -- there is no status line. 788 // Enough data was read -- there is no status line.
791 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); 789 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
792 } 790 }
793 791
794 // Check for multiple Content-Length headers with no Transfer-Encoding header. 792 // Check for multiple Content-Length headers with no Transfer-Encoding header.
795 // If they exist, and have distinct values, it's a potential response 793 // If they exist, and have distinct values, it's a potential response
796 // smuggling attack. 794 // smuggling attack.
797 if (!headers->HasHeader("Transfer-Encoding")) { 795 if (!headers->HasHeader("Transfer-Encoding")) {
798 if (HeadersContainMultipleCopiesOfField(*headers, "Content-Length")) 796 if (HeadersContainMultipleCopiesOfField(*headers.get(), "Content-Length"))
799 return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH; 797 return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH;
800 } 798 }
801 799
802 // Check for multiple Content-Disposition or Location headers. If they exist, 800 // Check for multiple Content-Disposition or Location headers. If they exist,
803 // it's also a potential response smuggling attack. 801 // it's also a potential response smuggling attack.
804 if (HeadersContainMultipleCopiesOfField(*headers, "Content-Disposition")) 802 if (HeadersContainMultipleCopiesOfField(*headers.get(),
803 "Content-Disposition"))
805 return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION; 804 return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION;
806 if (HeadersContainMultipleCopiesOfField(*headers, "Location")) 805 if (HeadersContainMultipleCopiesOfField(*headers.get(), "Location"))
807 return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION; 806 return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION;
808 807
809 response_->headers = headers; 808 response_->headers = headers;
810 response_->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP1; 809 response_->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP1;
811 response_->vary_data.Init(*request_, *response_->headers); 810 response_->vary_data.Init(*request_, *response_->headers.get());
812 DVLOG(1) << __FUNCTION__ << "()" 811 DVLOG(1) << __FUNCTION__ << "()"
813 << " content_length = \"" 812 << " content_length = \"" << response_->headers->GetContentLength()
814 << response_->headers->GetContentLength() << "\n\"" 813 << "\n\""
815 << " headers = \"" << GetResponseHeaderLines(*response_->headers) 814 << " headers = \""
816 << "\""; 815 << GetResponseHeaderLines(*response_->headers.get()) << "\"";
817 return OK; 816 return OK;
818 } 817 }
819 818
820 void HttpStreamParser::CalculateResponseBodySize() { 819 void HttpStreamParser::CalculateResponseBodySize() {
821 // Figure how to determine EOF: 820 // Figure how to determine EOF:
822 821
823 // For certain responses, we know the content length is always 0. From 822 // For certain responses, we know the content length is always 0. From
824 // RFC 2616 Section 4.3 Message Body: 823 // RFC 2616 Section 4.3 Message Body:
825 // 824 //
826 // For response messages, whether or not a message-body is included with 825 // For response messages, whether or not a message-body is included with
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 request_body->IsInMemory() && 946 request_body->IsInMemory() &&
948 request_body->size() > 0) { 947 request_body->size() > 0) {
949 size_t merged_size = request_headers.size() + request_body->size(); 948 size_t merged_size = request_headers.size() + request_body->size();
950 if (merged_size <= kMaxMergedHeaderAndBodySize) 949 if (merged_size <= kMaxMergedHeaderAndBodySize)
951 return true; 950 return true;
952 } 951 }
953 return false; 952 return false;
954 } 953 }
955 954
956 } // namespace net 955 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl_unittest.cc ('k') | net/http/http_stream_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698