summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-19 15:13:08 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-19 15:13:08 +0000
commitd7f5ecd6dc2156872e641cf892a39a3d6b62d386 (patch)
tree3ee768538c2a7fc8decac8f8d8a389f9d8b2b3c7 /net/http
parent91ee3680d8087a7877a866114df12842a95a3229 (diff)
downloadchromium_src-d7f5ecd6dc2156872e641cf892a39a3d6b62d386.zip
chromium_src-d7f5ecd6dc2156872e641cf892a39a3d6b62d386.tar.gz
chromium_src-d7f5ecd6dc2156872e641cf892a39a3d6b62d386.tar.bz2
Revert 118265 (added a static initializer on linux)
- Factor out chunk encoding logic into HttpStreamParser::EncodeChunk(). The logic is meaty enough to be factored out. Add unit tests along the way. BUG=72001 TEST=add unit tests. Review URL: http://codereview.chromium.org/9242018 TBR=satorux@chromium.org Review URL: https://chromiumcodereview.appspot.com/9264010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118295 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_stream_parser.cc60
-rw-r--r--net/http/http_stream_parser.h21
-rw-r--r--net/http/http_stream_parser_unittest.cc77
3 files changed, 20 insertions, 138 deletions
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index a61349a..bd9bda1 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -6,6 +6,7 @@
#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"
@@ -60,15 +61,6 @@ bool HeadersContainMultipleCopiesOfField(
namespace net {
-// 2 CRLFs + max of 8 hex chars.
-const size_t HttpStreamParser::kChunkHeaderFooterSize = 12;
-
-// The size of the chunk buffer (chunk_buf_). The chunk buffer is
-// guaranteed to be large enough to hold the encoded chunk.
-static const size_t kChunkBufferSize =
- UploadDataStream::kBufferSize +
- HttpStreamParser::kChunkHeaderFooterSize;
-
HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
const HttpRequestInfo* request,
GrowableIOBuffer* read_buffer,
@@ -136,7 +128,9 @@ 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);
- chunk_buf_ = new IOBuffer(kChunkBufferSize);
+ const int kChunkHeaderFooterSize = 12; // 2 CRLFs + max of 8 hex chars.
+ chunk_buf_ = new IOBuffer(request_body_->GetMaxBufferSize() +
+ kChunkHeaderFooterSize);
}
io_state_ = STATE_SENDING_HEADERS;
@@ -355,17 +349,23 @@ 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()) {
- chunk_length_ = EncodeChunk(
- base::StringPiece(), chunk_buf_->data(), kChunkBufferSize);
+ static const char kLastChunk[] = "0\r\n\r\n";
+ chunk_length_ = strlen(kLastChunk);
+ memcpy(chunk_buf_->data(), kLastChunk, chunk_length_);
sent_last_chunk_ = true;
- } else if (request_body_->buf_len() > 0) {
+ } else if (buf_len) {
// Encode and send the buffer as 1 chunk.
- const base::StringPiece payload(request_body_->buf()->data(),
- request_body_->buf_len());
- chunk_length_ = EncodeChunk(payload, chunk_buf_->data(),
- kChunkBufferSize);
- chunk_length_without_encoding_ = payload.size();
+ 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;
} else {
// Nothing to send. More POST data is yet to come?
return ERR_IO_PENDING;
@@ -773,28 +773,4 @@ 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
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
index efb41a0..ae9fc3e 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,9 +9,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/string_piece.h"
#include "net/base/completion_callback.h"
-#include "net/base/net_export.h"
#include "net/base/net_log.h"
#include "net/base/upload_data_stream.h"
#include "net/http/http_chunked_decoder.h"
@@ -28,7 +26,7 @@ class IOBuffer;
class SSLCertRequestInfo;
class SSLInfo;
-class NET_EXPORT_PRIVATE HttpStreamParser : public ChunkCallback {
+class HttpStreamParser : public ChunkCallback {
public:
// Any data in |read_buffer| will be used before reading from the socket
// and any data left over after parsing the stream will be put into
@@ -79,21 +77,6 @@ class NET_EXPORT_PRIVATE HttpStreamParser : public ChunkCallback {
// ChunkCallback methods.
virtual void OnChunkAvailable() OVERRIDE;
- // Encodes the given |payload| in the chunked format to |output|.
- // Returns the number of bytes written to |output|. |output_size| should
- // be large enough to store the encoded chunk, which is payload.size() +
- // kChunkHeaderFooterSize. Returns ERR_INVALID_ARGUMENT if |output_size|
- // is not large enough.
- //
- // The output will look like: "HEX\r\n[payload]\r\n"
- // where HEX is a length in hexdecimal (without the "0x" prefix).
- static int EncodeChunk(const base::StringPiece& payload,
- char* output,
- size_t output_size);
-
- // The number of extra bytes required to encode a chunk.
- static const size_t kChunkHeaderFooterSize;
-
private:
// FOO_COMPLETE states implement the second half of potentially asynchronous
// operations and don't necessarily mean that FOO is complete.
diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
deleted file mode 100644
index d40eac6..0000000
--- a/net/http/http_stream_parser_unittest.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/http_stream_parser.h"
-
-#include "base/string_piece.h"
-#include "base/stringprintf.h"
-#include "net/base/net_errors.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-const size_t kOutputSize = 1024; // Just large enough for this test.
-// The number of bytes that can fit in a buffer of kOutputSize.
-const size_t kMaxPayloadSize =
- kOutputSize - HttpStreamParser::kChunkHeaderFooterSize;
-
-// The empty payload is how the last chunk is encoded.
-TEST(HttpStreamParser, EncodeChunk_EmptyPayload) {
- char output[kOutputSize];
-
- const base::StringPiece kPayload = "";
- const base::StringPiece kExpected = "0\r\n\r\n";
- const int num_bytes_written =
- HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output));
- ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written));
- EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written));
-}
-
-TEST(HttpStreamParser, EncodeChunk_ShortPayload) {
- char output[kOutputSize];
-
- const std::string kPayload("foo\x00\x11\x22", 6);
- // 11 = payload size + sizeof("6") + CRLF x 2.
- const std::string kExpected("6\r\nfoo\x00\x11\x22\r\n", 11);
- const int num_bytes_written =
- HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output));
- ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written));
- EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written));
-}
-
-TEST(HttpStreamParser, EncodeChunk_LargePayload) {
- char output[kOutputSize];
-
- const std::string kPayload(1000, '\xff'); // '\xff' x 1000.
- // 3E8 = 1000 in hex.
- const std::string kExpected = "3E8\r\n" + kPayload + "\r\n";
- const int num_bytes_written =
- HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output));
- ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written));
- EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written));
-}
-
-TEST(HttpStreamParser, EncodeChunk_FullPayload) {
- char output[kOutputSize];
-
- const std::string kPayload(kMaxPayloadSize, '\xff');
- // 3F4 = 1012 in hex.
- const std::string kExpected = "3F4\r\n" + kPayload + "\r\n";
- const int num_bytes_written =
- HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output));
- ASSERT_EQ(kExpected.size(), static_cast<size_t>(num_bytes_written));
- EXPECT_EQ(kExpected, base::StringPiece(output, num_bytes_written));
-}
-
-TEST(HttpStreamParser, EncodeChunk_TooLargePayload) {
- char output[kOutputSize];
-
- // The payload is one byte larger the output buffer size.
- const std::string kPayload(kMaxPayloadSize + 1, '\xff');
- const int num_bytes_written =
- HttpStreamParser::EncodeChunk(kPayload, output, sizeof(output));
- ASSERT_EQ(ERR_INVALID_ARGUMENT, num_bytes_written);
-}
-
-} // namespace net