summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/string_util.cc14
-rw-r--r--net/http/http_auth_handler.h2
-rw-r--r--net/http/http_auth_sspi_win.h3
-rw-r--r--net/http/http_basic_stream.h2
-rw-r--r--net/http/http_cache.h2
-rw-r--r--net/http/http_cache_transaction.cc83
-rw-r--r--net/http/http_cache_unittest.cc135
-rw-r--r--net/http/http_network_layer_unittest.cc3
-rw-r--r--net/http/http_network_transaction.cc52
-rw-r--r--net/http/http_network_transaction_unittest.cc12
-rw-r--r--net/http/http_request_headers.cc83
-rw-r--r--net/http/http_request_headers.h91
-rw-r--r--net/http/http_request_headers_unittest.cc28
-rw-r--r--net/http/http_request_info.h11
-rw-r--r--net/http/http_stream.h2
-rw-r--r--net/http/http_stream_parser.h2
-rw-r--r--net/http/http_transaction.h2
-rw-r--r--net/http/http_transaction_unittest.h2
-rw-r--r--net/http/http_util.cc6
-rw-r--r--net/http/http_util.h5
-rw-r--r--net/http/http_vary_data.cc28
-rw-r--r--net/http/http_vary_data.h2
-rw-r--r--net/http/http_vary_data_unittest.cc15
-rw-r--r--net/http/partial_data.cc50
-rw-r--r--net/http/partial_data.h17
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc22
-rw-r--r--net/spdy/spdy_session.cc14
-rw-r--r--net/spdy/spdy_session.h2
-rw-r--r--net/url_request/url_request_http_job.cc51
29 files changed, 409 insertions, 332 deletions
diff --git a/base/string_util.cc b/base/string_util.cc
index fafc106..0269ba1 100644
--- a/base/string_util.cc
+++ b/base/string_util.cc
@@ -1352,20 +1352,6 @@ void SplitStringUsingSubstr(const std::string& str,
SplitStringUsingSubstrT(str, s, r);
}
-std::vector<string16> SplitStringUsingSubstr(const string16& str,
- const string16& s) {
- std::vector<string16> result;
- SplitStringUsingSubstr(str, s, &result);
- return result;
-}
-
-std::vector<std::string> SplitStringUsingSubstr(const std::string& str,
- const std::string& s) {
- std::vector<std::string> result;
- SplitStringUsingSubstr(str, s, &result);
- return result;
-}
-
template<typename STR>
static size_t TokenizeT(const STR& str,
const STR& delimiters,
diff --git a/net/http/http_auth_handler.h b/net/http/http_auth_handler.h
index dc87d34..40ebe8d 100644
--- a/net/http/http_auth_handler.h
+++ b/net/http/http_auth_handler.h
@@ -15,8 +15,8 @@ namespace net {
class BoundNetLog;
class HostResolver;
-class HttpRequestInfo;
class ProxyInfo;
+struct HttpRequestInfo;
// HttpAuthHandler is the interface for the authentication schemes
// (basic, digest, NTLM, Negotiate).
diff --git a/net/http/http_auth_sspi_win.h b/net/http/http_auth_sspi_win.h
index a6fb49e..12808bf 100644
--- a/net/http/http_auth_sspi_win.h
+++ b/net/http/http_auth_sspi_win.h
@@ -20,7 +20,7 @@
namespace net {
-class HttpRequestInfo;
+struct HttpRequestInfo;
class ProxyInfo;
// SSPILibrary is introduced so unit tests can mock the calls to Windows' SSPI
@@ -152,4 +152,3 @@ int DetermineMaxTokenLength(SSPILibrary* library,
} // namespace net
#endif // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
-
diff --git a/net/http/http_basic_stream.h b/net/http/http_basic_stream.h
index cd533db..8a31d64 100644
--- a/net/http/http_basic_stream.h
+++ b/net/http/http_basic_stream.h
@@ -20,7 +20,7 @@ namespace net {
class BoundNetLog;
class ClientSocketHandle;
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpResponseInfo;
class UploadDataStream;
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index f8db513..836bb52 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -40,7 +40,7 @@ namespace net {
class HostResolver;
class HttpAuthHandlerFactory;
class HttpNetworkSession;
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpResponseInfo;
class IOBuffer;
class NetworkChangeNotifier;
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index b5b3515..c0eefea 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -69,16 +69,17 @@ static const HeaderNameAndValue kForceValidateHeaders[] = {
{ NULL, NULL }
};
-static bool HeaderMatches(const HttpUtil::HeadersIterator& h,
+static bool HeaderMatches(const HttpRequestHeaders& headers,
const HeaderNameAndValue* search) {
for (; search->name; ++search) {
- if (!LowerCaseEqualsASCII(h.name_begin(), h.name_end(), search->name))
+ std::string header_value;
+ if (!headers.GetHeader(search->name, &header_value))
continue;
if (!search->value)
return true;
- HttpUtil::ValuesIterator v(h.values_begin(), h.values_end(), ',');
+ HttpUtil::ValuesIterator v(header_value.begin(), header_value.end(), ',');
while (v.GetNext()) {
if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value))
return true;
@@ -1176,45 +1177,37 @@ void HttpCache::Transaction::SetRequest(const BoundNetLog& net_log,
{ kForceValidateHeaders, LOAD_VALIDATE_CACHE },
};
- std::string new_extra_headers;
bool range_found = false;
bool external_validation_error = false;
- // scan request headers to see if we have any that would impact our load flags
- HttpUtil::HeadersIterator it(request_->extra_headers.begin(),
- request_->extra_headers.end(),
- "\r\n");
- while (it.GetNext()) {
- if (!LowerCaseEqualsASCII(it.name(), "range")) {
- new_extra_headers.append(it.name_begin(), it.values_end());
- new_extra_headers.append("\r\n");
+ if (request_->extra_headers.HasHeader(HttpRequestHeaders::kRange)) {
+ if (enable_range_support_) {
+ range_found = true;
} else {
- if (enable_range_support_) {
- range_found = true;
- } else {
- effective_load_flags_ |= LOAD_DISABLE_CACHE;
- continue;
- }
+ effective_load_flags_ |= LOAD_DISABLE_CACHE;
}
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) {
- if (HeaderMatches(it, kSpecialHeaders[i].search)) {
- effective_load_flags_ |= kSpecialHeaders[i].load_flag;
- break;
- }
+ }
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) {
+ if (HeaderMatches(request_->extra_headers, kSpecialHeaders[i].search)) {
+ effective_load_flags_ |= kSpecialHeaders[i].load_flag;
+ break;
}
+ }
- // Check for conditionalization headers which may correspond with a
- // cache validation request.
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); ++i) {
- const ValidationHeaderInfo& info = kValidationHeaders[i];
- if (LowerCaseEqualsASCII(it.name_begin(), it.name_end(),
- info.request_header_name)) {
- if (!external_validation_.values[i].empty() || it.values().empty())
- external_validation_error = true;
- external_validation_.values[i] = it.values();
- external_validation_.initialized = true;
- break;
- }
+ // Check for conditionalization headers which may correspond with a
+ // cache validation request.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); ++i) {
+ const ValidationHeaderInfo& info = kValidationHeaders[i];
+ std::string validation_value;
+ if (request_->extra_headers.GetHeader(
+ info.request_header_name, &validation_value)) {
+ if (!external_validation_.values[i].empty() ||
+ validation_value.empty())
+ external_validation_error = true;
+ external_validation_.values[i] = validation_value;
+ external_validation_.initialized = true;
+ break;
}
}
@@ -1238,9 +1231,9 @@ void HttpCache::Transaction::SetRequest(const BoundNetLog& net_log,
// We will be modifying the actual range requested to the server, so
// let's remove the header here.
custom_request_.reset(new HttpRequestInfo(*request_));
+ custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange);
request_ = custom_request_.get();
- custom_request_->extra_headers = new_extra_headers;
- partial_->SetHeaders(new_extra_headers);
+ partial_->SetHeaders(custom_request_->extra_headers);
} else {
// The range is invalid or we cannot handle it properly.
LOG(INFO) << "Invalid byte range found.";
@@ -1502,12 +1495,12 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
if (partial_.get() && !partial_->IsCurrentRangeCached()) {
// We don't want to switch to WRITE mode if we don't have this block of a
// byte-range request because we may have other parts cached.
- custom_request_->extra_headers.append("If-Range: ");
+ custom_request_->extra_headers.SetHeader(
+ HttpRequestHeaders::kIfRange, etag_value);
} else {
- custom_request_->extra_headers.append("If-None-Match: ");
+ custom_request_->extra_headers.SetHeader(
+ HttpRequestHeaders::kIfNoneMatch, etag_value);
}
- custom_request_->extra_headers.append(etag_value);
- custom_request_->extra_headers.append("\r\n");
// For byte-range requests, make sure that we use only one way to validate
// the request.
if (partial_.get() && !partial_->IsCurrentRangeCached())
@@ -1516,12 +1509,12 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
if (!last_modified_value.empty()) {
if (partial_.get() && !partial_->IsCurrentRangeCached()) {
- custom_request_->extra_headers.append("If-Range: ");
+ custom_request_->extra_headers.SetHeader(
+ HttpRequestHeaders::kIfRange, last_modified_value);
} else {
- custom_request_->extra_headers.append("If-Modified-Since: ");
+ custom_request_->extra_headers.SetHeader(
+ HttpRequestHeaders::kIfModifiedSince, last_modified_value);
}
- custom_request_->extra_headers.append(last_modified_value);
- custom_request_->extra_headers.append("\r\n");
}
return true;
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 4e8a139..48e61e7 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -15,6 +15,7 @@
#include "net/base/ssl_cert_request_info.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_byte_range.h"
+#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
@@ -726,20 +727,21 @@ bool RangeTransactionServer::modified_ = false;
bool RangeTransactionServer::bad_200_ = false;
// A dummy extra header that must be preserved on a given request.
-#define EXTRA_HEADER "Extra: header\r\n"
+#define EXTRA_HEADER "Extra: header"
+static const char kExtraHeaderKey[] = "Extra";
// Static.
void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
std::string* response_status,
std::string* response_headers,
std::string* response_data) {
- if (request->extra_headers.empty()) {
+ if (request->extra_headers.IsEmpty()) {
response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
return;
}
// We want to make sure we don't delete extra headers.
- EXPECT_TRUE(request->extra_headers.find(EXTRA_HEADER) != std::string::npos);
+ EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
if (not_modified_) {
response_status->assign("HTTP/1.1 304 Not Modified");
@@ -747,7 +749,10 @@ void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
}
std::vector<net::HttpByteRange> ranges;
- if (!net::HttpUtil::ParseRanges(request->extra_headers, &ranges) ||
+ std::string range_header;
+ if (!request->extra_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &range_header) ||
+ !net::HttpUtil::ParseRangeHeader(range_header, &ranges) ||
ranges.size() != 1)
return;
// We can handle this range request.
@@ -763,19 +768,11 @@ void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
EXPECT_LT(end, 80);
- size_t if_range_header = request->extra_headers.find("If-Range");
- if (std::string::npos != if_range_header) {
- // Check that If-Range isn't specified twice.
- EXPECT_EQ(std::string::npos,
- request->extra_headers.find("If-Range", if_range_header + 1));
- }
-
std::string content_range = StringPrintf("Content-Range: bytes %d-%d/80\n",
start, end);
response_headers->append(content_range);
- if (request->extra_headers.find("If-None-Match") == std::string::npos ||
- modified_) {
+ if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
EXPECT_EQ(9, (end - start) % 10);
std::string data;
for (int block_start = start; block_start < end; block_start += 10)
@@ -819,33 +816,25 @@ const MockTransaction kRangeGET_TransactionOK = {
0
};
-// Returns true if the response headers (|response|) match a partial content
+// Verifies the response headers (|response|) match a partial content
// response for the range starting at |start| and ending at |end|.
-bool Verify206Response(std::string response, int start, int end) {
+void Verify206Response(std::string response, int start, int end) {
std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
response.size()));
scoped_refptr<net::HttpResponseHeaders> headers =
new net::HttpResponseHeaders(raw_headers);
- if (206 != headers->response_code())
- return false;
+ ASSERT_EQ(206, headers->response_code());
int64 range_start, range_end, object_size;
- if (!headers->GetContentRange(&range_start, &range_end, &object_size))
- return false;
+ ASSERT_TRUE(
+ headers->GetContentRange(&range_start, &range_end, &object_size));
int64 content_length = headers->GetContentLength();
int length = end - start + 1;
- if (content_length != length)
- return false;
-
- if (range_start != start)
- return false;
-
- if (range_end != end)
- return false;
-
- return true;
+ ASSERT_EQ(length, content_length);
+ ASSERT_EQ(start, range_start);
+ ASSERT_EQ(end, range_end);
}
// Helper to represent a network HTTP response.
@@ -1220,7 +1209,7 @@ static void PreserveRequestHeaders_Handler(
std::string* response_status,
std::string* response_headers,
std::string* response_data) {
- EXPECT_TRUE(request->extra_headers.find(EXTRA_HEADER) != std::string::npos);
+ EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
}
// Tests that we don't remove extra headers for simple requests.
@@ -1252,7 +1241,7 @@ TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
MockTransaction transaction(kETagGET_Transaction);
transaction.handler = PreserveRequestHeaders_Handler;
- transaction.request_headers = "If-None-Match: \"foopy\"\n"
+ transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
EXTRA_HEADER;
AddMockTransaction(&transaction);
@@ -1703,8 +1692,8 @@ static void ETagGet_ConditionalRequest_Handler(
std::string* response_status,
std::string* response_headers,
std::string* response_data) {
- EXPECT_TRUE(request->extra_headers.find("If-None-Match") !=
- std::string::npos);
+ EXPECT_TRUE(
+ request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
response_status->assign("HTTP/1.1 304 Not Modified");
response_headers->assign(kETagGET_Transaction.response_headers);
response_data->clear();
@@ -1738,8 +1727,8 @@ static void ETagGet_ConditionalRequest_NoStore_Handler(
std::string* response_status,
std::string* response_headers,
std::string* response_data) {
- EXPECT_TRUE(request->extra_headers.find("If-None-Match") !=
- std::string::npos);
+ EXPECT_TRUE(
+ request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
response_status->assign("HTTP/1.1 304 Not Modified");
response_headers->assign("Cache-Control: no-store\n");
response_data->clear();
@@ -2004,7 +1993,7 @@ TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
};
const char* kExtraRequestHeaders =
- "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
+ "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
// We will control the network layer's responses for |kUrl| using
// |mock_network_response|.
@@ -2048,7 +2037,7 @@ TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
};
const char* kExtraRequestHeaders =
- "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
+ "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
// We will control the network layer's responses for |kUrl| using
// |mock_network_response|.
@@ -2156,8 +2145,8 @@ TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
};
const char* kExtraRequestHeaders =
- "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"
- "If-None-Match: \"Foo1\"\n";
+ "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
+ "If-None-Match: \"Foo1\"\r\n";
ConditionalizedRequestUpdatesCacheHelper(
kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
@@ -2371,9 +2360,9 @@ TEST(HttpCache, RangeGET_SkipsCache2) {
cache.http_cache()->set_enable_range_support(true);
MockTransaction transaction(kRangeGET_Transaction);
- transaction.request_headers = "If-None-Match: foo\n"
+ transaction.request_headers = "If-None-Match: foo\r\n"
EXTRA_HEADER
- "Range: bytes = 40-49\n";
+ "\r\nRange: bytes = 40-49";
RunTransactionTest(cache.http_cache(), transaction);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
@@ -2381,18 +2370,18 @@ TEST(HttpCache, RangeGET_SkipsCache2) {
EXPECT_EQ(0, cache.disk_cache()->create_count());
transaction.request_headers =
- "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\n"
+ "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
EXTRA_HEADER
- "Range: bytes = 40-49\n";
+ "\r\nRange: bytes = 40-49";
RunTransactionTest(cache.http_cache(), transaction);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(0, cache.disk_cache()->create_count());
- transaction.request_headers = "If-Range: bla\n"
+ transaction.request_headers = "If-Range: bla\r\n"
EXTRA_HEADER
- "Range: bytes = 40-49\n";
+ "\r\nRange: bytes = 40-49\n";
RunTransactionTest(cache.http_cache(), transaction);
EXPECT_EQ(3, cache.network_layer()->transaction_count());
@@ -2437,7 +2426,7 @@ TEST(HttpCache, RangeGET_OK) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2446,7 +2435,7 @@ TEST(HttpCache, RangeGET_OK) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2460,7 +2449,7 @@ TEST(HttpCache, RangeGET_OK) {
transaction.data = "rg: 30-39 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 30, 39));
+ Verify206Response(headers, 30, 39);
EXPECT_EQ(3, cache.network_layer()->transaction_count());
EXPECT_EQ(2, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2473,7 +2462,7 @@ TEST(HttpCache, RangeGET_OK) {
transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 20, 59));
+ Verify206Response(headers, 20, 59);
EXPECT_EQ(5, cache.network_layer()->transaction_count());
EXPECT_EQ(3, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2495,7 +2484,7 @@ TEST(HttpCache, RangeGET_SyncOK) {
std::string headers;
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2503,7 +2492,7 @@ TEST(HttpCache, RangeGET_SyncOK) {
// Read from the cache (40-49).
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2516,7 +2505,7 @@ TEST(HttpCache, RangeGET_SyncOK) {
transaction.data = "rg: 30-39 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 30, 39));
+ Verify206Response(headers, 30, 39);
EXPECT_EQ(3, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2529,7 +2518,7 @@ TEST(HttpCache, RangeGET_SyncOK) {
transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 20, 59));
+ Verify206Response(headers, 20, 59);
EXPECT_EQ(5, cache.network_layer()->transaction_count());
EXPECT_EQ(2, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2548,7 +2537,7 @@ TEST(HttpCache, RangeGET_304) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2559,7 +2548,7 @@ TEST(HttpCache, RangeGET_304) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2578,7 +2567,7 @@ TEST(HttpCache, RangeGET_ModifiedResult) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2589,7 +2578,7 @@ TEST(HttpCache, RangeGET_ModifiedResult) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2617,7 +2606,7 @@ TEST(HttpCache, UnknownRangeGET_1) {
transaction.data = "rg: 70-79 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 70, 79));
+ Verify206Response(headers, 70, 79);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2630,7 +2619,7 @@ TEST(HttpCache, UnknownRangeGET_1) {
transaction.data = "rg: 60-69 rg: 70-79 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 60, 79));
+ Verify206Response(headers, 60, 79);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2657,7 +2646,7 @@ TEST(HttpCache, UnknownRangeGET_2) {
transaction.data = "rg: 70-79 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 70, 79));
+ Verify206Response(headers, 70, 79);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2670,7 +2659,7 @@ TEST(HttpCache, UnknownRangeGET_2) {
transaction.data = "rg: 60-69 rg: 70-79 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 60, 79));
+ Verify206Response(headers, 60, 79);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2719,7 +2708,7 @@ TEST(HttpCache, GET_Previous206) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2754,7 +2743,7 @@ TEST(HttpCache, GET_Previous206_NotModified) {
// Write to the cache (0-9).
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 0, 9));
+ Verify206Response(headers, 0, 9);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2788,7 +2777,7 @@ TEST(HttpCache, GET_Previous206_NewContent) {
transaction.data = "rg: 00-09 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 0, 9));
+ Verify206Response(headers, 0, 9);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2892,7 +2881,7 @@ TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
&headers);
// We are expecting a 206.
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(2, cache.disk_cache()->create_count());
@@ -2927,7 +2916,7 @@ TEST(HttpCache, RangeGET_Previous200) {
RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
// We are expecting a 206.
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2939,7 +2928,7 @@ TEST(HttpCache, RangeGET_Previous200) {
handler.set_not_modified(false);
transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(3, cache.network_layer()->transaction_count());
EXPECT_EQ(2, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -2963,7 +2952,7 @@ TEST(HttpCache, RangeRequestResultsIn200) {
transaction.data = "rg: 70-79 ";
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 70, 79));
+ Verify206Response(headers, 70, 79);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -3002,7 +2991,7 @@ TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -3243,7 +3232,7 @@ TEST(HttpCache, RangeGET_InvalidResponse3) {
AddMockTransaction(&transaction);
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 50, 59));
+ Verify206Response(headers, 50, 59);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -3256,7 +3245,7 @@ TEST(HttpCache, RangeGET_InvalidResponse3) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
@@ -3334,7 +3323,7 @@ TEST(HttpCache, RangeHEAD) {
std::string headers;
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
- EXPECT_TRUE(Verify206Response(headers, 70, 79));
+ Verify206Response(headers, 70, 79);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(0, cache.disk_cache()->open_count());
EXPECT_EQ(0, cache.disk_cache()->create_count());
@@ -3876,7 +3865,7 @@ TEST(HttpCache, RangeGET_IncompleteResource) {
RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
&headers);
- EXPECT_TRUE(Verify206Response(headers, 40, 49));
+ Verify206Response(headers, 40, 49);
EXPECT_EQ(1, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(2, cache.disk_cache()->create_count());
diff --git a/net/http/http_network_layer_unittest.cc b/net/http/http_network_layer_unittest.cc
index e8aa494..697fe98 100644
--- a/net/http/http_network_layer_unittest.cc
+++ b/net/http/http_network_layer_unittest.cc
@@ -82,7 +82,8 @@ TEST_F(HttpNetworkLayerTest, GET) {
net::HttpRequestInfo request_info;
request_info.url = GURL("http://www.google.com/");
request_info.method = "GET";
- request_info.user_agent = "Foo/1.0";
+ request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kUserAgent,
+ "Foo/1.0");
request_info.load_flags = net::LOAD_NORMAL;
rv = trans->Start(&request_info, &callback, net::BoundNetLog());
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 64c4fd9..39111f4 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -57,13 +57,13 @@ void BuildRequestHeaders(const HttpRequestInfo* request_info,
const HttpRequestHeaders& authorization_headers,
const UploadDataStream* upload_data_stream,
bool using_proxy,
+ std::string* request_line,
HttpRequestHeaders* request_headers) {
const std::string path = using_proxy ?
HttpUtil::SpecForRequest(request_info->url) :
HttpUtil::PathForRequest(request_info->url);
- request_headers->SetRequestLine(
- request_info->method, path, "1.1");
-
+ *request_line = StringPrintf(
+ "%s %s HTTP/1.1\r\n", request_info->method.c_str(), path.c_str());
request_headers->SetHeader(HttpRequestHeaders::kHost,
GetHostAndOptionalPort(request_info->url));
@@ -75,11 +75,6 @@ void BuildRequestHeaders(const HttpRequestInfo* request_info,
request_headers->SetHeader(HttpRequestHeaders::kConnection, "keep-alive");
}
- if (!request_info->user_agent.empty()) {
- request_headers->SetHeader(HttpRequestHeaders::kUserAgent,
- request_info->user_agent);
- }
-
// Our consumer should have made sure that this is a safe referrer. See for
// instance WebCore::FrameLoader::HideReferrer.
if (request_info->referrer.is_valid()) {
@@ -120,22 +115,11 @@ void BuildRequestHeaders(const HttpRequestInfo* request_info,
"Referer"
};
- // TODO(willchan): Change HttpRequestInfo::extra_headers to be a
- // HttpRequestHeaders.
-
- std::vector<std::string> extra_headers_vector;
- Tokenize(request_info->extra_headers, "\r\n", &extra_headers_vector);
- HttpRequestHeaders extra_headers;
- if (!extra_headers_vector.empty()) {
- for (std::vector<std::string>::const_iterator it =
- extra_headers_vector.begin(); it != extra_headers_vector.end(); ++it)
- extra_headers.AddHeaderFromString(*it);
-
+ HttpRequestHeaders stripped_extra_headers;
+ stripped_extra_headers.CopyFrom(request_info->extra_headers);
for (size_t i = 0; i < arraysize(kExtraHeadersToBeStripped); ++i)
- extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]);
-
- request_headers->MergeFrom(extra_headers);
- }
+ stripped_extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]);
+ request_headers->MergeFrom(stripped_extra_headers);
}
// The HTTP CONNECT method for establishing a tunnel connection is documented
@@ -143,21 +127,22 @@ void BuildRequestHeaders(const HttpRequestInfo* request_info,
// 5.3.
void BuildTunnelRequest(const HttpRequestInfo* request_info,
const HttpRequestHeaders& authorization_headers,
+ std::string* request_line,
HttpRequestHeaders* request_headers) {
// RFC 2616 Section 9 says the Host request-header field MUST accompany all
// HTTP/1.1 requests. Add "Proxy-Connection: keep-alive" for compat with
// HTTP/1.0 proxies such as Squid (required for NTLM authentication).
- request_headers->SetRequestLine(
- "CONNECT", GetHostAndPort(request_info->url), "1.1");
+ *request_line = StringPrintf(
+ "CONNECT %s HTTP/1.1\r\n", GetHostAndPort(request_info->url).c_str());
request_headers->SetHeader(HttpRequestHeaders::kHost,
GetHostAndOptionalPort(request_info->url));
request_headers->SetHeader(HttpRequestHeaders::kProxyConnection,
"keep-alive");
- if (!request_info->user_agent.empty()) {
- request_headers->SetHeader(HttpRequestHeaders::kUserAgent,
- request_info->user_agent);
- }
+ std::string user_agent;
+ if (request_info->extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
+ &user_agent))
+ request_headers->SetHeader(HttpRequestHeaders::kUserAgent, user_agent);
request_headers->MergeFrom(authorization_headers);
}
@@ -962,6 +947,7 @@ int HttpNetworkTransaction::DoSendRequest() {
(HaveAuth(HttpAuth::AUTH_SERVER) ||
SelectPreemptiveAuth(HttpAuth::AUTH_SERVER));
+ std::string request_line;
HttpRequestHeaders request_headers;
HttpRequestHeaders authorization_headers;
@@ -974,13 +960,15 @@ int HttpNetworkTransaction::DoSendRequest() {
AddAuthorizationHeader(HttpAuth::AUTH_SERVER, &authorization_headers);
if (establishing_tunnel_) {
- BuildTunnelRequest(request_, authorization_headers, &request_headers);
+ BuildTunnelRequest(request_, authorization_headers, &request_line,
+ &request_headers);
} else {
BuildRequestHeaders(request_, authorization_headers, request_body,
- proxy_mode_ == kHTTPProxy, &request_headers);
+ proxy_mode_ == kHTTPProxy, &request_line,
+ &request_headers);
}
- request_headers_ = request_headers.ToString();
+ request_headers_ = request_line + request_headers.ToString();
}
headers_valid_ = false;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 28dfa8d..8c0d8bd 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -2924,7 +2924,8 @@ TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
std::replace(temp.begin(), temp.end(), '\n', '\0');
scoped_refptr<HttpResponseHeaders> headers = new HttpResponseHeaders(temp);
- request.extra_headers = "Foo: 1\nbar: 23";
+ request.extra_headers.SetHeader("Foo", "1");
+ request.extra_headers.SetHeader("bar", "23");
EXPECT_TRUE(response->vary_data.Init(request, *headers));
}
@@ -3083,7 +3084,8 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.google.com/");
- request.user_agent = "Chromium Ultra Awesome X Edition";
+ request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
+ "Chromium Ultra Awesome X Edition");
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -3349,7 +3351,7 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.google.com/");
- request.extra_headers = "FooHeader: Bar\r\n";
+ request.extra_headers.SetHeader("FooHeader", "Bar");
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -3387,7 +3389,9 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.google.com/");
- request.extra_headers = "referer: www.foo.com\nhEllo: Kitty\rFoO: bar\r\n";
+ request.extra_headers.SetHeader("referer", "www.foo.com");
+ request.extra_headers.SetHeader("hEllo", "Kitty");
+ request.extra_headers.SetHeader("FoO", "bar");
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc
index d894584..43e6205 100644
--- a/net/http/http_request_headers.cc
+++ b/net/http/http_request_headers.cc
@@ -11,29 +11,57 @@
namespace net {
const char HttpRequestHeaders::kGetMethod[] = "GET";
-
+const char HttpRequestHeaders::kAcceptCharset[] = "Accept-Charset";
+const char HttpRequestHeaders::kAcceptEncoding[] = "Accept-Encoding";
+const char HttpRequestHeaders::kAcceptLanguage[] = "Accept-Language";
const char HttpRequestHeaders::kCacheControl[] = "Cache-Control";
const char HttpRequestHeaders::kConnection[] = "Connection";
+const char HttpRequestHeaders::kCookie[] = "Cookie";
const char HttpRequestHeaders::kContentLength[] = "Content-Length";
const char HttpRequestHeaders::kHost[] = "Host";
+const char HttpRequestHeaders::kIfModifiedSince[] = "If-Modified-Since";
+const char HttpRequestHeaders::kIfNoneMatch[] = "If-None-Match";
+const char HttpRequestHeaders::kIfRange[] = "If-Range";
const char HttpRequestHeaders::kPragma[] = "Pragma";
const char HttpRequestHeaders::kProxyConnection[] = "Proxy-Connection";
+const char HttpRequestHeaders::kRange[] = "Range";
const char HttpRequestHeaders::kReferer[] = "Referer";
const char HttpRequestHeaders::kUserAgent[] = "User-Agent";
+HttpRequestHeaders::Iterator::Iterator(const HttpRequestHeaders& headers)
+ : started_(false),
+ curr_(headers.headers_.begin()),
+ end_(headers.headers_.end()) {}
+
+HttpRequestHeaders::Iterator::~Iterator() {}
+
+bool HttpRequestHeaders::Iterator::GetNext() {
+ if (!started_) {
+ started_ = true;
+ return curr_ != end_;
+ }
+
+ if (curr_ == end_)
+ return false;
+
+ ++curr_;
+ return curr_ != end_;
+}
+
HttpRequestHeaders::HttpRequestHeaders() {}
HttpRequestHeaders::~HttpRequestHeaders() {}
-void HttpRequestHeaders::SetRequestLine(const base::StringPiece& method,
- const base::StringPiece& path,
- const base::StringPiece& version) {
- DCHECK(!method.empty());
- DCHECK(!path.empty());
- DCHECK(!version.empty());
+bool HttpRequestHeaders::GetHeader(const base::StringPiece& key,
+ std::string* out) const {
+ HeaderVector::const_iterator it = FindHeader(key);
+ if (it == headers_.end())
+ return false;
+ out->assign(it->value);
+ return true;
+}
- method_.assign(method.data(), method.length());
- path_.assign(path.data(), path.length());
- version_.assign(version.data(), version.length());
+void HttpRequestHeaders::Clear() {
+ headers_.clear();
}
void HttpRequestHeaders::SetHeader(const base::StringPiece& key,
@@ -95,11 +123,20 @@ void HttpRequestHeaders::AddHeaderFromString(
}
}
-void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) {
- DCHECK(other.method_.empty());
- DCHECK(other.path_.empty());
- DCHECK(other.version_.empty());
+void HttpRequestHeaders::AddHeadersFromString(
+ const base::StringPiece& headers) {
+ // TODO(willchan): Consider adding more StringPiece support in string_util.h
+ // to eliminate copies.
+ std::vector<std::string> header_line_vector;
+ SplitStringUsingSubstr(headers.as_string(), "\r\n", &header_line_vector);
+ for (std::vector<std::string>::const_iterator it = header_line_vector.begin();
+ it != header_line_vector.end(); ++it) {
+ if (!it->empty())
+ AddHeaderFromString(*it);
+ }
+}
+void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) {
for (HeaderVector::const_iterator it = other.headers_.begin();
it != other.headers_.end(); ++it ) {
SetHeader(it->key, it->value);
@@ -108,12 +145,6 @@ void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) {
std::string HttpRequestHeaders::ToString() const {
std::string output;
- if (!method_.empty()) {
- DCHECK(!path_.empty());
- DCHECK(!version_.empty());
- output = StringPrintf(
- "%s %s HTTP/%s\r\n", method_.c_str(), path_.c_str(), version_.c_str());
- }
for (HeaderVector::const_iterator it = headers_.begin();
it != headers_.end(); ++it) {
if (!it->value.empty())
@@ -137,4 +168,16 @@ HttpRequestHeaders::FindHeader(const base::StringPiece& key) {
return headers_.end();
}
+HttpRequestHeaders::HeaderVector::const_iterator
+HttpRequestHeaders::FindHeader(const base::StringPiece& key) const {
+ for (HeaderVector::const_iterator it = headers_.begin();
+ it != headers_.end(); ++it) {
+ if (key.length() == it->key.length() &&
+ !base::strncasecmp(key.data(), it->key.data(), key.length()))
+ return it;
+ }
+
+ return headers_.end();
+}
+
} // namespace net
diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h
index 79522aa..c107a3c 100644
--- a/net/http/http_request_headers.h
+++ b/net/http/http_request_headers.h
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// HttpRequestHeaders manages the request headers (including the request line).
+// HttpRequestHeaders manages the request headers.
// It maintains these in a vector of header key/value pairs, thereby maintaining
// the order of the headers. This means that any lookups are linear time
// operations.
@@ -19,23 +19,74 @@ namespace net {
class HttpRequestHeaders {
public:
+ struct HeaderKeyValuePair {
+ HeaderKeyValuePair() {}
+ HeaderKeyValuePair(const base::StringPiece& key,
+ const base::StringPiece& value)
+ : key(key.data(), key.size()), value(value.data(), value.size()) {}
+
+ std::string key;
+ std::string value;
+ };
+
+ typedef std::vector<HeaderKeyValuePair> HeaderVector;
+
+ class Iterator {
+ public:
+ explicit Iterator(const HttpRequestHeaders& headers);
+ ~Iterator();
+
+ // Advances the iterator to the next header, if any. Returns true if there
+ // is a next header. Use name() and value() methods to access the resultant
+ // header name and value.
+ bool GetNext();
+
+ // These two accessors are only valid if GetNext() returned true.
+ const std::string& name() const { return curr_->key; }
+ const std::string& value() const { return curr_->value; }
+
+ private:
+ bool started_;
+ HttpRequestHeaders::HeaderVector::const_iterator curr_;
+ const HttpRequestHeaders::HeaderVector::const_iterator end_;
+
+ DISALLOW_COPY_AND_ASSIGN(Iterator);
+ };
+
static const char kGetMethod[];
+ static const char kAcceptCharset[];
+ static const char kAcceptEncoding[];
+ static const char kAcceptLanguage[];
static const char kCacheControl[];
static const char kConnection[];
+ static const char kCookie[];
static const char kContentLength[];
static const char kHost[];
+ static const char kIfModifiedSince[];
+ static const char kIfNoneMatch[];
+ static const char kIfRange[];
static const char kPragma[];
static const char kProxyConnection[];
+ static const char kRange[];
static const char kReferer[];
static const char kUserAgent[];
HttpRequestHeaders();
~HttpRequestHeaders();
- void SetRequestLine(const base::StringPiece& method,
- const base::StringPiece& path,
- const base::StringPiece& version);
+ bool IsEmpty() const { return headers_.empty(); }
+
+ bool HasHeader(const base::StringPiece& key) const {
+ return FindHeader(key) != headers_.end();
+ }
+
+ // Gets the first header that matches |key|. If found, returns true and
+ // writes the value to |out|.
+ bool GetHeader(const base::StringPiece& key, std::string* out) const;
+
+ // Clears all the headers.
+ void Clear();
// Sets the header value pair for |key| and |value|. If |key| already exists,
// then the header value is modified, but the key is untouched, and the order
@@ -59,37 +110,35 @@ class HttpRequestHeaders {
// field-content.
void AddHeaderFromString(const base::StringPiece& header_line);
+ // Same thing as AddHeaderFromString() except that |headers| is a "\r\n"
+ // delimited string of header lines. It will split up the string by "\r\n"
+ // and call AddHeaderFromString() on each.
+ void AddHeadersFromString(const base::StringPiece& headers);
+
// Calls SetHeader() on each header from |other|, maintaining order.
void MergeFrom(const HttpRequestHeaders& other);
+ // Copies from |other| to |this|.
+ void CopyFrom(const HttpRequestHeaders& other) {
+ *this = other;
+ }
+
// Serializes HttpRequestHeaders to a string representation. Joins all the
// header keys and values with ": ", and inserts "\r\n" between each header
// line, and adds the trailing "\r\n".
std::string ToString() const;
private:
- struct HeaderKeyValuePair {
- HeaderKeyValuePair() {}
- HeaderKeyValuePair(const base::StringPiece& key,
- const base::StringPiece& value)
- : key(key.data(), key.size()), value(value.data(), value.size()) {}
-
- std::string key;
- std::string value;
- };
-
- typedef std::vector<HeaderKeyValuePair> HeaderVector;
-
HeaderVector::iterator FindHeader(const base::StringPiece& key);
HeaderVector::const_iterator FindHeader(const base::StringPiece& key) const;
- std::string method_;
- std::string path_;
- std::string version_;
-
HeaderVector headers_;
- DISALLOW_COPY_AND_ASSIGN(HttpRequestHeaders);
+ // Allow the copy construction and operator= to facilitate copying in
+ // HttpRequestInfo.
+ // TODO(willchan): Investigate to see if we can remove the need to copy
+ // HttpRequestInfo.
+ // DISALLOW_COPY_AND_ASSIGN(HttpRequestHeaders);
};
} // namespace net
diff --git a/net/http/http_request_headers_unittest.cc b/net/http/http_request_headers_unittest.cc
index 29431d9..f3abfbe2 100644
--- a/net/http/http_request_headers_unittest.cc
+++ b/net/http/http_request_headers_unittest.cc
@@ -10,11 +10,17 @@ namespace net {
namespace {
-TEST(HttpRequestHeaders, SetRequestLine) {
+TEST(HttpRequestHeaders, HasHeader) {
HttpRequestHeaders headers;
- headers.SetRequestLine(
- HttpRequestHeaders::kGetMethod, "/foo", "1.1");
- EXPECT_EQ("GET /foo HTTP/1.1\r\n\r\n", headers.ToString());
+ headers.SetHeader("Foo", "bar");
+ EXPECT_TRUE(headers.HasHeader("foo"));
+ EXPECT_TRUE(headers.HasHeader("Foo"));
+ EXPECT_FALSE(headers.HasHeader("Fo"));
+
+ const HttpRequestHeaders& headers_ref = headers;
+ EXPECT_TRUE(headers_ref.HasHeader("foo"));
+ EXPECT_TRUE(headers_ref.HasHeader("Foo"));
+ EXPECT_FALSE(headers_ref.HasHeader("Fo"));
}
TEST(HttpRequestHeaders, SetHeader) {
@@ -50,6 +56,8 @@ TEST(HttpRequestHeaders, SetHeaderTwiceSamePrefix) {
headers.SetHeader("FooBar", "smokes");
headers.SetHeader("Foo", "crack");
EXPECT_EQ("FooBar: smokes\r\nFoo: crack\r\n\r\n", headers.ToString());
+ const HttpRequestHeaders& headers_ref = headers;
+ EXPECT_EQ("FooBar: smokes\r\nFoo: crack\r\n\r\n", headers_ref.ToString());
}
TEST(HttpRequestHeaders, SetEmptyHeader) {
@@ -135,6 +143,18 @@ TEST(HttpRequestHeaders, MergeFrom) {
EXPECT_EQ("A: A\r\nB: b\r\nC: c\r\n\r\n", headers.ToString());
}
+TEST(HttpRequestHeaders, CopyFrom) {
+ HttpRequestHeaders headers;
+ headers.SetHeader("A", "A");
+ headers.SetHeader("B", "B");
+
+ HttpRequestHeaders headers2;
+ headers2.SetHeader("B", "b");
+ headers2.SetHeader("C", "c");
+ headers.CopyFrom(headers2);
+ EXPECT_EQ("B: b\r\nC: c\r\n\r\n", headers.ToString());
+}
+
} // namespace
} // namespace net
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index 7ada539..c36e21a 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -10,10 +10,11 @@
#include "googleurl/src/gurl.h"
#include "net/base/request_priority.h"
#include "net/base/upload_data.h"
+#include "net/http/http_request_headers.h"
namespace net {
-class HttpRequestInfo {
+struct HttpRequestInfo {
public:
HttpRequestInfo() : load_flags(0), priority(LOWEST) {
}
@@ -27,12 +28,8 @@ class HttpRequestInfo {
// The method to use (GET, POST, etc.).
std::string method;
- // The user agent string to use. TODO(darin): we should just add this to
- // extra_headers
- std::string user_agent;
-
- // Any extra request headers (\r\n-delimited).
- std::string extra_headers;
+ // Any extra request headers (including User-Agent).
+ HttpRequestHeaders extra_headers;
// Any upload data.
scoped_refptr<UploadData> upload_data;
diff --git a/net/http/http_stream.h b/net/http/http_stream.h
index 87bd8e2..de2a8d78 100644
--- a/net/http/http_stream.h
+++ b/net/http/http_stream.h
@@ -17,7 +17,7 @@
namespace net {
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpResponseInfo;
class IOBuffer;
class UploadDataStream;
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
index e42b9b5..724127f 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -18,7 +18,7 @@
namespace net {
class ClientSocketHandle;
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpStreamParser {
public:
diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h
index a18d422..103f8f6 100644
--- a/net/http/http_transaction.h
+++ b/net/http/http_transaction.h
@@ -13,7 +13,7 @@
namespace net {
class BoundNetLog;
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpResponseInfo;
class IOBuffer;
class X509Certificate;
diff --git a/net/http/http_transaction_unittest.h b/net/http/http_transaction_unittest.h
index e578db2..8a99812 100644
--- a/net/http/http_transaction_unittest.h
+++ b/net/http/http_transaction_unittest.h
@@ -97,7 +97,7 @@ class MockHttpRequest : public net::HttpRequestInfo {
explicit MockHttpRequest(const MockTransaction& t) {
url = GURL(t.url);
method = t.method;
- extra_headers = t.request_headers;
+ extra_headers.AddHeadersFromString(t.request_headers);
load_flags = t.load_flags;
}
};
diff --git a/net/http/http_util.cc b/net/http/http_util.cc
index 5ea46d0..2ca8f02 100644
--- a/net/http/http_util.cc
+++ b/net/http/http_util.cc
@@ -202,6 +202,12 @@ bool HttpUtil::ParseRanges(const std::string& headers,
if (ranges_specifier.empty())
return false;
+ return ParseRangeHeader(ranges_specifier, ranges);
+}
+
+// static
+bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier,
+ std::vector<HttpByteRange>* ranges) {
size_t equal_char_offset = ranges_specifier.find('=');
if (equal_char_offset == std::string::npos)
return false;
diff --git a/net/http/http_util.h b/net/http/http_util.h
index c630cfe..4d4b200 100644
--- a/net/http/http_util.h
+++ b/net/http/http_util.h
@@ -54,6 +54,11 @@ class HttpUtil {
static bool ParseRanges(const std::string& headers,
std::vector<HttpByteRange>* ranges);
+ // Same thing as ParseRanges except the Range header is known and its value
+ // is directly passed in, rather than requiring searching through a string.
+ static bool ParseRangeHeader(const std::string& range_specifier,
+ std::vector<HttpByteRange>* ranges);
+
// Scans the '\r\n'-delimited headers for the given header name. Returns
// true if a match is found. Input is assumed to be well-formed.
// TODO(darin): kill this
diff --git a/net/http/http_vary_data.cc b/net/http/http_vary_data.cc
index fa7a325..f5c7514 100644
--- a/net/http/http_vary_data.cc
+++ b/net/http/http_vary_data.cc
@@ -8,6 +8,7 @@
#include "base/pickle.h"
#include "base/string_util.h"
+#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
@@ -97,33 +98,18 @@ std::string HttpVaryData::GetRequestValue(
const HttpRequestInfo& request_info,
const std::string& request_header) {
// Some special cases:
- if (LowerCaseEqualsASCII(request_header, "referer"))
+ if (!base::strcasecmp(request_header.c_str(), HttpRequestHeaders::kReferer))
return request_info.referrer.spec();
- if (LowerCaseEqualsASCII(request_header, "user-agent"))
- return request_info.user_agent;
-
- std::string result;
-
- // Check extra headers:
- HttpUtil::HeadersIterator it(request_info.extra_headers.begin(),
- request_info.extra_headers.end(),
- "\r\n");
- while (it.GetNext()) {
- size_t name_len = it.name_end() - it.name_begin();
- if (request_header.size() == name_len &&
- std::equal(it.name_begin(), it.name_end(), request_header.begin(),
- CaseInsensitiveCompare<char>())) {
- if (!result.empty())
- result.append(1, ',');
- result.append(it.values());
- }
- }
// Unfortunately, we do not have access to all of the request headers at this
// point. Most notably, we do not have access to an Authorization header if
// one will be added to the request.
- return result;
+ std::string result;
+ if (request_info.extra_headers.GetHeader(request_header, &result))
+ return result;
+
+ return "";
}
// static
diff --git a/net/http/http_vary_data.h b/net/http/http_vary_data.h
index 360799d..98b94fa 100644
--- a/net/http/http_vary_data.h
+++ b/net/http/http_vary_data.h
@@ -11,7 +11,7 @@ class Pickle;
namespace net {
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpResponseHeaders;
// Used to implement the HTTP/1.1 Vary header. This class contains a MD5 hash
diff --git a/net/http/http_vary_data_unittest.cc b/net/http/http_vary_data_unittest.cc
index 7b2bd16..38e4e32 100644
--- a/net/http/http_vary_data_unittest.cc
+++ b/net/http/http_vary_data_unittest.cc
@@ -23,7 +23,8 @@ struct TestTransaction {
std::replace(temp.begin(), temp.end(), '\n', '\0');
response = new net::HttpResponseHeaders(temp);
- request.extra_headers = request_headers;
+ request.extra_headers.Clear();
+ request.extra_headers.AddHeadersFromString(request_headers);
}
};
@@ -54,13 +55,13 @@ TEST(HttpVaryDataTest, MultipleInit) {
// Init to something valid.
TestTransaction t1;
- t1.Init("Foo: 1\nbar: 23", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
+ t1.Init("Foo: 1\r\nbar: 23", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
EXPECT_TRUE(v.Init(t1.request, *t1.response));
EXPECT_TRUE(v.is_valid());
// Now overwrite by initializing to something invalid.
TestTransaction t2;
- t2.Init("Foo: 1\nbar: 23", "HTTP/1.1 200 OK\nVary: *\n\n");
+ t2.Init("Foo: 1\r\nbar: 23", "HTTP/1.1 200 OK\nVary: *\n\n");
EXPECT_FALSE(v.Init(t2.request, *t2.response));
EXPECT_FALSE(v.is_valid());
}
@@ -80,10 +81,10 @@ TEST(HttpVaryDataTest, DoesVary) {
TEST(HttpVaryDataTest, DoesVary2) {
TestTransaction a;
- a.Init("Foo: 1\nbar: 23", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
+ a.Init("Foo: 1\r\nbar: 23", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
TestTransaction b;
- b.Init("Foo: 12\nbar: 3", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
+ b.Init("Foo: 12\r\nbar: 3", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
net::HttpVaryData v;
EXPECT_TRUE(v.Init(a.request, *a.response));
@@ -106,10 +107,10 @@ TEST(HttpVaryDataTest, DoesntVary) {
TEST(HttpVaryDataTest, DoesntVary2) {
TestTransaction a;
- a.Init("Foo: 1\nbAr: 2", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
+ a.Init("Foo: 1\r\nbAr: 2", "HTTP/1.1 200 OK\nVary: foo, bar\n\n");
TestTransaction b;
- b.Init("Foo: 1\nbaR: 2", "HTTP/1.1 200 OK\nVary: foo\nVary: bar\n\n");
+ b.Init("Foo: 1\r\nbaR: 2", "HTTP/1.1 200 OK\nVary: foo\nVary: bar\n\n");
net::HttpVaryData v;
EXPECT_TRUE(v.Init(a.request, *a.response));
diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc
index f727699..83bdb3b 100644
--- a/net/http/partial_data.cc
+++ b/net/http/partial_data.cc
@@ -12,6 +12,8 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
+namespace net {
+
namespace {
// The headers that we have to process.
@@ -19,13 +21,28 @@ const char kLengthHeader[] = "Content-Length";
const char kRangeHeader[] = "Content-Range";
const int kDataStream = 1;
+void AddRangeHeader(int64 start, int64 end, HttpRequestHeaders* headers) {
+ DCHECK(start >= 0 || end >= 0);
+ std::string my_start, my_end;
+ if (start >= 0)
+ my_start = Int64ToString(start);
+ if (end >= 0)
+ my_end = Int64ToString(end);
+
+ headers->SetHeader(
+ HttpRequestHeaders::kRange,
+ StringPrintf("bytes=%s-%s", my_start.c_str(), my_end.c_str()));
}
-namespace net {
+} // namespace
+
+bool PartialData::Init(const HttpRequestHeaders& headers) {
+ std::string range_header;
+ if (!headers.GetHeader(HttpRequestHeaders::kRange, &range_header))
+ return false;
-bool PartialData::Init(const std::string& headers) {
std::vector<HttpByteRange> ranges;
- if (!HttpUtil::ParseRanges(headers, &ranges) || ranges.size() != 1)
+ if (!HttpUtil::ParseRangeHeader(range_header, &ranges) || ranges.size() != 1)
return false;
// We can handle this range request.
@@ -38,23 +55,23 @@ bool PartialData::Init(const std::string& headers) {
return true;
}
-void PartialData::SetHeaders(const std::string& headers) {
- DCHECK(extra_headers_.empty());
- extra_headers_ = headers;
+void PartialData::SetHeaders(const HttpRequestHeaders& headers) {
+ DCHECK(extra_headers_.IsEmpty());
+ extra_headers_.CopyFrom(headers);
}
-void PartialData::RestoreHeaders(std::string* headers) const {
+void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const {
DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange());
int64 end = byte_range_.IsSuffixByteRange() ?
byte_range_.suffix_length() : byte_range_.last_byte_position();
- headers->assign(extra_headers_);
+ headers->CopyFrom(extra_headers_);
if (byte_range_.IsValid())
AddRangeHeader(current_range_start_, end, headers);
}
int PartialData::PrepareCacheValidation(disk_cache::Entry* entry,
- std::string* headers) {
+ HttpRequestHeaders* headers) {
DCHECK(current_range_start_ >= 0);
// Scan the disk cache for the first cached portion within this range.
@@ -86,7 +103,7 @@ int PartialData::PrepareCacheValidation(disk_cache::Entry* entry,
return cached_min_len_;
}
- headers->assign(extra_headers_);
+ headers->CopyFrom(extra_headers_);
if (!cached_min_len_) {
// We don't have anything else stored.
@@ -322,17 +339,4 @@ void PartialData::OnNetworkReadCompleted(int result) {
current_range_start_ += result;
}
-// Static.
-void PartialData::AddRangeHeader(int64 start, int64 end, std::string* headers) {
- DCHECK(start >= 0 || end >= 0);
- std::string my_start, my_end;
- if (start >= 0)
- my_start = Int64ToString(start);
- if (end >= 0)
- my_end = Int64ToString(end);
-
- headers->append(StringPrintf("Range: bytes=%s-%s\r\n", my_start.c_str(),
- my_end.c_str()));
-}
-
} // namespace net
diff --git a/net/http/partial_data.h b/net/http/partial_data.h
index 3a30e0a..51e6d7d 100644
--- a/net/http/partial_data.h
+++ b/net/http/partial_data.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "net/base/completion_callback.h"
#include "net/http/http_byte_range.h"
+#include "net/http/http_request_headers.h"
namespace disk_cache {
class Entry;
@@ -36,19 +37,19 @@ class PartialData {
truncated_(false) {}
~PartialData() {}
- // Performs initialization of the object by parsing the request |headers|
+ // Performs initialization of the object by examining the request |headers|
// and verifying that we can process the requested range. Returns true if
// we can process the requested range, and false otherwise.
- bool Init(const std::string& headers);
+ bool Init(const HttpRequestHeaders& headers);
// Sets the headers that we should use to make byte range requests. This is a
// subset of the request extra headers, with byte-range related headers
// removed.
- void SetHeaders(const std::string& headers);
+ void SetHeaders(const HttpRequestHeaders& headers);
// Restores the byte-range headers, by appending the byte range to the headers
// provided to SetHeaders().
- void RestoreHeaders(std::string* headers) const;
+ void RestoreHeaders(HttpRequestHeaders* headers) const;
// Builds the required |headers| to perform the proper cache validation for
// the next range to be fetched. Returns 0 when there is no need to perform
@@ -56,7 +57,8 @@ class PartialData {
// should be actually returned to the user), a positive number to indicate
// that |headers| should be used to validate the cache, or an appropriate
// error code.
- int PrepareCacheValidation(disk_cache::Entry* entry, std::string* headers);
+ int PrepareCacheValidation(disk_cache::Entry* entry,
+ HttpRequestHeaders* headers);
// Returns true if the current range is stored in the cache.
bool IsCurrentRangeCached() const;
@@ -105,14 +107,13 @@ class PartialData {
void OnNetworkReadCompleted(int result);
private:
- static void AddRangeHeader(int64 start, int64 end, std::string* headers);
-
int64 current_range_start_;
int64 cached_start_;
int64 resource_size_;
int cached_min_len_;
HttpByteRange byte_range_; // The range requested by the user.
- std::string extra_headers_; // The clean set of extra headers (no ranges).
+ // The clean set of extra headers (no ranges).
+ HttpRequestHeaders extra_headers_;
bool range_present_; // True if next range entry is already stored.
bool final_range_;
bool sparse_entry_;
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index cc08a9e..12625b2 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -1193,9 +1193,8 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
{
&syn_reply_info,
true,
- { 2, 4 },
- { { "cookie", "val1",
- "cookie", "val2",
+ { 1, 4 },
+ { { "cookie", "val1,val2",
NULL
},
{ "vary", "cookie",
@@ -1254,8 +1253,6 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
- char modified_syn_header[64];
-
// Construct the request.
scoped_ptr<spdy::SpdyFrame> frame_req(
ConstructSpdyGet(test_cases[i].extra_headers[0],
@@ -1292,17 +1289,12 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
request.load_flags = 0;
// Attach the headers to the request.
- int hdrCount = test_cases[i].num_headers[0];
- int len = 0;
-
- for (int ct = 0; ct < hdrCount; ct++) {
- len = ConstructSpdyHeader(test_cases[i].extra_headers[0],
- test_cases[i].num_headers[0],
- modified_syn_header,
- 64,
- ct);
+ int header_count = test_cases[i].num_headers[0];
- request.extra_headers.append(modified_syn_header);
+ for (int ct = 0; ct < header_count; ct++) {
+ const char* header_key = test_cases[i].extra_headers[0][ct * 2];
+ const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1];
+ request.extra_headers.SetHeader(header_key, header_value);
}
scoped_refptr<DelayedSocketData> data(
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 54e80c9..90b040c 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -133,19 +133,21 @@ bool SpdyHeadersToHttpResponse(const spdy::SpdyHeaderBlock& headers,
// a HttpRequestInfo block.
void CreateSpdyHeadersFromHttpRequest(
const HttpRequestInfo& info, spdy::SpdyHeaderBlock* headers) {
+ // TODO(willchan): It's not really necessary to convert from
+ // HttpRequestHeaders to spdy::SpdyHeaderBlock.
+
static const char kHttpProtocolVersion[] = "HTTP/1.1";
- HttpUtil::HeadersIterator it(info.extra_headers.begin(),
- info.extra_headers.end(),
- "\r\n");
+ HttpRequestHeaders::Iterator it(info.extra_headers);
+
while (it.GetNext()) {
std::string name = StringToLowerASCII(it.name());
if (headers->find(name) == headers->end()) {
- (*headers)[name] = it.values();
+ (*headers)[name] = it.value();
} else {
std::string new_value = (*headers)[name];
new_value.append(1, '\0'); // +=() doesn't append 0's
- new_value += it.values();
+ new_value += it.value();
(*headers)[name] = new_value;
}
}
@@ -156,8 +158,6 @@ void CreateSpdyHeadersFromHttpRequest(
(*headers)["method"] = info.method;
(*headers)["url"] = info.url.spec();
(*headers)["version"] = kHttpProtocolVersion;
- if (info.user_agent.length())
- (*headers)["user-agent"] = info.user_agent;
if (!info.referrer.is_empty())
(*headers)["referer"] = info.referrer.spec();
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index d7f60c0..0564354 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -30,7 +30,7 @@ namespace net {
class SpdyStream;
class HttpNetworkSession;
-class HttpRequestInfo;
+struct HttpRequestInfo;
class HttpResponseInfo;
class BoundNetLog;
class SSLInfo;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index feeba7b..52eda7d 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -22,6 +22,7 @@
#include "net/base/net_util.h"
#include "net/base/sdch_manager.h"
#include "net/base/ssl_cert_request_info.h"
+#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_transaction.h"
@@ -32,6 +33,8 @@
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_redirect_job.h"
+static const char kAvailDictionaryHeader[] = "Avail-Dictionary";
+
// TODO(darin): make sure the port blocking code is not lost
// static
URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request,
@@ -130,7 +133,7 @@ void URLRequestHttpJob::SetUpload(net::UploadData* upload) {
void URLRequestHttpJob::SetExtraRequestHeaders(
const std::string& headers) {
DCHECK(!transaction_.get()) << "cannot change once started";
- request_info_.extra_headers = headers;
+ request_info_.extra_headers.AddHeadersFromString(headers);
}
void URLRequestHttpJob::Start() {
@@ -146,8 +149,9 @@ void URLRequestHttpJob::Start() {
request_info_.priority = request_->priority();
if (request_->context()) {
- request_info_.user_agent =
- request_->context()->GetUserAgent(request_->url());
+ request_info_.extra_headers.SetHeader(
+ net::HttpRequestHeaders::kUserAgent,
+ request_->context()->GetUserAgent(request_->url()));
}
AddExtraHeaders();
@@ -334,9 +338,8 @@ void URLRequestHttpJob::RestartTransactionWithAuth(
// Update the cookies, since the cookie store may have been updated from the
// headers in the 401/407. Since cookies were already appended to
// extra_headers, we need to strip them out before adding them again.
- static const char* const cookie_name[] = { "cookie" };
- request_info_.extra_headers = net::HttpUtil::StripHeaders(
- request_info_.extra_headers, cookie_name, arraysize(cookie_name));
+ request_info_.extra_headers.RemoveHeader(
+ net::HttpRequestHeaders::kCookie);
AddCookieHeaderAndStart();
}
@@ -446,8 +449,10 @@ void URLRequestHttpJob::OnCanGetCookiesCompleted(int policy) {
request_->context()->cookie_store()->GetCookiesWithOptions(
request_->url(), options);
if (request_->context()->InterceptRequestCookies(request_, cookies) &&
- !cookies.empty())
- request_info_.extra_headers += "Cookie: " + cookies + "\r\n";
+ !cookies.empty()) {
+ request_info_.extra_headers.SetHeader(
+ net::HttpRequestHeaders::kCookie, cookies);
+ }
}
// We may have been canceled within OnGetCookiesBlocked.
if (GetStatus().is_success()) {
@@ -665,14 +670,16 @@ void URLRequestHttpJob::AddExtraHeaders() {
// these headers. Some proxies deliberately corrupt Accept-Encoding headers.
if (!advertise_sdch) {
// Tell the server what compression formats we support (other than SDCH).
- request_info_.extra_headers += "Accept-Encoding: gzip,deflate\r\n";
+ request_info_.extra_headers.SetHeader(
+ net::HttpRequestHeaders::kAcceptEncoding, "gzip,deflate");
} else {
// Include SDCH in acceptable list.
- request_info_.extra_headers += "Accept-Encoding: "
- "gzip,deflate,sdch\r\n";
+ request_info_.extra_headers.SetHeader(
+ net::HttpRequestHeaders::kAcceptEncoding, "gzip,deflate,sdch");
if (!avail_dictionaries.empty()) {
- request_info_.extra_headers += "Avail-Dictionary: "
- + avail_dictionaries + "\r\n";
+ request_info_.extra_headers.SetHeader(
+ kAvailDictionaryHeader,
+ avail_dictionaries);
sdch_dictionary_advertised_ = true;
// Since we're tagging this transaction as advertising a dictionary, we'll
// definately employ an SDCH filter (or tentative sdch filter) when we get
@@ -686,12 +693,18 @@ void URLRequestHttpJob::AddExtraHeaders() {
if (context) {
// Only add default Accept-Language and Accept-Charset if the request
// didn't have them specified.
- net::HttpUtil::AppendHeaderIfMissing("Accept-Language",
- context->accept_language(),
- &request_info_.extra_headers);
- net::HttpUtil::AppendHeaderIfMissing("Accept-Charset",
- context->accept_charset(),
- &request_info_.extra_headers);
+ if (!request_info_.extra_headers.HasHeader(
+ net::HttpRequestHeaders::kAcceptLanguage)) {
+ request_info_.extra_headers.SetHeader(
+ net::HttpRequestHeaders::kAcceptLanguage,
+ context->accept_language());
+ }
+ if (!request_info_.extra_headers.HasHeader(
+ net::HttpRequestHeaders::kAcceptCharset)) {
+ request_info_.extra_headers.SetHeader(
+ net::HttpRequestHeaders::kAcceptCharset,
+ context->accept_charset());
+ }
}
}