summaryrefslogtreecommitdiffstats
path: root/net/spdy
diff options
context:
space:
mode:
Diffstat (limited to 'net/spdy')
-rw-r--r--net/spdy/spdy_http_stream.cc28
-rw-r--r--net/spdy/spdy_http_stream.h17
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc47
-rw-r--r--net/spdy/spdy_session.cc11
-rw-r--r--net/spdy/spdy_session.h13
-rw-r--r--net/spdy/spdy_stream.cc4
-rw-r--r--net/spdy/spdy_stream.h6
7 files changed, 90 insertions, 36 deletions
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
index 52c99f4..41b18aa 100644
--- a/net/spdy/spdy_http_stream.cc
+++ b/net/spdy/spdy_http_stream.cc
@@ -14,6 +14,7 @@
#include "base/string_util.h"
#include "net/base/load_flags.h"
#include "net/base/net_util.h"
+#include "net/base/ssl_cert_request_info.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
@@ -257,6 +258,12 @@ int SpdyHttpStream::ReadResponseBody(
return ERR_IO_PENDING;
}
+void SpdyHttpStream::Close(bool not_reusable) {
+ // Note: the not_reusable flag has no meaning for SPDY streams.
+
+ Cancel();
+}
+
int SpdyHttpStream::SendRequest(const std::string& /*headers_string*/,
UploadDataStream* request_body,
HttpResponseInfo* response,
@@ -358,6 +365,11 @@ int SpdyHttpStream::OnResponseReceived(const spdy::SpdyHeaderBlock& response,
response_info_ = push_response_info_.get();
}
+ // TODO(mbelshe): This is the time of all headers received, not just time
+ // to first byte.
+ DCHECK(response_info_->response_time.is_null());
+ response_info_->response_time = base::Time::Now();
+
if (!SpdyHeadersToHttpResponse(response, response_info_)) {
status = ERR_INVALID_RESPONSE;
} else {
@@ -409,10 +421,6 @@ void SpdyHttpStream::OnClose(int status) {
DoCallback(status);
}
-bool SpdyHttpStream::ShouldResendFailedRequest(int error) const {
- return spdy_session_->ShouldResendFailedRequest(error);
-}
-
void SpdyHttpStream::ScheduleBufferedReadCallback() {
// If there is already a scheduled DoBufferedReadCallback, don't issue
// another one. Mark that we have received more data and return.
@@ -485,4 +493,16 @@ void SpdyHttpStream::DoCallback(int rv) {
c->Run(rv);
}
+void SpdyHttpStream::GetSSLInfo(SSLInfo* ssl_info) {
+ DCHECK(stream_);
+ bool using_npn;
+ stream_->GetSSLInfo(ssl_info, &using_npn);
+}
+
+void SpdyHttpStream::GetSSLCertRequestInfo(
+ SSLCertRequestInfo* cert_request_info) {
+ DCHECK(stream_);
+ stream_->GetSSLCertRequestInfo(cert_request_info);
+}
+
} // namespace net
diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h
index b333742..2fe15c8 100644
--- a/net/spdy/spdy_http_stream.h
+++ b/net/spdy/spdy_http_stream.h
@@ -17,6 +17,7 @@
#include "net/http/http_request_info.h"
#include "net/http/http_stream.h"
#include "net/spdy/spdy_protocol.h"
+#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_stream.h"
namespace net {
@@ -66,6 +67,9 @@ class SpdyHttpStream : public SpdyStream::Delegate, public HttpStream {
virtual int ReadResponseBody(
IOBuffer* buf, int buf_len, CompletionCallback* callback);
+ // Closes the stream.
+ virtual void Close(bool not_reusable);
+
// Indicates if the response body has been completely read.
virtual bool IsResponseBodyComplete() const {
return stream_->closed();
@@ -77,6 +81,17 @@ class SpdyHttpStream : public SpdyStream::Delegate, public HttpStream {
// A SPDY stream never has more data after the FIN.
virtual bool IsMoreDataBuffered() const { return false; }
+ virtual bool IsConnectionReused() const {
+ return spdy_session_->IsReused();
+ }
+
+ virtual void SetConnectionReused() {
+ // SPDY doesn't need an indicator here.
+ }
+
+ virtual void GetSSLInfo(SSLInfo* ssl_info);
+ virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+
// ===================================================
// SpdyStream::Delegate.
@@ -113,8 +128,6 @@ class SpdyHttpStream : public SpdyStream::Delegate, public HttpStream {
// ReadResponseHeaders or ReadResponseBody.
virtual void OnClose(int status);
- bool ShouldResendFailedRequest(int error) const;
-
private:
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, FlowControlStallResume);
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index a4bd90d..112ade7 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -6,6 +6,7 @@
#include <vector>
#include "net/base/net_log_unittest.h"
+#include "net/http/http_stream_handle.h"
#include "net/http/http_transaction_unittest.h"
#include "net/spdy/spdy_http_stream.h"
#include "net/spdy/spdy_session.h"
@@ -93,24 +94,24 @@ class SpdyNetworkTransactionTest
if (!session_.get())
session_ = SpdySessionDependencies::SpdyCreateSession(
session_deps_.get());
- HttpNetworkTransaction::SetUseAlternateProtocols(false);
- HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
- HttpNetworkTransaction::SetUseSpdyWithoutNPN(false);
+ HttpStreamFactory::set_use_alternate_protocols(false);
+ HttpStreamFactory::set_force_spdy_over_ssl(false);
+ HttpStreamFactory::set_force_spdy_always(false);
switch (test_type_) {
case SPDYNPN:
session_->mutable_alternate_protocols()->SetAlternateProtocolFor(
HostPortPair("www.google.com", 80), 443,
HttpAlternateProtocols::NPN_SPDY_2);
- HttpNetworkTransaction::SetUseAlternateProtocols(true);
- HttpNetworkTransaction::SetNextProtos(kExpectedNPNString);
+ HttpStreamFactory::set_use_alternate_protocols(true);
+ HttpStreamFactory::set_next_protos(kExpectedNPNString);
break;
case SPDYNOSSL:
- HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
- HttpNetworkTransaction::SetUseSpdyWithoutNPN(true);
+ HttpStreamFactory::set_force_spdy_over_ssl(false);
+ HttpStreamFactory::set_force_spdy_always(true);
break;
case SPDYSSL:
- HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(true);
- HttpNetworkTransaction::SetUseSpdyWithoutNPN(true);
+ HttpStreamFactory::set_force_spdy_over_ssl(true);
+ HttpStreamFactory::set_force_spdy_always(true);
break;
default:
NOTREACHED();
@@ -1274,12 +1275,7 @@ TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
request.upload_data, NULL));
ASSERT_EQ(request.upload_data->GetContentLength(), stream->size());
- scoped_ptr<spdy::SpdyFrame>
- req(ConstructSpdyPost(request.upload_data->GetContentLength(), NULL, 0));
scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
- MockWrite writes[] = {
- CreateMockWrite(*req.get(), 2),
- };
scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyPostSynReply(NULL, 0));
MockRead reads[] = {
@@ -1289,8 +1285,7 @@ TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
};
scoped_refptr<DelayedSocketData> data(
- new DelayedSocketData(0, reads, arraysize(reads),
- writes, arraysize(writes)));
+ new DelayedSocketData(0, reads, arraysize(reads), NULL, 0));
NormalSpdyTransactionHelper helper(request,
BoundNetLog(), GetParam());
helper.RunPreTestSetup();
@@ -1424,7 +1419,8 @@ TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
// writes are ordered so that writing tests like these are easy, right now
// we are working around the limitations as described above and it's not
// deterministic, tests may fail under specific circumstances.
-TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
+// TODO(mbelshe): Disabling until we have deterministic sockets!
+TEST_P(SpdyNetworkTransactionTest, DISABLED_WindowUpdateReceived) {
SpdySession::SetFlowControl(true);
static int kFrameCount = 2;
@@ -1488,7 +1484,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
EXPECT_EQ(OK, rv);
SpdyHttpStream* stream =
- static_cast<SpdyHttpStream*>(trans->stream_.get());
+ static_cast<SpdyHttpStream*>(trans->stream_->stream());
ASSERT_TRUE(stream != NULL);
ASSERT_TRUE(stream->stream() != NULL);
EXPECT_EQ(spdy::kInitialWindowSize +
@@ -1538,6 +1534,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
CreateMockRead(*window_update),
CreateMockRead(*window_update),
CreateMockRead(*window_update),
+ MockRead(true, ERR_IO_PENDING, 0), // Wait for the RST to be written.
MockRead(true, 0, 0) // EOF
};
@@ -1567,6 +1564,8 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
rv = callback.WaitForResult();
EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
+ data->CompleteRead();
+
ASSERT_TRUE(helper.session() != NULL);
ASSERT_TRUE(helper.session()->spdy_session_pool() != NULL);
helper.session()->spdy_session_pool()->ClearSessions();
@@ -1671,7 +1670,7 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
MessageLoop::current()->RunAllPending(); // Write as much as we can.
SpdyHttpStream* stream =
- static_cast<SpdyHttpStream*>(trans->stream_.get());
+ static_cast<SpdyHttpStream*>(trans->stream_->stream());
ASSERT_TRUE(stream != NULL);
ASSERT_TRUE(stream->stream() != NULL);
EXPECT_EQ(0, stream->stream()->send_window_size());
@@ -1825,7 +1824,7 @@ TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
new OrderedSocketData(reads, arraysize(reads),
writes, arraysize(writes)));
scoped_refptr<DelayedSocketData> data2(
- new DelayedSocketData(0, reads2, arraysize(reads2),
+ new DelayedSocketData(1, reads2, arraysize(reads2),
writes2, arraysize(writes2)));
NormalSpdyTransactionHelper helper(CreateGetRequest(),
@@ -1989,8 +1988,8 @@ TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) {
writes2, arraysize(writes2)));
// TODO(erikchen): Make test support SPDYSSL, SPDYNPN
- HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
- HttpNetworkTransaction::SetUseSpdyWithoutNPN(true);
+ HttpStreamFactory::set_force_spdy_over_ssl(false);
+ HttpStreamFactory::set_force_spdy_always(true);
TestDelegate d;
{
URLRequest r(GURL("http://www.google.com/"), &d);
@@ -2109,8 +2108,8 @@ TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
writes2, arraysize(writes2)));
// TODO(erikchen): Make test support SPDYSSL, SPDYNPN
- HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
- HttpNetworkTransaction::SetUseSpdyWithoutNPN(true);
+ HttpStreamFactory::set_force_spdy_over_ssl(false);
+ HttpStreamFactory::set_force_spdy_always(true);
TestDelegate d;
TestDelegate d2;
{
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index b1e9c23..07de80f 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -916,6 +916,17 @@ bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated) {
return false;
}
+bool SpdySession::GetSSLCertRequestInfo(
+ SSLCertRequestInfo* cert_request_info) {
+ if (is_secure_) {
+ SSLClientSocket* ssl_socket =
+ reinterpret_cast<SSLClientSocket*>(connection_->socket());
+ ssl_socket->GetSSLCertRequestInfo(cert_request_info);
+ return true;
+ }
+ return false;
+}
+
void SpdySession::OnError(spdy::SpdyFramer* framer) {
LOG(ERROR) << "SpdySession error: " << framer->error_code();
CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR);
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 72e8c06..4230289 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -132,6 +132,10 @@ class SpdySession : public base::RefCounted<SpdySession>,
// Fills SSL info in |ssl_info| and returns true when SSL is in use.
bool GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated);
+ // Fills SSL Certificate Request info |cert_request_info| and returns
+ // true when SSL is in use.
+ bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+
// Enable or disable SSL.
static void SetSSLMode(bool enable) { use_ssl_ = enable; }
static bool SSLMode() { return use_ssl_; }
@@ -148,12 +152,9 @@ class SpdySession : public base::RefCounted<SpdySession>,
// error.
void CloseSessionOnError(net::Error err);
- // Indicates whether we should retry failed requets on a session.
- bool ShouldResendFailedRequest(int error) const {
- // NOTE: we resend a request only if this connection has successfully
- // been used for some data receiving. Otherwise, we assume the error
- // is not transient.
- // This is primarily for use with recovery from a TCP RESET.
+ // Indicates whether the session is being reused after having successfully
+ // used to send/receive data in the past.
+ bool IsReused() const {
return frames_received_ > 0;
}
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index 09129fc..71c0901 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -277,6 +277,10 @@ bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated) {
return session_->GetSSLInfo(ssl_info, was_npn_negotiated);
}
+bool SpdyStream::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {
+ return session_->GetSSLCertRequestInfo(cert_request_info);
+}
+
int SpdyStream::DoLoop(int result) {
do {
State state = io_state_;
diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h
index 1b0a3f6..7cabdc1 100644
--- a/net/spdy/spdy_stream.h
+++ b/net/spdy/spdy_stream.h
@@ -22,6 +22,7 @@
namespace net {
class SpdySession;
+class SSLCertRequestInfo;
class SSLInfo;
// The SpdyStream is used by the SpdySession to represent each stream known
@@ -168,8 +169,13 @@ class SpdyStream : public base::RefCounted<SpdyStream> {
int WriteStreamData(IOBuffer* data, int length,
spdy::SpdyDataFlags flags);
+ // Fills SSL info in |ssl_info| and returns true when SSL is in use.
bool GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated);
+ // Fills SSL Certificate Request info |cert_request_info| and returns
+ // true when SSL is in use.
+ bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+
bool is_idle() const {
return io_state_ == STATE_OPEN || io_state_ == STATE_DONE;
}