summaryrefslogtreecommitdiffstats
path: root/net/http/http_stream_parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/http/http_stream_parser.cc')
-rw-r--r--net/http/http_stream_parser.cc56
1 files changed, 38 insertions, 18 deletions
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index dcde04f..aa8eaad 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -6,7 +6,6 @@
#include "base/compiler_specific.h"
#include "base/metrics/histogram.h"
-#include "base/stringprintf.h"
#include "base/string_util.h"
#include "net/base/address_list.h"
#include "net/base/auth.h"
@@ -63,6 +62,9 @@ bool HeadersContainMultipleCopiesOfField(
namespace net {
+// 2 CRLFs + max of 8 hex chars.
+const size_t HttpStreamParser::kChunkHeaderFooterSize = 12;
+
HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
const HttpRequestInfo* request,
GrowableIOBuffer* read_buffer,
@@ -85,6 +87,8 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
io_callback_(
base::Bind(&HttpStreamParser::OnIOComplete,
base::Unretained(this)))),
+ chunk_buffer_size_(UploadDataStream::GetBufferSize() +
+ kChunkHeaderFooterSize),
chunk_length_(0),
chunk_length_without_encoding_(0),
sent_last_chunk_(false) {
@@ -127,9 +131,7 @@ int HttpStreamParser::SendRequest(const std::string& request_line,
request_body_.reset(request_body);
if (request_body_ != NULL && request_body_->is_chunked()) {
request_body_->set_chunk_callback(this);
- const int kChunkHeaderFooterSize = 12; // 2 CRLFs + max of 8 hex chars.
- chunk_buf_ = new IOBuffer(request_body_->GetMaxBufferSize() +
- kChunkHeaderFooterSize);
+ chunk_buf_ = new IOBuffer(chunk_buffer_size_);
}
io_state_ = STATE_SENDING_HEADERS;
@@ -359,23 +361,17 @@ int HttpStreamParser::DoSendBody(int result) {
request_body_->MarkConsumedAndFillBuffer(chunk_length_without_encoding_);
chunk_length_without_encoding_ = 0;
- int buf_len = static_cast<int>(request_body_->buf_len());
if (request_body_->eof()) {
- static const char kLastChunk[] = "0\r\n\r\n";
- chunk_length_ = strlen(kLastChunk);
- memcpy(chunk_buf_->data(), kLastChunk, chunk_length_);
+ chunk_length_ = EncodeChunk(
+ base::StringPiece(), chunk_buf_->data(), chunk_buffer_size_);
sent_last_chunk_ = true;
- } else if (buf_len) {
+ } else if (request_body_->buf_len() > 0) {
// Encode and send the buffer as 1 chunk.
- std::string chunk_header = StringPrintf("%X\r\n", buf_len);
- char* chunk_ptr = chunk_buf_->data();
- memcpy(chunk_ptr, chunk_header.data(), chunk_header.length());
- chunk_ptr += chunk_header.length();
- memcpy(chunk_ptr, request_body_->buf()->data(), buf_len);
- chunk_ptr += buf_len;
- memcpy(chunk_ptr, "\r\n", 2);
- chunk_length_without_encoding_ = buf_len;
- chunk_length_ = chunk_header.length() + buf_len + 2;
+ const base::StringPiece payload(request_body_->buf()->data(),
+ request_body_->buf_len());
+ chunk_length_ = EncodeChunk(payload, chunk_buf_->data(),
+ chunk_buffer_size_);
+ chunk_length_without_encoding_ = payload.size();
} else {
// Nothing to send. More POST data is yet to come?
return ERR_IO_PENDING;
@@ -783,4 +779,28 @@ void HttpStreamParser::GetSSLCertRequestInfo(
}
}
+int HttpStreamParser::EncodeChunk(const base::StringPiece& payload,
+ char* output,
+ size_t output_size) {
+ if (output_size < payload.size() + kChunkHeaderFooterSize)
+ return ERR_INVALID_ARGUMENT;
+
+ char* cursor = output;
+ // Add the header.
+ const int num_chars = base::snprintf(output, output_size,
+ "%X\r\n",
+ static_cast<int>(payload.size()));
+ cursor += num_chars;
+ // Add the payload if any.
+ if (payload.size() > 0) {
+ memcpy(cursor, payload.data(), payload.size());
+ cursor += payload.size();
+ }
+ // Add the trailing CRLF.
+ memcpy(cursor, "\r\n", 2);
+ cursor += 2;
+
+ return cursor - output;
+}
+
} // namespace net