Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: net/http/bidirectional_stream_unittest.cc

Issue 1326503003: Added a net::BidirectionalStream to expose a bidirectional streaming interface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove unneeded return value Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http/bidirectional_stream.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string_piece.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/test_data_directory.h"
12 #include "net/http/http_network_session.h"
13 #include "net/http/http_request_info.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/log/net_log.h"
16 #include "net/socket/socket_test_util.h"
17 #include "net/spdy/spdy_session.h"
18 #include "net/spdy/spdy_test_util_common.h"
19 #include "net/spdy/spdy_test_util_common.h"
20 #include "net/test/cert_test_util.h"
21 #include "net/url_request/url_request_test_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace net {
25
26 namespace {
27
28 const char kBodyData[] = "Body data";
29 const size_t kBodyDataSize = arraysize(kBodyData);
30 const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize);
31 // Size of the buffer to be allocated for each read.
32 const size_t kReadBufferSize = 4096;
33
34 class TestBidirectionalStreamDelegate : public BidirectionalStream::Delegate {
35 public:
36 TestBidirectionalStreamDelegate(IOBuffer* read_buf, int read_buf_len)
37 : bytes_read_(0),
38 close_status_(ERR_FAILED),
39 read_buf_(read_buf),
40 read_buf_len_(read_buf_len) {}
41
42 ~TestBidirectionalStreamDelegate() override {}
43
44 void OnRequestHeadersSent() override {}
45
46 void OnHeaders(const SpdyHeaderBlock& response_headers) override {
47 response_headers_ = response_headers;
48 StartOrContinueReading();
49 }
50
51 void OnReadCompleted(int bytes_read) override {
52 CHECK_GT(bytes_read, OK);
53 bytes_read_ += bytes_read;
54 data_received_.append(read_buf_->data(), bytes_read_);
55 StartOrContinueReading();
56 }
57
58 void OnDataSent() override {}
59
60 void OnTrailers(const SpdyHeaderBlock& trailers) override {
61 trailers_ = trailers;
62 }
63
64 void OnClose(int status) override {
65 close_status_ = status;
66 loop_.Quit();
67 }
68
69 void CreateBidirectionalStream(const HttpRequestInfo& request_info,
70 RequestPriority priority,
71 HttpNetworkSession* session) {
72 stream_.reset(
73 new BidirectionalStream(request_info, priority, session, this));
74 loop_.Run();
75 }
76
77 void SendData(IOBuffer* data, int length, bool end_of_stream) {
78 stream_->SendData(data, length, end_of_stream);
79 }
80
81 const std::string& data_received() const { return data_received_; }
82
83 SpdyHeaderBlock response_headers_;
84 SpdyHeaderBlock trailers_;
85 int bytes_read_;
86 int close_status_;
87
88 private:
89 void StartOrContinueReading() {
90 int rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
91 while (rv > 0) {
92 bytes_read_ += rv;
93 data_received_.append(read_buf_->data(), rv);
94 rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
95 }
96 }
97
98 scoped_refptr<IOBuffer> read_buf_;
99 int read_buf_len_;
100 std::string data_received_;
101 base::RunLoop loop_;
102 scoped_ptr<BidirectionalStream> stream_;
103 };
104
105 // A delegate that sends data after request headers are sent.
106 class SendDataDelegate : public TestBidirectionalStreamDelegate {
107 public:
108 SendDataDelegate(IOBuffer* buf, int buf_len, base::StringPiece data)
109 : TestBidirectionalStreamDelegate(buf, buf_len), data_(data) {}
110
111 ~SendDataDelegate() override {}
112
113 void OnRequestHeadersSent() override {
114 TestBidirectionalStreamDelegate::OnRequestHeadersSent();
115 if (data_.data()) {
116 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(data_.as_string()));
117 SendData(buf.get(), buf->size(), NO_MORE_DATA_TO_SEND);
118 }
119 }
120
121 private:
122 base::StringPiece data_;
123 };
124
125 class BidirectionalStreamTest : public testing::Test {
126 public:
127 BidirectionalStreamTest()
128 : spdy_util_(kProtoHTTP2, false), session_deps_(kProtoHTTP2) {}
129
130 protected:
131 // Initializes the session using SequencedSocketData.
132 void InitSession(MockRead* reads,
133 size_t reads_count,
134 MockWrite* writes,
135 size_t writes_count,
136 const SpdySessionKey& key) {
137 sequenced_data_.reset(
138 new SequencedSocketData(reads, reads_count, writes, writes_count));
139 session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get());
140 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
141 session_ = CreateSecureSpdySession(http_session_.get(), key, BoundNetLog());
142 }
143
144 SpdyTestUtil spdy_util_;
145 SpdySessionDependencies session_deps_;
146 scoped_ptr<SequencedSocketData> sequenced_data_;
147 scoped_ptr<HttpNetworkSession> http_session_;
148 base::WeakPtr<SpdySession> session_;
149 };
150
151 } // namespace
152
153 TEST_F(BidirectionalStreamTest, CreateInsecureStream) {
154 HttpRequestInfo request;
155 request.method = "GET";
156 request.url = GURL("http://www.example.org/");
157
158 TestBidirectionalStreamDelegate delegate(nullptr, 0);
159 HttpNetworkSession::Params params =
160 SpdySessionDependencies::CreateSessionParams(&session_deps_);
161 scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
162 delegate.CreateBidirectionalStream(request, LOWEST, session.get());
163 EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, delegate.close_status_);
164 }
165
166 TEST_F(BidirectionalStreamTest, SendPostRequest) {
167 spdy_util_.set_default_url(GURL("https://www.example.org"));
168 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
169
170 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
171 scoped_ptr<SpdyFrame> body(
172 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_FIN));
173 MockWrite writes[] = {
174 CreateMockWrite(*req, 0), // request
175 CreateMockWrite(*body, 1), // POST upload frame
176 };
177 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
178 scoped_ptr<SpdyFrame> resp(
179 spdy_util_.ConstructSpdyPostSynReply(kExtraResponseHeaders, 1));
180
181 scoped_ptr<SpdyFrame> resp_data(
182 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
183
184 const char* const kExtraHeaders[] = {"foo", "bar"};
185 scoped_ptr<SpdyFrame> trailers(
186 spdy_util_.ConstructSpdyHeaderFrame(1, kExtraHeaders, 1, true));
187
188 MockRead reads[] = {
189 CreateMockRead(*resp, 2), CreateMockRead(*resp_data, 3),
190 CreateMockRead(*trailers, 4), MockRead(SYNCHRONOUS, 0, 5) // EOF
191 };
192
193 HostPortPair host_port_pair("www.example.org", 443);
194 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
195 PRIVACY_MODE_DISABLED);
196
197 SSLSocketDataProvider ssl_data(ASYNC, OK);
198 ssl_data.SetNextProto(kProtoHTTP2);
199 ssl_data.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
200 ASSERT_TRUE(ssl_data.cert.get());
201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
202
203 InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
204
205 HttpRequestInfo request;
206 request.method = "POST";
207 request.url = GURL("https://www.example.org/");
208
209 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
210 scoped_ptr<TestBidirectionalStreamDelegate> delegate(new SendDataDelegate(
211 read_buffer.get(), kReadBufferSize, kBodyDataStringPiece));
212 delegate->CreateBidirectionalStream(request, DEFAULT_PRIORITY,
213 http_session_.get());
214
215 base::StringPiece header = delegate->response_headers_[":status"];
216 EXPECT_EQ("200", header);
217 base::StringPiece extra_header = delegate->response_headers_["header-name"];
218 EXPECT_EQ("header-value", extra_header);
219 EXPECT_EQ((int)kBodyDataSize, delegate->bytes_read_);
220 EXPECT_EQ(std::string(kBodyData, kBodyDataSize), delegate->data_received());
221 base::StringPiece trailer = delegate->trailers_["foo"];
222 EXPECT_EQ("bar", trailer);
223 EXPECT_EQ(OK, delegate->close_status_);
224 }
225
226 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698