summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_cache_unittest.cc26
-rw-r--r--net/http/http_network_transaction_unittest.cc3
-rw-r--r--net/http/http_response_info.cc17
-rw-r--r--net/http/http_response_info.h10
-rw-r--r--net/http/http_stream_parser.cc11
5 files changed, 66 insertions, 1 deletions
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index bf8cb6b..8d5fea4 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -11,6 +11,7 @@
#include "base/stringprintf.h"
#include "net/base/cache_type.h"
#include "net/base/cert_status_flags.h"
+#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_log_unittest.h"
@@ -3978,6 +3979,31 @@ TEST(HttpCache, WriteResponseInfo_Truncated) {
entry->Close();
}
+// Tests basic pickling/unpickling of HttpResponseInfo.
+TEST(HttpCache, PersistHttpResponseInfo) {
+ // Set some fields (add more if needed.)
+ net::HttpResponseInfo response1;
+ response1.was_cached = false;
+ response1.socket_address = net::HostPortPair("1.2.3.4", 80);
+ response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
+
+ // Pickle.
+ Pickle pickle;
+ response1.Persist(&pickle, false, false);
+
+ // Unpickle.
+ net::HttpResponseInfo response2;
+ bool response_truncated;
+ EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
+ EXPECT_FALSE(response_truncated);
+
+ // Verify fields.
+ EXPECT_TRUE(response2.was_cached); // InitFromPickle sets this flag.
+ EXPECT_EQ("1.2.3.4", response2.socket_address.host());
+ EXPECT_EQ(80, response2.socket_address.port());
+ EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
+}
+
// Tests that we delete an entry when the request is cancelled before starting
// to read from the network.
TEST(HttpCache, DoomOnDestruction) {
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 8c87136..e54edf5 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -175,6 +175,9 @@ class HttpNetworkTransactionTest : public PlatformTest {
EXPECT_TRUE(response->headers != NULL);
out.status_line = response->headers->GetStatusLine();
+ EXPECT_EQ("192.0.2.33", response->socket_address.host());
+ EXPECT_EQ(0, response->socket_address.port());
+
rv = ReadTransaction(trans.get(), &out.response_data);
EXPECT_EQ(OK, rv);
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc
index 2c23faa..9b3444a 100644
--- a/net/http/http_response_info.cc
+++ b/net/http/http_response_info.cc
@@ -74,6 +74,7 @@ HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs)
was_npn_negotiated(rhs.was_npn_negotiated),
was_alternate_protocol_available(rhs.was_alternate_protocol_available),
was_fetched_via_proxy(rhs.was_fetched_via_proxy),
+ socket_address(rhs.socket_address),
request_time(rhs.request_time),
response_time(rhs.response_time),
auth_challenge(rhs.auth_challenge),
@@ -93,6 +94,7 @@ HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) {
was_npn_negotiated = rhs.was_npn_negotiated;
was_alternate_protocol_available = rhs.was_alternate_protocol_available;
was_fetched_via_proxy = rhs.was_fetched_via_proxy;
+ socket_address = rhs.socket_address;
request_time = rhs.request_time;
response_time = rhs.response_time;
auth_challenge = rhs.auth_challenge;
@@ -158,6 +160,18 @@ bool HttpResponseInfo::InitFromPickle(const Pickle& pickle,
return false;
}
+ // Read socket_address. This was not always present in the response info,
+ // so we don't fail if it can't be read. If additional fields are added in
+ // a future version, then they must only be read if this operation succeeds.
+ std::string socket_address_host;
+ if (pickle.ReadString(&iter, &socket_address_host)) {
+ // If the host was written, we always expect the port to follow.
+ uint16 socket_address_port;
+ if (!pickle.ReadUInt16(&iter, &socket_address_port))
+ return false;
+ socket_address = HostPortPair(socket_address_host, socket_address_port);
+ }
+
was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0;
was_npn_negotiated = (flags & RESPONSE_INFO_WAS_NPN) != 0;
@@ -223,6 +237,9 @@ void HttpResponseInfo::Persist(Pickle* pickle,
if (vary_data.is_valid())
vary_data.Persist(pickle);
+
+ pickle->WriteString(socket_address.host());
+ pickle->WriteUInt16(socket_address.port());
}
} // namespace net
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h
index 4fbea3d..e13f288 100644
--- a/net/http/http_response_info.h
+++ b/net/http/http_response_info.h
@@ -7,6 +7,7 @@
#pragma once
#include "base/time.h"
+#include "net/base/host_port_pair.h"
#include "net/base/ssl_info.h"
#include "net/http/http_vary_data.h"
@@ -60,6 +61,15 @@ class HttpResponseInfo {
// transparent proxy may have been involved.
bool was_fetched_via_proxy;
+ // Remote address of the socket which fetched this resource.
+ //
+ // NOTE: If the response was served from the cache (was_cached is true),
+ // the socket address will be set to the address that the content came from
+ // originally. This is true even if the response was re-validated using a
+ // different remote address, or if some of the content came from a byte-range
+ // request to a different address.
+ HostPortPair socket_address;
+
// The time at which the request was made that resulted in this response.
// For cached responses, this is the last time the cache entry was validated.
base::Time request_time;
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index 20ebd87..6621f0b 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 "net/base/address_list.h"
#include "net/base/auth.h"
#include "net/base/io_buffer.h"
#include "net/base/ssl_cert_request_info.h"
@@ -65,6 +66,14 @@ int HttpStreamParser::SendRequest(const std::string& request_line,
request_line, headers)));
}
response_ = response;
+
+ // Put the peer's IP address and port into the response.
+ AddressList address;
+ int result = connection_->socket()->GetPeerAddress(&address);
+ if (result != OK)
+ return result;
+ response_->socket_address = HostPortPair::FromAddrInfo(address.head());
+
std::string request = request_line + headers.ToString();
scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request));
request_headers_ = new DrainableIOBuffer(headers_io_buf,
@@ -74,7 +83,7 @@ int HttpStreamParser::SendRequest(const std::string& request_line,
request_body_->set_chunk_callback(this);
io_state_ = STATE_SENDING_HEADERS;
- int result = DoLoop(OK);
+ result = DoLoop(OK);
if (result == ERR_IO_PENDING)
user_callback_ = callback;