Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "net/base/address_list.h" | 10 #include "net/base/address_list.h" |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 AddressList address; | 121 AddressList address; |
| 122 int result = connection_->socket()->GetPeerAddress(&address); | 122 int result = connection_->socket()->GetPeerAddress(&address); |
| 123 if (result != OK) | 123 if (result != OK) |
| 124 return result; | 124 return result; |
| 125 response_->socket_address = HostPortPair::FromAddrInfo(address.head()); | 125 response_->socket_address = HostPortPair::FromAddrInfo(address.head()); |
| 126 | 126 |
| 127 std::string request = request_line + headers.ToString(); | 127 std::string request = request_line + headers.ToString(); |
| 128 request_body_.reset(request_body); | 128 request_body_.reset(request_body); |
| 129 if (request_body_ != NULL && request_body_->is_chunked()) { | 129 if (request_body_ != NULL && request_body_->is_chunked()) { |
| 130 request_body_->set_chunk_callback(this); | 130 request_body_->set_chunk_callback(this); |
| 131 // The raw chunk buffer is guaranteed to be large enough to hold the | 131 // The chunk buffer is guaranteed to be large enough to hold the encoded |
| 132 // encoded chunk. | 132 // chunk. |
| 133 raw_chunk_buf_ = new IOBufferWithSize(UploadDataStream::GetBufferSize() + | 133 chunk_buf_ = new SeekableIOBuffer(UploadDataStream::GetBufferSize() + |
| 134 kChunkHeaderFooterSize); | 134 kChunkHeaderFooterSize); |
| 135 } | 135 } |
| 136 | 136 |
| 137 io_state_ = STATE_SENDING_HEADERS; | 137 io_state_ = STATE_SENDING_HEADERS; |
| 138 | 138 |
| 139 // If we have a small request body, then we'll merge with the headers into a | 139 // If we have a small request body, then we'll merge with the headers into a |
| 140 // single write. | 140 // single write. |
| 141 bool did_merge = false; | 141 bool did_merge = false; |
| 142 if (ShouldMergeRequestHeadersAndBody(request, request_body_.get())) { | 142 if (ShouldMergeRequestHeadersAndBody(request, request_body_.get())) { |
| 143 size_t merged_size = request.size() + request_body->size(); | 143 size_t merged_size = request.size() + request_body->size(); |
| 144 scoped_refptr<IOBuffer> merged_request_headers_and_body( | 144 scoped_refptr<IOBuffer> merged_request_headers_and_body( |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 io_state_ = STATE_REQUEST_SENT; | 342 io_state_ = STATE_REQUEST_SENT; |
| 343 } | 343 } |
| 344 return result; | 344 return result; |
| 345 } | 345 } |
| 346 | 346 |
| 347 int HttpStreamParser::DoSendChunkedBody(int result) { | 347 int HttpStreamParser::DoSendChunkedBody(int result) { |
| 348 // |result| is the number of bytes sent from the last call to | 348 // |result| is the number of bytes sent from the last call to |
| 349 // DoSendChunkedBody(), or 0 (i.e. OK) the first time. | 349 // DoSendChunkedBody(), or 0 (i.e. OK) the first time. |
| 350 | 350 |
| 351 // Send the remaining data in the chunk buffer. | 351 // Send the remaining data in the chunk buffer. |
| 352 if (chunk_buf_.get()) { | 352 if (result > 0) { |
|
wtc
2012/02/02 20:22:57
Nit: it is safe to call
chunk_buf_->DidConsume(
satorux1
2012/02/02 22:02:27
Good point. Done.
| |
| 353 chunk_buf_->DidConsume(result); | 353 chunk_buf_->DidConsume(result); |
| 354 if (chunk_buf_->BytesRemaining() > 0) { | 354 if (chunk_buf_->BytesRemaining() > 0) { |
| 355 return connection_->socket()->Write(chunk_buf_, | 355 return connection_->socket()->Write(chunk_buf_, |
| 356 chunk_buf_->BytesRemaining(), | 356 chunk_buf_->BytesRemaining(), |
| 357 io_callback_); | 357 io_callback_); |
| 358 } | 358 } |
| 359 } | 359 } |
| 360 | 360 |
| 361 if (sent_last_chunk_) { | 361 if (sent_last_chunk_) { |
| 362 io_state_ = STATE_REQUEST_SENT; | 362 io_state_ = STATE_REQUEST_SENT; |
| 363 return OK; | 363 return OK; |
| 364 } | 364 } |
| 365 | 365 |
| 366 // |chunk_length_without_encoding_| is 0 when DoSendBody() is first | 366 // |chunk_length_without_encoding_| is 0 when DoSendBody() is first |
| 367 // called, hence the first call to MarkConsumedAndFillBuffer() is a noop. | 367 // called, hence the first call to MarkConsumedAndFillBuffer() is a noop. |
| 368 request_body_->MarkConsumedAndFillBuffer(chunk_length_without_encoding_); | 368 request_body_->MarkConsumedAndFillBuffer(chunk_length_without_encoding_); |
| 369 chunk_length_without_encoding_ = 0; | 369 chunk_length_without_encoding_ = 0; |
| 370 | 370 |
| 371 if (request_body_->eof()) { | 371 if (request_body_->eof()) { |
| 372 chunk_buf_->Clear(); | |
| 372 const int chunk_length = EncodeChunk( | 373 const int chunk_length = EncodeChunk( |
| 373 base::StringPiece(), raw_chunk_buf_->data(), raw_chunk_buf_->size()); | 374 base::StringPiece(), chunk_buf_->data(), chunk_buf_->capacity()); |
| 374 chunk_buf_ = new DrainableIOBuffer(raw_chunk_buf_, chunk_length); | 375 chunk_buf_->DidAppend(chunk_length); |
| 375 sent_last_chunk_ = true; | 376 sent_last_chunk_ = true; |
| 376 } else if (request_body_->buf_len() > 0) { | 377 } else if (request_body_->buf_len() > 0) { |
| 377 // Encode and send the buffer as 1 chunk. | 378 // Encode and send the buffer as 1 chunk. |
| 378 const base::StringPiece payload(request_body_->buf()->data(), | 379 const base::StringPiece payload(request_body_->buf()->data(), |
| 379 request_body_->buf_len()); | 380 request_body_->buf_len()); |
| 381 chunk_buf_->Clear(); | |
| 380 const int chunk_length = EncodeChunk( | 382 const int chunk_length = EncodeChunk( |
| 381 payload, raw_chunk_buf_->data(), raw_chunk_buf_->size()); | 383 payload, chunk_buf_->data(), chunk_buf_->capacity()); |
| 382 chunk_buf_ = new DrainableIOBuffer(raw_chunk_buf_, chunk_length); | 384 chunk_buf_->DidAppend(chunk_length); |
| 383 chunk_length_without_encoding_ = payload.size(); | 385 chunk_length_without_encoding_ = payload.size(); |
| 384 } else { | 386 } else { |
| 385 // Nothing to send. More POST data is yet to come? | 387 // Nothing to send. More POST data is yet to come? |
| 386 return ERR_IO_PENDING; | 388 return ERR_IO_PENDING; |
| 387 } | 389 } |
| 388 | 390 |
| 389 return connection_->socket()->Write(chunk_buf_, chunk_buf_->BytesRemaining(), | 391 return connection_->socket()->Write(chunk_buf_, chunk_buf_->BytesRemaining(), |
| 390 io_callback_); | 392 io_callback_); |
| 391 } | 393 } |
| 392 | 394 |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 823 request_body->IsInMemory() && | 825 request_body->IsInMemory() && |
| 824 request_body->size() > 0) { | 826 request_body->size() > 0) { |
| 825 size_t merged_size = request_headers.size() + request_body->size(); | 827 size_t merged_size = request_headers.size() + request_body->size(); |
| 826 if (merged_size <= kMaxMergedHeaderAndBodySize) | 828 if (merged_size <= kMaxMergedHeaderAndBodySize) |
| 827 return true; | 829 return true; |
| 828 } | 830 } |
| 829 return false; | 831 return false; |
| 830 } | 832 } |
| 831 | 833 |
| 832 } // namespace net | 834 } // namespace net |
| OLD | NEW |