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

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: Rebased Created 5 years, 1 month 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 : error_code_(OK),
38 bytes_read_(0),
39 close_status_(ERR_FAILED),
40 read_buf_(read_buf),
41 read_buf_len_(read_buf_len) {}
42
43 ~TestBidirectionalStreamDelegate() override {}
44
45 void OnFailed(Error error) override {
46 error_code_ = error;
47 loop_.Quit();
48 }
49
50 void OnRequestHeadersSent() override {}
51
52 void OnHeaders(const SpdyHeaderBlock& response_headers) override {
53 response_headers_ = response_headers;
54 StartOrContinueReading();
55 }
56
57 void OnReadCompleted(int bytes_read) override {
58 CHECK_GT(bytes_read, OK);
59 bytes_read_ += bytes_read;
60 data_received_.append(read_buf_->data(), bytes_read_);
61 StartOrContinueReading();
62 }
63
64 void OnDataSent() override {}
65
66 void OnTrailers(const SpdyHeaderBlock& trailers) override {
67 trailers_ = trailers;
68 }
69
70 void OnClose(int status) override {
71 close_status_ = status;
72 loop_.Quit();
73 }
74
75 void CreateBidirectionalStream(const HttpRequestInfo& request_info,
76 RequestPriority priority,
77 HttpNetworkSession* session) {
78 stream_.reset(
79 new BidirectionalStream(request_info, priority, session, this));
80 loop_.Run();
81 }
82
83 void SendData(IOBuffer* data, int length, bool end_of_stream) {
84 stream_->SendData(data, length, end_of_stream);
85 }
86
87 const std::string& data_received() const { return data_received_; }
88
89 int error_code_;
90 SpdyHeaderBlock response_headers_;
91 SpdyHeaderBlock trailers_;
92 int bytes_read_;
93 int close_status_;
94
95 private:
96 void StartOrContinueReading() {
97 int rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
98 while (rv > 0) {
99 bytes_read_ += rv;
100 data_received_.append(read_buf_->data(), rv);
101 rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
102 }
103 }
104
105 scoped_refptr<IOBuffer> read_buf_;
106 int read_buf_len_;
107 std::string data_received_;
108 base::RunLoop loop_;
109 scoped_ptr<BidirectionalStream> stream_;
110 };
111
112 // A delegate that sends data after request headers are sent.
113 class SendDataDelegate : public TestBidirectionalStreamDelegate {
114 public:
115 SendDataDelegate(IOBuffer* buf, int buf_len, base::StringPiece data)
116 : TestBidirectionalStreamDelegate(buf, buf_len), data_(data) {}
117
118 ~SendDataDelegate() override {}
119
120 void OnRequestHeadersSent() override {
121 TestBidirectionalStreamDelegate::OnRequestHeadersSent();
122 if (data_.data()) {
123 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(data_.as_string()));
124 SendData(buf.get(), buf->size(), NO_MORE_DATA_TO_SEND);
125 }
126 }
127
128 private:
129 base::StringPiece data_;
130 };
131
132 class BidirectionalStreamTest : public testing::Test {
133 public:
134 BidirectionalStreamTest()
135 : spdy_util_(kProtoHTTP2), session_deps_(kProtoHTTP2) {}
136
137 protected:
138 // Initializes the session using SequencedSocketData.
139 void InitSession(MockRead* reads,
140 size_t reads_count,
141 MockWrite* writes,
142 size_t writes_count,
143 const SpdySessionKey& key) {
144 sequenced_data_.reset(
145 new SequencedSocketData(reads, reads_count, writes, writes_count));
146 session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get());
147 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
148 session_ = CreateSecureSpdySession(http_session_.get(), key, BoundNetLog());
149 }
150
151 SpdyTestUtil spdy_util_;
152 SpdySessionDependencies session_deps_;
153 scoped_ptr<SequencedSocketData> sequenced_data_;
154 scoped_ptr<HttpNetworkSession> http_session_;
155 base::WeakPtr<SpdySession> session_;
156 };
157
158 } // namespace
159
160 TEST_F(BidirectionalStreamTest, CreateInsecureStream) {
161 HttpRequestInfo request;
162 request.method = "GET";
163 request.url = GURL("http://www.example.org/");
164
165 TestBidirectionalStreamDelegate delegate(nullptr, 0);
166 HttpNetworkSession::Params params =
167 SpdySessionDependencies::CreateSessionParams(&session_deps_);
168 scoped_ptr<HttpNetworkSession> session(new HttpNetworkSession(params));
169 delegate.CreateBidirectionalStream(request, LOWEST, session.get());
170 EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, delegate.error_code_);
171 }
172
173 TEST_F(BidirectionalStreamTest, SendPostRequest) {
174 spdy_util_.set_default_url(GURL("https://www.example.org"));
175 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
176
177 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
178 scoped_ptr<SpdyFrame> body(
179 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_FIN));
180 MockWrite writes[] = {
181 CreateMockWrite(*req, 0), // request
182 CreateMockWrite(*body, 1), // POST upload frame
183 };
184 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
185 scoped_ptr<SpdyFrame> resp(
186 spdy_util_.ConstructSpdyPostSynReply(kExtraResponseHeaders, 1));
187
188 scoped_ptr<SpdyFrame> resp_data(
189 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
190
191 const char* const kExtraHeaders[] = {"foo", "bar"};
192 scoped_ptr<SpdyFrame> trailers(
193 spdy_util_.ConstructSpdyHeaderFrame(1, kExtraHeaders, 1, true));
194
195 MockRead reads[] = {
196 CreateMockRead(*resp, 2), CreateMockRead(*resp_data, 3),
197 CreateMockRead(*trailers, 4), MockRead(SYNCHRONOUS, 0, 5) // EOF
198 };
199
200 HostPortPair host_port_pair("www.example.org", 443);
201 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
202 PRIVACY_MODE_DISABLED);
203
204 SSLSocketDataProvider ssl_data(ASYNC, OK);
205 ssl_data.SetNextProto(kProtoHTTP2);
206 ssl_data.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
207 ASSERT_TRUE(ssl_data.cert.get());
208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
209
210 InitSession(reads, arraysize(reads), writes, arraysize(writes), key);
211
212 HttpRequestInfo request;
213 request.method = "POST";
214 request.url = GURL("https://www.example.org/");
215
216 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
217 scoped_ptr<TestBidirectionalStreamDelegate> delegate(new SendDataDelegate(
218 read_buffer.get(), kReadBufferSize, kBodyDataStringPiece));
219 delegate->CreateBidirectionalStream(request, DEFAULT_PRIORITY,
220 http_session_.get());
221
222 base::StringPiece header = delegate->response_headers_[":status"];
223 EXPECT_EQ("200", header);
224 base::StringPiece extra_header = delegate->response_headers_["header-name"];
225 EXPECT_EQ("header-value", extra_header);
226 EXPECT_EQ((int)kBodyDataSize, delegate->bytes_read_);
227 EXPECT_EQ(std::string(kBodyData, kBodyDataSize), delegate->data_received());
228 base::StringPiece trailer = delegate->trailers_["foo"];
229 EXPECT_EQ("bar", trailer);
230 EXPECT_EQ(OK, delegate->close_status_);
231 }
232
233 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698