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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info)); | 68 EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info)); |
69 | 69 |
70 EXPECT_FALSE(load_timing_info.socket_reused); | 70 EXPECT_FALSE(load_timing_info.socket_reused); |
71 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | 71 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
72 | 72 |
73 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, | 73 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, |
74 CONNECT_TIMING_HAS_DNS_TIMES); | 74 CONNECT_TIMING_HAS_DNS_TIMES); |
75 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); | 75 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); |
76 } | 76 } |
77 | 77 |
78 class ReadErrorUploadDataStream : public UploadDataStream { | |
79 public: | |
80 enum class FailureMode { SYNC, ASYNC }; | |
81 | |
82 explicit ReadErrorUploadDataStream(FailureMode mode) | |
83 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {} | |
84 | |
85 private: | |
86 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); } | |
87 | |
88 // UploadDataStream implementation: | |
89 int InitInternal() override { return OK; } | |
90 | |
91 int ReadInternal(IOBuffer* buf, int buf_len) override { | |
92 if (async_ == FailureMode::ASYNC) { | |
93 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
94 FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead, | |
95 weak_factory_.GetWeakPtr()), | |
96 base::TimeDelta::FromSeconds(1)); | |
97 return ERR_IO_PENDING; | |
98 } | |
99 return ERR_FAILED; | |
100 } | |
101 | |
102 void ResetInternal() override {} | |
103 | |
104 const FailureMode async_; | |
105 | |
106 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_; | |
107 | |
108 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream); | |
109 }; | |
110 | |
78 } // namespace | 111 } // namespace |
79 | 112 |
80 class SpdyHttpStreamTest : public testing::Test, | 113 class SpdyHttpStreamTest : public testing::Test, |
81 public testing::WithParamInterface<TestCase> { | 114 public testing::WithParamInterface<TestCase> { |
82 public: | 115 public: |
83 SpdyHttpStreamTest() | 116 SpdyHttpStreamTest() |
84 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()), | 117 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()), |
85 session_deps_(GetProtocol()) { | 118 session_deps_(GetProtocol()) { |
86 session_deps_.enable_priority_dependencies = GetDependenciesFromPriority(); | 119 session_deps_.enable_priority_dependencies = GetDependenciesFromPriority(); |
87 session_deps_.net_log = &net_log_; | 120 session_deps_.net_log = &net_log_; |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 HttpRequestHeaders headers; | 464 HttpRequestHeaders headers; |
432 BoundNetLog net_log; | 465 BoundNetLog net_log; |
433 SpdyHttpStream http_stream(session_, true); | 466 SpdyHttpStream http_stream(session_, true); |
434 ASSERT_EQ(OK, http_stream.InitializeStream(&request, DEFAULT_PRIORITY, | 467 ASSERT_EQ(OK, http_stream.InitializeStream(&request, DEFAULT_PRIORITY, |
435 net_log, CompletionCallback())); | 468 net_log, CompletionCallback())); |
436 | 469 |
437 EXPECT_EQ(ERR_IO_PENDING, | 470 EXPECT_EQ(ERR_IO_PENDING, |
438 http_stream.SendRequest(headers, &response, callback.callback())); | 471 http_stream.SendRequest(headers, &response, callback.callback())); |
439 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 472 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
440 | 473 |
441 EXPECT_EQ(OK, callback.WaitForResult()); | 474 // Server closes the connection. Thus, callback now returns |
475 // "CONNECTION_CLOSED" error. | |
476 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult()); | |
442 | 477 |
443 EXPECT_EQ(static_cast<int64_t>(req->size() + body->size()), | 478 EXPECT_EQ(static_cast<int64_t>(req->size() + body->size()), |
444 http_stream.GetTotalSentBytes()); | 479 http_stream.GetTotalSentBytes()); |
445 EXPECT_EQ(0, http_stream.GetTotalReceivedBytes()); | 480 EXPECT_EQ(0, http_stream.GetTotalReceivedBytes()); |
446 | 481 |
447 // Because the server closed the connection, we there shouldn't be a session | 482 // Because the server closed the connection, we there shouldn't be a session |
448 // in the pool anymore. | 483 // in the pool anymore. |
449 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 484 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
450 | 485 |
451 // Appending a second chunk now should not result in a crash. | 486 // Appending a second chunk now should not result in a crash. |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
881 scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize)); | 916 scoped_refptr<IOBuffer> buf1(new IOBuffer(kUploadDataSize)); |
882 ASSERT_EQ(kUploadDataSize, | 917 ASSERT_EQ(kUploadDataSize, |
883 http_stream->ReadResponseBody( | 918 http_stream->ReadResponseBody( |
884 buf1.get(), kUploadDataSize, callback.callback())); | 919 buf1.get(), kUploadDataSize, callback.callback())); |
885 EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize)); | 920 EXPECT_EQ(kUploadData, std::string(buf1->data(), kUploadDataSize)); |
886 | 921 |
887 ASSERT_TRUE(response.headers.get()); | 922 ASSERT_TRUE(response.headers.get()); |
888 ASSERT_EQ(200, response.headers->response_code()); | 923 ASSERT_EQ(200, response.headers->response_code()); |
889 } | 924 } |
890 | 925 |
926 TEST_P(SpdyHttpStreamTest, DataReadErrorSynchronous) { | |
927 BufferedSpdyFramer framer(spdy_util_.spdy_version()); | |
928 | |
929 std::unique_ptr<SpdySerializedFrame> req( | |
930 spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | |
mmenke
2016/06/01 17:24:07
Note that my comments apply to both test.
nit: n
| |
931 std::unique_ptr<SpdySerializedFrame> rst_frame( | |
932 framer.CreateRstStream(1, RST_STREAM_INTERNAL_ERROR)); | |
mmenke
2016/06/01 17:24:07
This should probably use spdy_util_.ConstructSpdyF
maksims (do not use this acc)
2016/06/03 11:39:08
spdy_util_.ConstructSpdyRstStream
does the great j
| |
933 MockWrite writes[] = { | |
934 CreateMockWrite(*req, 0, SYNCHRONOUS), // request | |
935 CreateMockWrite(*rst_frame, 1, SYNCHRONOUS) // POST upload frame | |
936 }; | |
937 | |
938 std::unique_ptr<SpdySerializedFrame> resp( | |
939 spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | |
940 MockRead reads[] = { | |
941 CreateMockRead(*resp, 2), CreateMockRead(*rst_frame, 3), | |
mmenke
2016/06/01 17:24:07
Are these frames needed?
maksims (do not use this acc)
2016/06/02 12:43:12
Otherwise I got !AllReadDataConsumed failures.
mmenke
2016/06/02 15:02:10
Even if you just have the "MockRead(SYNCHRONOUS, 0
maksims (do not use this acc)
2016/06/03 11:39:08
Oh, I got it. the resp frame is needed, but the rs
| |
942 MockRead(SYNCHRONOUS, 0, 4), | |
943 }; | |
944 | |
945 HostPortPair host_port_pair("www.example.org", 80); | |
946 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | |
947 PRIVACY_MODE_DISABLED); | |
948 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); | |
949 EXPECT_EQ(spdy_util_.spdy_version(), session_->GetProtocolVersion()); | |
950 ReadErrorUploadDataStream upload_data_stream( | |
951 ReadErrorUploadDataStream::FailureMode::SYNC); | |
952 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback())); | |
953 | |
954 HttpRequestInfo request; | |
955 request.method = "POST"; | |
956 request.url = GURL("http://www.example.org/"); | |
957 request.upload_data_stream = &upload_data_stream; | |
958 | |
959 TestCompletionCallback callback; | |
960 HttpResponseInfo response; | |
961 HttpRequestHeaders headers; | |
962 BoundNetLog net_log; | |
963 SpdyHttpStream http_stream(session_, true); | |
964 ASSERT_EQ(OK, http_stream.InitializeStream(&request, DEFAULT_PRIORITY, | |
965 net_log, CompletionCallback())); | |
966 | |
967 int result = http_stream.SendRequest(headers, &response, callback.callback()); | |
968 EXPECT_EQ(ERR_FAILED, callback.GetResult(result)); | |
969 | |
970 // Because the server has not closed the connection yet, there shouldn't be | |
971 // a stream but a session in the pool | |
972 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); | |
973 } | |
974 | |
975 TEST_P(SpdyHttpStreamTest, DataReadErrorAsynchronous) { | |
976 BufferedSpdyFramer framer(spdy_util_.spdy_version()); | |
977 | |
978 std::unique_ptr<SpdySerializedFrame> req( | |
979 spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | |
980 | |
981 // Server receives RST_STREAM_INTERNAL_ERROR on clients an internal failure. | |
982 // The failure is reading error in this case cause by | |
983 // UploadDataStream::Read() | |
984 std::unique_ptr<SpdySerializedFrame> rst_frame( | |
985 framer.CreateRstStream(1, RST_STREAM_INTERNAL_ERROR)); | |
986 MockWrite writes[] = { | |
987 CreateMockWrite(*req, 0), // Request | |
988 CreateMockWrite(*rst_frame, 1) // Reset frame | |
989 }; | |
990 | |
991 std::unique_ptr<SpdySerializedFrame> resp( | |
992 spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | |
993 MockRead reads[] = { | |
994 CreateMockRead(*resp, 2), | |
995 CreateMockRead(*rst_frame, 3), | |
996 MockRead(ASYNC, 0, 4), | |
997 }; | |
998 | |
999 HostPortPair host_port_pair("www.example.org", 80); | |
1000 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | |
1001 PRIVACY_MODE_DISABLED); | |
1002 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); | |
1003 EXPECT_EQ(spdy_util_.spdy_version(), session_->GetProtocolVersion()); | |
1004 | |
1005 ReadErrorUploadDataStream upload_data_stream( | |
1006 ReadErrorUploadDataStream::FailureMode::ASYNC); | |
1007 ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback())); | |
1008 | |
1009 HttpRequestInfo request; | |
1010 request.method = "POST"; | |
1011 request.url = GURL("http://www.example.org/"); | |
1012 request.upload_data_stream = &upload_data_stream; | |
1013 | |
1014 TestCompletionCallback callback; | |
1015 HttpResponseInfo response; | |
1016 HttpRequestHeaders headers; | |
1017 BoundNetLog net_log; | |
1018 SpdyHttpStream http_stream(session_, true); | |
1019 ASSERT_EQ(OK, http_stream.InitializeStream(&request, DEFAULT_PRIORITY, | |
1020 net_log, CompletionCallback())); | |
1021 | |
1022 int result = http_stream.SendRequest(headers, &response, callback.callback()); | |
1023 EXPECT_EQ(ERR_IO_PENDING, result); | |
1024 | |
1025 // Headers sent | |
1026 EXPECT_EQ(OK, callback.GetResult(result)); | |
1027 | |
1028 // Body read failed | |
1029 EXPECT_EQ(ERR_FAILED, callback.GetResult(result)); | |
1030 | |
1031 // Because the server has closed the connection, there shouldn't be a session | |
1032 // in the pool anymore. | |
1033 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); | |
1034 } | |
1035 | |
891 // TODO(willchan): Write a longer test for SpdyStream that exercises all | 1036 // TODO(willchan): Write a longer test for SpdyStream that exercises all |
892 // methods. | 1037 // methods. |
893 | 1038 |
894 } // namespace net | 1039 } // namespace net |
OLD | NEW |