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

Side by Side Diff: net/websockets/websocket_stream_test.cc

Issue 336263005: Map WebSocket URL schemes to HTTP URL schemes for auth purposes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Factor out WebSocketDispatchOnFinishOpeningHandshake() into a separate function. Created 6 years, 5 months 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/websockets/websocket_stream.h" 5 #include "net/websockets/websocket_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 48
49 std::vector<HeaderKeyValuePair> ToVector(const HttpResponseHeaders& headers) { 49 std::vector<HeaderKeyValuePair> ToVector(const HttpResponseHeaders& headers) {
50 void* iter = NULL; 50 void* iter = NULL;
51 std::string name, value; 51 std::string name, value;
52 std::vector<HeaderKeyValuePair> result; 52 std::vector<HeaderKeyValuePair> result;
53 while (headers.EnumerateHeaderLines(&iter, &name, &value)) 53 while (headers.EnumerateHeaderLines(&iter, &name, &value))
54 result.push_back(HeaderKeyValuePair(name, value)); 54 result.push_back(HeaderKeyValuePair(name, value));
55 return result; 55 return result;
56 } 56 }
57 57
58 // Simple builder for a DeterministicSocketData object to save repetitive code.
59 // It always sets the connect data to MockConnect(SYNCHRONOUS, OK), so it cannot
60 // be used in tests where the connect fails. In practice, those tests never have
61 // any read/write data and so can't benefit from it anyway. The arrays are not
62 // copied. It is up to the caller to ensure they stay in scope until the test
63 // ends.
64 template <size_t reads_count, size_t writes_count>
65 scoped_ptr<DeterministicSocketData> BuildSocketData(
66 MockRead (&reads)[reads_count],
67 MockWrite (&writes)[writes_count]) {
68 scoped_ptr<DeterministicSocketData> socket_data(
69 new DeterministicSocketData(reads, reads_count, writes, writes_count));
70 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
71 socket_data->SetStop(reads_count + writes_count);
72 return socket_data.Pass();
73 }
74
75 // Builder for a DeterministicSocketData that expects nothing. This does not
76 // set the connect data, so the calling code must do that explicitly.
77 scoped_ptr<DeterministicSocketData> BuildNullSocketData() {
78 return make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0));
79 }
80
58 // A sub-class of WebSocketHandshakeStreamCreateHelper which always sets a 81 // A sub-class of WebSocketHandshakeStreamCreateHelper which always sets a
59 // deterministic key to use in the WebSocket handshake. 82 // deterministic key to use in the WebSocket handshake.
60 class DeterministicKeyWebSocketHandshakeStreamCreateHelper 83 class DeterministicKeyWebSocketHandshakeStreamCreateHelper
61 : public WebSocketHandshakeStreamCreateHelper { 84 : public WebSocketHandshakeStreamCreateHelper {
62 public: 85 public:
63 DeterministicKeyWebSocketHandshakeStreamCreateHelper( 86 DeterministicKeyWebSocketHandshakeStreamCreateHelper(
64 WebSocketStream::ConnectDelegate* connect_delegate, 87 WebSocketStream::ConnectDelegate* connect_delegate,
65 const std::vector<std::string>& requested_subprotocols) 88 const std::vector<std::string>& requested_subprotocols)
66 : WebSocketHandshakeStreamCreateHelper(connect_delegate, 89 : WebSocketHandshakeStreamCreateHelper(connect_delegate,
67 requested_subprotocols) {} 90 requested_subprotocols) {}
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 origin, 134 origin,
112 extra_request_headers, 135 extra_request_headers,
113 WebSocketStandardResponse(extra_response_headers)); 136 WebSocketStandardResponse(extra_response_headers));
114 } 137 }
115 138
116 void CreateAndConnectRawExpectations( 139 void CreateAndConnectRawExpectations(
117 const std::string& socket_url, 140 const std::string& socket_url,
118 const std::vector<std::string>& sub_protocols, 141 const std::vector<std::string>& sub_protocols,
119 const std::string& origin, 142 const std::string& origin,
120 scoped_ptr<DeterministicSocketData> socket_data) { 143 scoped_ptr<DeterministicSocketData> socket_data) {
144 AddRawExpectations(socket_data.Pass());
145 CreateAndConnectStream(socket_url, sub_protocols, origin);
146 }
147
148 // Add additional raw expectations for sockets created before the final one.
149 void AddRawExpectations(scoped_ptr<DeterministicSocketData> socket_data) {
121 url_request_context_host_.AddRawExpectations(socket_data.Pass()); 150 url_request_context_host_.AddRawExpectations(socket_data.Pass());
122 CreateAndConnectStream(socket_url, sub_protocols, origin);
123 } 151 }
124 152
125 // A wrapper for CreateAndConnectStreamForTesting that knows about our default 153 // A wrapper for CreateAndConnectStreamForTesting that knows about our default
126 // parameters. 154 // parameters.
127 void CreateAndConnectStream(const std::string& socket_url, 155 void CreateAndConnectStream(const std::string& socket_url,
128 const std::vector<std::string>& sub_protocols, 156 const std::vector<std::string>& sub_protocols,
129 const std::string& origin) { 157 const std::string& origin) {
130 for (size_t i = 0; i < ssl_data_.size(); ++i) { 158 for (size_t i = 0; i < ssl_data_.size(); ++i) {
131 scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]); 159 scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]);
132 ssl_data_[i] = NULL; 160 ssl_data_[i] = NULL;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 stream.swap(owner_->stream_); 195 stream.swap(owner_->stream_);
168 } 196 }
169 197
170 virtual void OnFailure(const std::string& message) OVERRIDE { 198 virtual void OnFailure(const std::string& message) OVERRIDE {
171 owner_->has_failed_ = true; 199 owner_->has_failed_ = true;
172 owner_->failure_message_ = message; 200 owner_->failure_message_ = message;
173 } 201 }
174 202
175 virtual void OnStartOpeningHandshake( 203 virtual void OnStartOpeningHandshake(
176 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { 204 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE {
177 if (owner_->request_info_) 205 // Can be called multiple times (in the case of HTTP auth). Last call
178 ADD_FAILURE(); 206 // wins.
179 owner_->request_info_ = request.Pass(); 207 owner_->request_info_ = request.Pass();
180 } 208 }
181 virtual void OnFinishOpeningHandshake( 209 virtual void OnFinishOpeningHandshake(
182 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { 210 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE {
183 if (owner_->response_info_) 211 if (owner_->response_info_)
184 ADD_FAILURE(); 212 ADD_FAILURE();
185 owner_->response_info_ = response.Pass(); 213 owner_->response_info_ = response.Pass();
186 } 214 }
187 virtual void OnSSLCertificateError( 215 virtual void OnSSLCertificateError(
188 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> 216 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks>
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 "ws://localhost/testing_path", 254 "ws://localhost/testing_path",
227 "/testing_path", 255 "/testing_path",
228 NoSubProtocols(), 256 NoSubProtocols(),
229 "http://localhost", 257 "http://localhost",
230 "", 258 "",
231 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); 259 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n");
232 RunUntilIdle(); 260 RunUntilIdle();
233 } 261 }
234 }; 262 };
235 263
264 // Common code to construct expectations for authentication tests that receive
265 // the auth challenge on one connection and then create a second connection to
266 // send the authenticated request on.
267 class CommonAuthTestHelper {
268 public:
269 scoped_ptr<DeterministicSocketData> BuildSocketData1(
270 const std::string& response) {
271 request1 = WebSocketStandardRequest("/", "http://localhost", "");
272 writes1[0] = MockWrite(SYNCHRONOUS, 0, request1.c_str());
273 response1 = response;
274 reads1[0] = MockRead(SYNCHRONOUS, 1, response1.c_str());
275 reads1[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection
276
277 return BuildSocketData(reads1, writes1);
278 }
279
280 scoped_ptr<DeterministicSocketData> BuildSocketData2(
281 const std::string& request,
282 const std::string& response) {
283 request2 = request;
284 response2 = response;
285 writes2[0] = MockWrite(SYNCHRONOUS, 0, request2.c_str());
286 reads2[0] = MockRead(SYNCHRONOUS, 1, response2.c_str());
287 return BuildSocketData(reads2, writes2);
288 }
289
290 private:
291 // These need to be object-scoped since they have to remain valid until all
292 // socket operations in the test are complete.
293 std::string request1;
Johnny 2014/07/08 20:27:40 Trailing underscores?
Adam Rice 2014/07/09 06:35:01 Okay, that's weird. In my brain this was a struct,
294 std::string request2;
295 std::string response1;
296 std::string response2;
297 MockRead reads1[2];
298 MockWrite writes1[1];
299 MockRead reads2[1];
300 MockWrite writes2[1];
301 };
302
303 // Data and methods for BasicAuth tests.
304 class WebSocketStreamCreateBasicAuthTest : public WebSocketStreamCreateTest {
305 protected:
306 void CreateAndConnectAuthHandshake(const std::string& url,
307 const std::string& base64_user_pass,
308 const std::string& response2) {
309 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
310
311 static const char request2format[] =
312 "GET / HTTP/1.1\r\n"
313 "Host: localhost\r\n"
314 "Connection: Upgrade\r\n"
315 "Pragma: no-cache\r\n"
316 "Cache-Control: no-cache\r\n"
317 "Authorization: Basic %s\r\n"
318 "Upgrade: websocket\r\n"
319 "Origin: http://localhost\r\n"
320 "Sec-WebSocket-Version: 13\r\n"
321 "User-Agent:\r\n"
322 "Accept-Encoding: gzip,deflate\r\n"
323 "Accept-Language: en-us,fr\r\n"
324 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
325 "Sec-WebSocket-Extensions: permessage-deflate; "
326 "client_max_window_bits\r\n"
327 "\r\n";
328 const std::string request =
329 base::StringPrintf(request2format, base64_user_pass.c_str());
330 CreateAndConnectRawExpectations(
331 url,
332 NoSubProtocols(),
333 "http://localhost",
334 helper_.BuildSocketData2(request, response2));
335 }
336
337 static const char kUnauthorizedResponse[];
338
339 CommonAuthTestHelper helper_;
340 };
341
342 class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest {
343 protected:
344 static const char kUnauthorizedResponse[];
345 static const char kAuthorizedRequest[];
346
347 CommonAuthTestHelper helper_;
348 };
349
350 const char WebSocketStreamCreateBasicAuthTest::kUnauthorizedResponse[] =
351 "HTTP/1.1 401 Unauthorized\r\n"
352 "Content-Length: 0\r\n"
353 "WWW-Authenticate: Basic realm=\"camelot\"\r\n"
354 "\r\n";
355
356 // These negotiation values are borrowed from
357 // http_auth_handler_digest_unittest.cc. Feel free to come up with new ones if
358 // you are bored. Only the weakest (no qop) variants of Digest authentication
359 // can be tested by this method, because the others involve random input.
360 const char WebSocketStreamCreateDigestAuthTest::kUnauthorizedResponse[] =
361 "HTTP/1.1 401 Unauthorized\r\n"
362 "Content-Length: 0\r\n"
363 "WWW-Authenticate: Digest realm=\"Oblivion\", nonce=\"nonce-value\"\r\n"
364 "\r\n";
365
366 const char WebSocketStreamCreateDigestAuthTest::kAuthorizedRequest[] =
367 "GET / HTTP/1.1\r\n"
368 "Host: localhost\r\n"
369 "Connection: Upgrade\r\n"
370 "Pragma: no-cache\r\n"
371 "Cache-Control: no-cache\r\n"
372 "Authorization: Digest username=\"FooBar\", realm=\"Oblivion\", "
373 "nonce=\"nonce-value\", uri=\"/\", "
374 "response=\"f72ff54ebde2f928860f806ec04acd1b\"\r\n"
375 "Upgrade: websocket\r\n"
376 "Origin: http://localhost\r\n"
377 "Sec-WebSocket-Version: 13\r\n"
378 "User-Agent:\r\n"
379 "Accept-Encoding: gzip,deflate\r\n"
380 "Accept-Language: en-us,fr\r\n"
381 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
382 "Sec-WebSocket-Extensions: permessage-deflate; "
383 "client_max_window_bits\r\n"
384 "\r\n";
385
236 class WebSocketStreamCreateUMATest : public ::testing::Test { 386 class WebSocketStreamCreateUMATest : public ::testing::Test {
237 public: 387 public:
238 // This enum should match with the enum in Delegate in websocket_stream.cc. 388 // This enum should match with the enum in Delegate in websocket_stream.cc.
239 enum HandshakeResult { 389 enum HandshakeResult {
240 INCOMPLETE, 390 INCOMPLETE,
241 CONNECTED, 391 CONNECTED,
242 FAILED, 392 FAILED,
243 NUM_HANDSHAKE_RESULT_TYPES, 393 NUM_HANDSHAKE_RESULT_TYPES,
244 }; 394 };
245 395
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 stream_request_.reset(); 1068 stream_request_.reset();
919 RunUntilIdle(); 1069 RunUntilIdle();
920 EXPECT_FALSE(has_failed()); 1070 EXPECT_FALSE(has_failed());
921 EXPECT_FALSE(stream_); 1071 EXPECT_FALSE(stream_);
922 EXPECT_FALSE(request_info_); 1072 EXPECT_FALSE(request_info_);
923 EXPECT_FALSE(response_info_); 1073 EXPECT_FALSE(response_info_);
924 } 1074 }
925 1075
926 // Connect failure must look just like negotiation failure. 1076 // Connect failure must look just like negotiation failure.
927 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { 1077 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) {
928 scoped_ptr<DeterministicSocketData> socket_data( 1078 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
929 new DeterministicSocketData(NULL, 0, NULL, 0));
930 socket_data->set_connect_data( 1079 socket_data->set_connect_data(
931 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); 1080 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
932 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 1081 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
933 "http://localhost", socket_data.Pass()); 1082 "http://localhost", socket_data.Pass());
934 RunUntilIdle(); 1083 RunUntilIdle();
935 EXPECT_TRUE(has_failed()); 1084 EXPECT_TRUE(has_failed());
936 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", 1085 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED",
937 failure_message()); 1086 failure_message());
938 EXPECT_FALSE(request_info_); 1087 EXPECT_FALSE(request_info_);
939 EXPECT_FALSE(response_info_); 1088 EXPECT_FALSE(response_info_);
940 } 1089 }
941 1090
942 // Connect timeout must look just like any other failure. 1091 // Connect timeout must look just like any other failure.
943 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { 1092 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) {
944 scoped_ptr<DeterministicSocketData> socket_data( 1093 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
945 new DeterministicSocketData(NULL, 0, NULL, 0));
946 socket_data->set_connect_data( 1094 socket_data->set_connect_data(
947 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); 1095 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT));
948 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 1096 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
949 "http://localhost", socket_data.Pass()); 1097 "http://localhost", socket_data.Pass());
950 RunUntilIdle(); 1098 RunUntilIdle();
951 EXPECT_TRUE(has_failed()); 1099 EXPECT_TRUE(has_failed());
952 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", 1100 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT",
953 failure_message()); 1101 failure_message());
954 } 1102 }
955 1103
956 // Cancellation during connect works. 1104 // Cancellation during connect works.
957 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { 1105 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) {
958 scoped_ptr<DeterministicSocketData> socket_data( 1106 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
959 new DeterministicSocketData(NULL, 0, NULL, 0));
960 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); 1107 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
961 CreateAndConnectRawExpectations("ws://localhost/", 1108 CreateAndConnectRawExpectations("ws://localhost/",
962 NoSubProtocols(), 1109 NoSubProtocols(),
963 "http://localhost", 1110 "http://localhost",
964 socket_data.Pass()); 1111 socket_data.Pass());
965 stream_request_.reset(); 1112 stream_request_.reset();
966 RunUntilIdle(); 1113 RunUntilIdle();
967 EXPECT_FALSE(has_failed()); 1114 EXPECT_FALSE(has_failed());
968 EXPECT_FALSE(stream_); 1115 EXPECT_FALSE(stream_);
969 } 1116 }
(...skipping 21 matching lines...) Expand all
991 EXPECT_FALSE(response_info_); 1138 EXPECT_FALSE(response_info_);
992 } 1139 }
993 1140
994 // Cancellation during read of the response headers works. 1141 // Cancellation during read of the response headers works.
995 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { 1142 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
996 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); 1143 std::string request = WebSocketStandardRequest("/", "http://localhost", "");
997 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; 1144 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())};
998 MockRead reads[] = { 1145 MockRead reads[] = {
999 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), 1146 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"),
1000 }; 1147 };
1001 DeterministicSocketData* socket_data(new DeterministicSocketData( 1148 scoped_ptr<DeterministicSocketData> socket_data(
1002 reads, arraysize(reads), writes, arraysize(writes))); 1149 BuildSocketData(reads, writes));
1003 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1004 socket_data->SetStop(1); 1150 socket_data->SetStop(1);
1151 DeterministicSocketData* socket_data_raw_ptr = socket_data.get();
1005 CreateAndConnectRawExpectations("ws://localhost/", 1152 CreateAndConnectRawExpectations("ws://localhost/",
1006 NoSubProtocols(), 1153 NoSubProtocols(),
1007 "http://localhost", 1154 "http://localhost",
1008 make_scoped_ptr(socket_data)); 1155 socket_data.Pass());
Johnny 2014/07/08 20:27:40 Why is ownership of |socket_data| passed to WebSoc
Adam Rice 2014/07/09 06:35:01 Short explanation: WebSocketDeterministicMockClien
Johnny 2014/07/09 16:16:17 SGTM.
1009 socket_data->Run(); 1156 socket_data_raw_ptr->Run();
1010 stream_request_.reset(); 1157 stream_request_.reset();
1011 RunUntilIdle(); 1158 RunUntilIdle();
1012 EXPECT_FALSE(has_failed()); 1159 EXPECT_FALSE(has_failed());
1013 EXPECT_FALSE(stream_); 1160 EXPECT_FALSE(stream_);
1014 EXPECT_TRUE(request_info_); 1161 EXPECT_TRUE(request_info_);
1015 EXPECT_FALSE(response_info_); 1162 EXPECT_FALSE(response_info_);
1016 } 1163 }
1017 1164
1018 // Over-size response headers (> 256KB) should not cause a crash. This is a 1165 // Over-size response headers (> 256KB) should not cause a crash. This is a
1019 // regression test for crbug.com/339456. It is based on the layout test 1166 // regression test for crbug.com/339456. It is based on the layout test
(...skipping 12 matching lines...) Expand all
1032 EXPECT_FALSE(response_info_); 1179 EXPECT_FALSE(response_info_);
1033 } 1180 }
1034 1181
1035 // If the remote host closes the connection without sending headers, we should 1182 // If the remote host closes the connection without sending headers, we should
1036 // log the console message "Connection closed before receiving a handshake 1183 // log the console message "Connection closed before receiving a handshake
1037 // response". 1184 // response".
1038 TEST_F(WebSocketStreamCreateTest, NoResponse) { 1185 TEST_F(WebSocketStreamCreateTest, NoResponse) {
1039 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); 1186 std::string request = WebSocketStandardRequest("/", "http://localhost", "");
1040 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; 1187 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)};
1041 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; 1188 MockRead reads[] = {MockRead(ASYNC, 0, 1)};
1042 DeterministicSocketData* socket_data(new DeterministicSocketData( 1189 scoped_ptr<DeterministicSocketData> socket_data(
1043 reads, arraysize(reads), writes, arraysize(writes))); 1190 BuildSocketData(reads, writes));
1044 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); 1191 DeterministicSocketData* socket_data_raw_ptr = socket_data.get();
1045 CreateAndConnectRawExpectations("ws://localhost/", 1192 CreateAndConnectRawExpectations("ws://localhost/",
1046 NoSubProtocols(), 1193 NoSubProtocols(),
1047 "http://localhost", 1194 "http://localhost",
1048 make_scoped_ptr(socket_data)); 1195 socket_data.Pass());
1049 socket_data->RunFor(2); 1196 socket_data_raw_ptr->RunFor(2);
1050 EXPECT_TRUE(has_failed()); 1197 EXPECT_TRUE(has_failed());
1051 EXPECT_FALSE(stream_); 1198 EXPECT_FALSE(stream_);
1052 EXPECT_FALSE(response_info_); 1199 EXPECT_FALSE(response_info_);
1053 EXPECT_EQ("Connection closed before receiving a handshake response", 1200 EXPECT_EQ("Connection closed before receiving a handshake response",
1054 failure_message()); 1201 failure_message());
1055 } 1202 }
1056 1203
1057 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) { 1204 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
1058 ssl_data_.push_back( 1205 ssl_data_.push_back(
1059 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); 1206 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
1060 ssl_data_[0]->cert = 1207 ssl_data_[0]->cert =
1061 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); 1208 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
1062 ASSERT_TRUE(ssl_data_[0]->cert); 1209 ASSERT_TRUE(ssl_data_[0]->cert);
1063 scoped_ptr<DeterministicSocketData> raw_socket_data( 1210 scoped_ptr<DeterministicSocketData> raw_socket_data(BuildNullSocketData());
1064 new DeterministicSocketData(NULL, 0, NULL, 0));
1065 CreateAndConnectRawExpectations("wss://localhost/", 1211 CreateAndConnectRawExpectations("wss://localhost/",
1066 NoSubProtocols(), 1212 NoSubProtocols(),
1067 "http://localhost", 1213 "http://localhost",
1068 raw_socket_data.Pass()); 1214 raw_socket_data.Pass());
1069 RunUntilIdle(); 1215 RunUntilIdle();
1070 EXPECT_FALSE(has_failed()); 1216 EXPECT_FALSE(has_failed());
1071 ASSERT_TRUE(ssl_error_callbacks_); 1217 ASSERT_TRUE(ssl_error_callbacks_);
1072 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, 1218 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID,
1073 &ssl_info_); 1219 &ssl_info_);
1074 RunUntilIdle(); 1220 RunUntilIdle();
1075 EXPECT_TRUE(has_failed()); 1221 EXPECT_TRUE(has_failed());
1076 } 1222 }
1077 1223
1078 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { 1224 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
1079 scoped_ptr<SSLSocketDataProvider> ssl_data( 1225 scoped_ptr<SSLSocketDataProvider> ssl_data(
1080 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); 1226 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
1081 ssl_data->cert = 1227 ssl_data->cert =
1082 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); 1228 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
1083 ASSERT_TRUE(ssl_data->cert); 1229 ASSERT_TRUE(ssl_data->cert);
1084 ssl_data_.push_back(ssl_data.release()); 1230 ssl_data_.push_back(ssl_data.release());
1085 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); 1231 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK));
1086 ssl_data_.push_back(ssl_data.release()); 1232 ssl_data_.push_back(ssl_data.release());
1087 url_request_context_host_.AddRawExpectations( 1233 url_request_context_host_.AddRawExpectations(BuildNullSocketData());
1088 make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0)));
1089 CreateAndConnectStandard( 1234 CreateAndConnectStandard(
1090 "wss://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); 1235 "wss://localhost/", "/", NoSubProtocols(), "http://localhost", "", "");
1091 RunUntilIdle(); 1236 RunUntilIdle();
1092 ASSERT_TRUE(ssl_error_callbacks_); 1237 ASSERT_TRUE(ssl_error_callbacks_);
1093 ssl_error_callbacks_->ContinueSSLRequest(); 1238 ssl_error_callbacks_->ContinueSSLRequest();
1094 RunUntilIdle(); 1239 RunUntilIdle();
1095 EXPECT_FALSE(has_failed()); 1240 EXPECT_FALSE(has_failed());
1096 EXPECT_TRUE(stream_); 1241 EXPECT_TRUE(stream_);
1097 } 1242 }
1098 1243
1244 // If the server requests authorisation, but we have no credentials, the
1245 // connection should fail cleanly.
1246 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
1247 CreateAndConnectCustomResponse("ws://localhost/",
1248 "/",
1249 NoSubProtocols(),
1250 "http://localhost",
1251 "",
1252 kUnauthorizedResponse);
1253 RunUntilIdle();
1254 EXPECT_TRUE(has_failed());
1255 EXPECT_EQ("HTTP Authentication failed; no valid credentials available",
1256 failure_message());
1257 EXPECT_TRUE(response_info_);
1258 }
1259
1260 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) {
1261 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/",
1262 "Zm9vOmJhcg==",
1263 WebSocketStandardResponse(std::string()));
1264 RunUntilIdle();
1265 EXPECT_FALSE(has_failed());
1266 EXPECT_TRUE(stream_);
1267 ASSERT_TRUE(response_info_);
1268 EXPECT_EQ(101, response_info_->status_code);
1269 }
1270
1271 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) {
1272 CreateAndConnectAuthHandshake(
1273 "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse);
1274 RunUntilIdle();
1275 EXPECT_TRUE(has_failed());
1276 EXPECT_TRUE(response_info_);
1277 }
1278
1279 // Digest auth has the same connection semantics as Basic auth, so we can
1280 // generally assume that whatever works for Basic auth will also work for
1281 // Digest. There's just one test here, to confirm that it works at all.
1282 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) {
1283 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
1284
1285 CreateAndConnectRawExpectations(
1286 "ws://FooBar:pass@localhost/",
1287 NoSubProtocols(),
1288 "http://localhost",
1289 helper_.BuildSocketData2(kAuthorizedRequest,
1290 WebSocketStandardResponse(std::string())));
1291 RunUntilIdle();
1292 EXPECT_FALSE(has_failed());
1293 EXPECT_TRUE(stream_);
1294 ASSERT_TRUE(response_info_);
1295 EXPECT_EQ(101, response_info_->status_code);
1296 }
1297
1099 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { 1298 TEST_F(WebSocketStreamCreateUMATest, Incomplete) {
1100 const std::string name("Net.WebSocket.HandshakeResult"); 1299 const std::string name("Net.WebSocket.HandshakeResult");
1101 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); 1300 scoped_ptr<base::HistogramSamples> original(GetSamples(name));
1102 1301
1103 { 1302 {
1104 StreamCreation creation; 1303 StreamCreation creation;
1105 creation.CreateAndConnectStandard("ws://localhost/", 1304 creation.CreateAndConnectStandard("ws://localhost/",
1106 "/", 1305 "/",
1107 creation.NoSubProtocols(), 1306 creation.NoSubProtocols(),
1108 "http://localhost", 1307 "http://localhost",
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 if (original) { 1370 if (original) {
1172 samples->Subtract(*original); // Cancel the original values. 1371 samples->Subtract(*original); // Cancel the original values.
1173 } 1372 }
1174 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); 1373 EXPECT_EQ(1, samples->GetCount(INCOMPLETE));
1175 EXPECT_EQ(0, samples->GetCount(CONNECTED)); 1374 EXPECT_EQ(0, samples->GetCount(CONNECTED));
1176 EXPECT_EQ(0, samples->GetCount(FAILED)); 1375 EXPECT_EQ(0, samples->GetCount(FAILED));
1177 } 1376 }
1178 1377
1179 } // namespace 1378 } // namespace
1180 } // namespace net 1379 } // namespace net
OLDNEW
« net/tools/testserver/testserver.py ('K') | « net/websockets/websocket_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698