| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/spdy/spdy_http_stream.h" | 5 #include "net/spdy/spdy_http_stream.h" |
| 6 | 6 |
| 7 #include "crypto/ec_private_key.h" | 7 #include "crypto/ec_private_key.h" |
| 8 #include "crypto/ec_signature_creator.h" | 8 #include "crypto/ec_signature_creator.h" |
| 9 #include "crypto/signature_creator.h" | 9 #include "crypto/signature_creator.h" |
| 10 #include "net/base/asn1_util.h" | 10 #include "net/base/asn1_util.h" |
| 11 #include "net/base/default_origin_bound_cert_store.h" | 11 #include "net/base/default_origin_bound_cert_store.h" |
| 12 #include "net/http/http_response_headers.h" | 12 #include "net/http/http_response_headers.h" |
| 13 #include "net/http/http_response_info.h" | 13 #include "net/http/http_response_info.h" |
| 14 #include "net/spdy/spdy_session.h" | 14 #include "net/spdy/spdy_session.h" |
| 15 #include "net/spdy/spdy_test_util.h" | 15 #include "net/spdy/spdy_test_util_spdy2.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using namespace net::test_spdy2; |
| 19 |
| 18 namespace net { | 20 namespace net { |
| 19 | 21 |
| 20 class SpdyHttpStreamTest : public testing::Test { | 22 class SpdyHttpStreamSpdy2Test : public testing::Test { |
| 21 public: | 23 public: |
| 22 OrderedSocketData* data() { return data_.get(); } | 24 OrderedSocketData* data() { return data_.get(); } |
| 23 protected: | 25 protected: |
| 24 SpdyHttpStreamTest() {} | 26 SpdyHttpStreamSpdy2Test() {} |
| 25 | 27 |
| 26 void EnableCompression(bool enabled) { | 28 void EnableCompression(bool enabled) { |
| 27 spdy::SpdyFramer::set_enable_compression_default(enabled); | 29 spdy::SpdyFramer::set_enable_compression_default(enabled); |
| 28 } | 30 } |
| 29 | 31 |
| 30 virtual void TearDown() { | 32 virtual void TearDown() { |
| 31 crypto::ECSignatureCreator::SetFactoryForTesting(NULL); | 33 crypto::ECSignatureCreator::SetFactoryForTesting(NULL); |
| 32 MessageLoop::current()->RunAllPending(); | 34 MessageLoop::current()->RunAllPending(); |
| 33 } | 35 } |
| 34 int InitSession(MockRead* reads, size_t reads_count, | 36 int InitSession(MockRead* reads, size_t reads_count, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 61 const std::string& proof, | 63 const std::string& proof, |
| 62 SSLClientCertType type); | 64 SSLClientCertType type); |
| 63 | 65 |
| 64 SpdySessionDependencies session_deps_; | 66 SpdySessionDependencies session_deps_; |
| 65 scoped_ptr<OrderedSocketData> data_; | 67 scoped_ptr<OrderedSocketData> data_; |
| 66 scoped_refptr<HttpNetworkSession> http_session_; | 68 scoped_refptr<HttpNetworkSession> http_session_; |
| 67 scoped_refptr<SpdySession> session_; | 69 scoped_refptr<SpdySession> session_; |
| 68 scoped_refptr<TransportSocketParams> transport_params_; | 70 scoped_refptr<TransportSocketParams> transport_params_; |
| 69 }; | 71 }; |
| 70 | 72 |
| 71 TEST_F(SpdyHttpStreamTest, SendRequest) { | 73 TEST_F(SpdyHttpStreamSpdy2Test, SendRequest) { |
| 72 EnableCompression(false); | 74 EnableCompression(false); |
| 73 SpdySession::SetSSLMode(false); | 75 SpdySession::SetSSLMode(false); |
| 74 | 76 |
| 75 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); | 77 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); |
| 76 MockWrite writes[] = { | 78 MockWrite writes[] = { |
| 77 CreateMockWrite(*req.get(), 1), | 79 CreateMockWrite(*req.get(), 1), |
| 78 }; | 80 }; |
| 79 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); | 81 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| 80 MockRead reads[] = { | 82 MockRead reads[] = { |
| 81 CreateMockRead(*resp, 2), | 83 CreateMockRead(*resp, 2), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 110 // This triggers read 3. The empty read causes the session to shut down. | 112 // This triggers read 3. The empty read causes the session to shut down. |
| 111 data()->CompleteRead(); | 113 data()->CompleteRead(); |
| 112 | 114 |
| 113 // Because we abandoned the stream, we don't expect to find a session in the | 115 // Because we abandoned the stream, we don't expect to find a session in the |
| 114 // pool anymore. | 116 // pool anymore. |
| 115 EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair)); | 117 EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair)); |
| 116 EXPECT_TRUE(data()->at_read_eof()); | 118 EXPECT_TRUE(data()->at_read_eof()); |
| 117 EXPECT_TRUE(data()->at_write_eof()); | 119 EXPECT_TRUE(data()->at_write_eof()); |
| 118 } | 120 } |
| 119 | 121 |
| 120 TEST_F(SpdyHttpStreamTest, SendChunkedPost) { | 122 TEST_F(SpdyHttpStreamSpdy2Test, SendChunkedPost) { |
| 121 EnableCompression(false); | 123 EnableCompression(false); |
| 122 SpdySession::SetSSLMode(false); | 124 SpdySession::SetSSLMode(false); |
| 123 UploadDataStream::set_merge_chunks(false); | 125 UploadDataStream::set_merge_chunks(false); |
| 124 | 126 |
| 125 scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0)); | 127 scoped_ptr<spdy::SpdyFrame> req(ConstructChunkedSpdyPost(NULL, 0)); |
| 126 scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false)); | 128 scoped_ptr<spdy::SpdyFrame> chunk1(ConstructSpdyBodyFrame(1, false)); |
| 127 scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true)); | 129 scoped_ptr<spdy::SpdyFrame> chunk2(ConstructSpdyBodyFrame(1, true)); |
| 128 MockWrite writes[] = { | 130 MockWrite writes[] = { |
| 129 CreateMockWrite(*req.get(), 1), | 131 CreateMockWrite(*req.get(), 1), |
| 130 CreateMockWrite(*chunk1, 2), // POST upload frames | 132 CreateMockWrite(*chunk1, 2), // POST upload frames |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 MessageLoop::current()->RunAllPending(); | 176 MessageLoop::current()->RunAllPending(); |
| 175 | 177 |
| 176 // Because we abandoned the stream, we don't expect to find a session in the | 178 // Because we abandoned the stream, we don't expect to find a session in the |
| 177 // pool anymore. | 179 // pool anymore. |
| 178 EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair)); | 180 EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair)); |
| 179 EXPECT_TRUE(data()->at_read_eof()); | 181 EXPECT_TRUE(data()->at_read_eof()); |
| 180 EXPECT_TRUE(data()->at_write_eof()); | 182 EXPECT_TRUE(data()->at_write_eof()); |
| 181 } | 183 } |
| 182 | 184 |
| 183 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058 | 185 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058 |
| 184 TEST_F(SpdyHttpStreamTest, SpdyURLTest) { | 186 TEST_F(SpdyHttpStreamSpdy2Test, SpdyURLTest) { |
| 185 EnableCompression(false); | 187 EnableCompression(false); |
| 186 SpdySession::SetSSLMode(false); | 188 SpdySession::SetSSLMode(false); |
| 187 | 189 |
| 188 const char * const full_url = "http://www.google.com/foo?query=what#anchor"; | 190 const char * const full_url = "http://www.google.com/foo?query=what#anchor"; |
| 189 const char * const base_url = "http://www.google.com/foo?query=what"; | 191 const char * const base_url = "http://www.google.com/foo?query=what"; |
| 190 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(base_url, false, 1, LOWEST)); | 192 scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(base_url, false, 1, LOWEST)); |
| 191 MockWrite writes[] = { | 193 MockWrite writes[] = { |
| 192 CreateMockWrite(*req.get(), 1), | 194 CreateMockWrite(*req.get(), 1), |
| 193 }; | 195 }; |
| 194 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); | 196 scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 // This triggers read 3. The empty read causes the session to shut down. | 233 // This triggers read 3. The empty read causes the session to shut down. |
| 232 data()->CompleteRead(); | 234 data()->CompleteRead(); |
| 233 | 235 |
| 234 // Because we abandoned the stream, we don't expect to find a session in the | 236 // Because we abandoned the stream, we don't expect to find a session in the |
| 235 // pool anymore. | 237 // pool anymore. |
| 236 EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair)); | 238 EXPECT_FALSE(http_session_->spdy_session_pool()->HasSession(pair)); |
| 237 EXPECT_TRUE(data()->at_read_eof()); | 239 EXPECT_TRUE(data()->at_read_eof()); |
| 238 EXPECT_TRUE(data()->at_write_eof()); | 240 EXPECT_TRUE(data()->at_write_eof()); |
| 239 } | 241 } |
| 240 | 242 |
| 243 namespace { |
| 244 |
| 241 void GetECOriginBoundCertAndProof(const std::string& origin, | 245 void GetECOriginBoundCertAndProof(const std::string& origin, |
| 242 OriginBoundCertService* obc_service, | 246 OriginBoundCertService* obc_service, |
| 243 std::string* cert, | 247 std::string* cert, |
| 244 std::string* proof) { | 248 std::string* proof) { |
| 245 TestCompletionCallback callback; | 249 TestCompletionCallback callback; |
| 246 std::vector<uint8> requested_cert_types; | 250 std::vector<uint8> requested_cert_types; |
| 247 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); | 251 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 248 SSLClientCertType cert_type; | 252 SSLClientCertType cert_type; |
| 249 std::string key; | 253 std::string key; |
| 250 OriginBoundCertService::RequestHandle request_handle; | 254 OriginBoundCertService::RequestHandle request_handle; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 270 std::vector<uint8> proof_data; | 274 std::vector<uint8> proof_data; |
| 271 scoped_ptr<crypto::ECPrivateKey> private_key( | 275 scoped_ptr<crypto::ECPrivateKey> private_key( |
| 272 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( | 276 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
| 273 OriginBoundCertService::kEPKIPassword, key_data, spki)); | 277 OriginBoundCertService::kEPKIPassword, key_data, spki)); |
| 274 scoped_ptr<crypto::ECSignatureCreator> creator( | 278 scoped_ptr<crypto::ECSignatureCreator> creator( |
| 275 crypto::ECSignatureCreator::Create(private_key.get())); | 279 crypto::ECSignatureCreator::Create(private_key.get())); |
| 276 creator->Sign(secret, arraysize(secret), &proof_data); | 280 creator->Sign(secret, arraysize(secret), &proof_data); |
| 277 proof->assign(proof_data.begin(), proof_data.end()); | 281 proof->assign(proof_data.begin(), proof_data.end()); |
| 278 } | 282 } |
| 279 | 283 |
| 284 } // namespace |
| 285 |
| 280 // TODO(rch): When openssl supports origin bound certifictes, this | 286 // TODO(rch): When openssl supports origin bound certifictes, this |
| 281 // guard can be removed | 287 // guard can be removed |
| 282 #if !defined(USE_OPENSSL) | 288 #if !defined(USE_OPENSSL) |
| 283 // Test that if we request a resource for a new origin on a session that | 289 // Test that if we request a resource for a new origin on a session that |
| 284 // used origin bound certificates, that we send a CREDENTIAL frame for | 290 // used origin bound certificates, that we send a CREDENTIAL frame for |
| 285 // the new origin before we send the new request. | 291 // the new origin before we send the new request. |
| 286 void SpdyHttpStreamTest::TestSendCredentials( | 292 void SpdyHttpStreamSpdy2Test::TestSendCredentials( |
| 287 OriginBoundCertService* obc_service, | 293 OriginBoundCertService* obc_service, |
| 288 const std::string& cert, | 294 const std::string& cert, |
| 289 const std::string& proof, | 295 const std::string& proof, |
| 290 SSLClientCertType type) { | 296 SSLClientCertType type) { |
| 291 EnableCompression(false); | 297 EnableCompression(false); |
| 292 | 298 |
| 293 spdy::SpdyCredential cred; | 299 spdy::SpdyCredential cred; |
| 294 cred.slot = 1; | 300 cred.slot = 1; |
| 295 cred.proof = proof; | 301 cred.proof = proof; |
| 296 cred.certs.push_back(cert); | 302 cred.certs.push_back(cert); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 virtual ~MockECSignatureCreatorFactory() {} | 440 virtual ~MockECSignatureCreatorFactory() {} |
| 435 | 441 |
| 436 virtual crypto::ECSignatureCreator* Create( | 442 virtual crypto::ECSignatureCreator* Create( |
| 437 crypto::ECPrivateKey* key) OVERRIDE { | 443 crypto::ECPrivateKey* key) OVERRIDE { |
| 438 return new MockECSignatureCreator(key); | 444 return new MockECSignatureCreator(key); |
| 439 } | 445 } |
| 440 private: | 446 private: |
| 441 DISALLOW_COPY_AND_ASSIGN(MockECSignatureCreatorFactory); | 447 DISALLOW_COPY_AND_ASSIGN(MockECSignatureCreatorFactory); |
| 442 }; | 448 }; |
| 443 | 449 |
| 444 TEST_F(SpdyHttpStreamTest, SendCredentialsEC) { | 450 TEST_F(SpdyHttpStreamSpdy2Test, SendCredentialsEC) { |
| 445 scoped_ptr<crypto::ECSignatureCreatorFactory> ec_signature_creator_factory( | 451 scoped_ptr<crypto::ECSignatureCreatorFactory> ec_signature_creator_factory( |
| 446 new MockECSignatureCreatorFactory()); | 452 new MockECSignatureCreatorFactory()); |
| 447 crypto::ECSignatureCreator::SetFactoryForTesting( | 453 crypto::ECSignatureCreator::SetFactoryForTesting( |
| 448 ec_signature_creator_factory.get()); | 454 ec_signature_creator_factory.get()); |
| 449 | 455 |
| 450 scoped_ptr<OriginBoundCertService> obc_service( | 456 scoped_ptr<OriginBoundCertService> obc_service( |
| 451 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 457 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); |
| 452 std::string cert; | 458 std::string cert; |
| 453 std::string proof; | 459 std::string proof; |
| 454 GetECOriginBoundCertAndProof("http://www.gmail.com/", obc_service.get(), | 460 GetECOriginBoundCertAndProof("http://www.gmail.com/", obc_service.get(), |
| 455 &cert, &proof); | 461 &cert, &proof); |
| 456 | 462 |
| 457 TestSendCredentials(obc_service.get(), cert, proof, CLIENT_CERT_ECDSA_SIGN); | 463 TestSendCredentials(obc_service.get(), cert, proof, CLIENT_CERT_ECDSA_SIGN); |
| 458 } | 464 } |
| 459 | 465 |
| 460 #endif // !defined(USE_OPENSSL) | 466 #endif // !defined(USE_OPENSSL) |
| 461 | 467 |
| 462 // TODO(willchan): Write a longer test for SpdyStream that exercises all | 468 // TODO(willchan): Write a longer test for SpdyStream that exercises all |
| 463 // methods. | 469 // methods. |
| 464 | 470 |
| 465 } // namespace net | 471 } // namespace net |
| OLD | NEW |