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

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: Remove unused file. 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 stream.swap(owner_->stream_); 194 stream.swap(owner_->stream_);
167 } 195 }
168 196
169 virtual void OnFailure(const std::string& message) OVERRIDE { 197 virtual void OnFailure(const std::string& message) OVERRIDE {
170 owner_->has_failed_ = true; 198 owner_->has_failed_ = true;
171 owner_->failure_message_ = message; 199 owner_->failure_message_ = message;
172 } 200 }
173 201
174 virtual void OnStartOpeningHandshake( 202 virtual void OnStartOpeningHandshake(
175 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { 203 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE {
176 if (owner_->request_info_) 204 // Can be called multiple times (in the case of HTTP auth). Last call
177 ADD_FAILURE(); 205 // wins.
178 owner_->request_info_ = request.Pass(); 206 owner_->request_info_ = request.Pass();
179 } 207 }
180 virtual void OnFinishOpeningHandshake( 208 virtual void OnFinishOpeningHandshake(
181 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { 209 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE {
182 if (owner_->response_info_) 210 if (owner_->response_info_)
183 ADD_FAILURE(); 211 ADD_FAILURE();
184 owner_->response_info_ = response.Pass(); 212 owner_->response_info_ = response.Pass();
185 } 213 }
186 virtual void OnSSLCertificateError( 214 virtual void OnSSLCertificateError(
187 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> 215 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks>
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 "ws://localhost/testing_path", 253 "ws://localhost/testing_path",
226 "/testing_path", 254 "/testing_path",
227 NoSubProtocols(), 255 NoSubProtocols(),
228 "http://localhost", 256 "http://localhost",
229 "", 257 "",
230 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n"); 258 "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n");
231 RunUntilIdle(); 259 RunUntilIdle();
232 } 260 }
233 }; 261 };
234 262
263 // Common code to construct expectations for authentication tests that receive
264 // the auth challenge on one connection and then create a second connection to
265 // send the authenticated request on.
266 class CommonAuthTestHelper {
267 public:
268 scoped_ptr<DeterministicSocketData> BuildSocketData1(
269 const std::string& response) {
270 request1 = WebSocketStandardRequest("/", "http://localhost", "");
271 writes1[0] = MockWrite(SYNCHRONOUS, 0, request1.c_str());
272 response1 = response;
273 reads1[0] = MockRead(SYNCHRONOUS, 1, response1.c_str());
274 reads1[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection
275
276 return BuildSocketData(reads1, writes1);
277 }
278
279 scoped_ptr<DeterministicSocketData> BuildSocketData2(
280 const std::string& request,
281 const std::string& response) {
282 request2 = request;
283 response2 = response;
284 writes2[0] = MockWrite(SYNCHRONOUS, 0, request2.c_str());
285 reads2[0] = MockRead(SYNCHRONOUS, 1, response2.c_str());
286 return BuildSocketData(reads2, writes2);
287 }
288
289 private:
290 // These need to be object-scoped since they have to remain valid until all
291 // socket operations in the test are complete.
292 std::string request1;
293 std::string request2;
294 std::string response1;
295 std::string response2;
296 MockRead reads1[2];
297 MockWrite writes1[1];
298 MockRead reads2[1];
299 MockWrite writes2[1];
300 };
301
302 // Data and methods for BasicAuth tests.
303 class WebSocketStreamCreateBasicAuthTest : public WebSocketStreamCreateTest {
304 protected:
305 void CreateAndConnectAuthHandshake(const std::string& url,
306 const std::string& base64_user_pass,
307 const std::string& response2) {
308 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
309
310 static const char request2format[] =
311 "GET / HTTP/1.1\r\n"
312 "Host: localhost\r\n"
313 "Connection: Upgrade\r\n"
314 "Pragma: no-cache\r\n"
315 "Cache-Control: no-cache\r\n"
316 "Authorization: Basic %s\r\n"
317 "Upgrade: websocket\r\n"
318 "Origin: http://localhost\r\n"
319 "Sec-WebSocket-Version: 13\r\n"
320 "User-Agent:\r\n"
321 "Accept-Encoding: gzip,deflate\r\n"
322 "Accept-Language: en-us,fr\r\n"
323 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
324 "Sec-WebSocket-Extensions: permessage-deflate; "
325 "client_max_window_bits\r\n"
326 "\r\n";
327 const std::string request =
328 base::StringPrintf(request2format, base64_user_pass.c_str());
329 CreateAndConnectRawExpectations(
330 url,
331 NoSubProtocols(),
332 "http://localhost",
333 helper_.BuildSocketData2(request, response2));
334 }
335
336 static const char kUnauthorizedResponse[];
337
338 CommonAuthTestHelper helper_;
339 };
340
341 class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest {
342 protected:
343 static const char kUnauthorizedResponse[];
344 static const char kAuthorizedRequest[];
345
346 CommonAuthTestHelper helper_;
347 };
348
349 const char WebSocketStreamCreateBasicAuthTest::kUnauthorizedResponse[] =
350 "HTTP/1.1 401 Unauthorized\r\n"
351 "Content-Length: 0\r\n"
352 "WWW-Authenticate: Basic realm=\"camelot\"\r\n"
353 "\r\n";
354
355 // These negotiation values are borrowed from
356 // http_auth_handler_digest_unittest.cc. Feel free to come up with new ones if
357 // you are bored. Only the weakest (no qop) variants of Digest authentication
358 // can be tested by this method, because the others involve random input.
359 const char WebSocketStreamCreateDigestAuthTest::kUnauthorizedResponse[] =
360 "HTTP/1.1 401 Unauthorized\r\n"
361 "Content-Length: 0\r\n"
362 "WWW-Authenticate: Digest realm=\"Oblivion\", nonce=\"nonce-value\"\r\n"
363 "\r\n";
364
365 const char WebSocketStreamCreateDigestAuthTest::kAuthorizedRequest[] =
366 "GET / HTTP/1.1\r\n"
367 "Host: localhost\r\n"
368 "Connection: Upgrade\r\n"
369 "Pragma: no-cache\r\n"
370 "Cache-Control: no-cache\r\n"
371 "Authorization: Digest username=\"FooBar\", realm=\"Oblivion\", "
372 "nonce=\"nonce-value\", uri=\"/\", "
373 "response=\"f72ff54ebde2f928860f806ec04acd1b\"\r\n"
374 "Upgrade: websocket\r\n"
375 "Origin: http://localhost\r\n"
376 "Sec-WebSocket-Version: 13\r\n"
377 "User-Agent:\r\n"
378 "Accept-Encoding: gzip,deflate\r\n"
379 "Accept-Language: en-us,fr\r\n"
380 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
381 "Sec-WebSocket-Extensions: permessage-deflate; "
382 "client_max_window_bits\r\n"
383 "\r\n";
384
235 class WebSocketStreamCreateUMATest : public ::testing::Test { 385 class WebSocketStreamCreateUMATest : public ::testing::Test {
236 public: 386 public:
237 // This enum should match with the enum in Delegate in websocket_stream.cc. 387 // This enum should match with the enum in Delegate in websocket_stream.cc.
238 enum HandshakeResult { 388 enum HandshakeResult {
239 INCOMPLETE, 389 INCOMPLETE,
240 CONNECTED, 390 CONNECTED,
241 FAILED, 391 FAILED,
242 NUM_HANDSHAKE_RESULT_TYPES, 392 NUM_HANDSHAKE_RESULT_TYPES,
243 }; 393 };
244 394
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 stream_request_.reset(); 1067 stream_request_.reset();
918 RunUntilIdle(); 1068 RunUntilIdle();
919 EXPECT_FALSE(has_failed()); 1069 EXPECT_FALSE(has_failed());
920 EXPECT_FALSE(stream_); 1070 EXPECT_FALSE(stream_);
921 EXPECT_FALSE(request_info_); 1071 EXPECT_FALSE(request_info_);
922 EXPECT_FALSE(response_info_); 1072 EXPECT_FALSE(response_info_);
923 } 1073 }
924 1074
925 // Connect failure must look just like negotiation failure. 1075 // Connect failure must look just like negotiation failure.
926 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { 1076 TEST_F(WebSocketStreamCreateTest, ConnectionFailure) {
927 scoped_ptr<DeterministicSocketData> socket_data( 1077 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
928 new DeterministicSocketData(NULL, 0, NULL, 0));
929 socket_data->set_connect_data( 1078 socket_data->set_connect_data(
930 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); 1079 MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
931 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 1080 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
932 "http://localhost", socket_data.Pass()); 1081 "http://localhost", socket_data.Pass());
933 RunUntilIdle(); 1082 RunUntilIdle();
934 EXPECT_TRUE(has_failed()); 1083 EXPECT_TRUE(has_failed());
935 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", 1084 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED",
936 failure_message()); 1085 failure_message());
937 EXPECT_FALSE(request_info_); 1086 EXPECT_FALSE(request_info_);
938 EXPECT_FALSE(response_info_); 1087 EXPECT_FALSE(response_info_);
939 } 1088 }
940 1089
941 // Connect timeout must look just like any other failure. 1090 // Connect timeout must look just like any other failure.
942 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { 1091 TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) {
943 scoped_ptr<DeterministicSocketData> socket_data( 1092 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
944 new DeterministicSocketData(NULL, 0, NULL, 0));
945 socket_data->set_connect_data( 1093 socket_data->set_connect_data(
946 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT)); 1094 MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT));
947 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), 1095 CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
948 "http://localhost", socket_data.Pass()); 1096 "http://localhost", socket_data.Pass());
949 RunUntilIdle(); 1097 RunUntilIdle();
950 EXPECT_TRUE(has_failed()); 1098 EXPECT_TRUE(has_failed());
951 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", 1099 EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT",
952 failure_message()); 1100 failure_message());
953 } 1101 }
954 1102
955 // Cancellation during connect works. 1103 // Cancellation during connect works.
956 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { 1104 TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) {
957 scoped_ptr<DeterministicSocketData> socket_data( 1105 scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData());
958 new DeterministicSocketData(NULL, 0, NULL, 0));
959 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); 1106 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
960 CreateAndConnectRawExpectations("ws://localhost/", 1107 CreateAndConnectRawExpectations("ws://localhost/",
961 NoSubProtocols(), 1108 NoSubProtocols(),
962 "http://localhost", 1109 "http://localhost",
963 socket_data.Pass()); 1110 socket_data.Pass());
964 stream_request_.reset(); 1111 stream_request_.reset();
965 RunUntilIdle(); 1112 RunUntilIdle();
966 EXPECT_FALSE(has_failed()); 1113 EXPECT_FALSE(has_failed());
967 EXPECT_FALSE(stream_); 1114 EXPECT_FALSE(stream_);
968 } 1115 }
(...skipping 21 matching lines...) Expand all
990 EXPECT_FALSE(response_info_); 1137 EXPECT_FALSE(response_info_);
991 } 1138 }
992 1139
993 // Cancellation during read of the response headers works. 1140 // Cancellation during read of the response headers works.
994 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) { 1141 TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
995 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); 1142 std::string request = WebSocketStandardRequest("/", "http://localhost", "");
996 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())}; 1143 MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())};
997 MockRead reads[] = { 1144 MockRead reads[] = {
998 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"), 1145 MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"),
999 }; 1146 };
1000 DeterministicSocketData* socket_data(new DeterministicSocketData( 1147 scoped_ptr<DeterministicSocketData> socket_data(
1001 reads, arraysize(reads), writes, arraysize(writes))); 1148 BuildSocketData(reads, writes));
1002 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1003 socket_data->SetStop(1); 1149 socket_data->SetStop(1);
1150 DeterministicSocketData* socket_data_raw_ptr = socket_data.get();
1004 CreateAndConnectRawExpectations("ws://localhost/", 1151 CreateAndConnectRawExpectations("ws://localhost/",
1005 NoSubProtocols(), 1152 NoSubProtocols(),
1006 "http://localhost", 1153 "http://localhost",
1007 make_scoped_ptr(socket_data)); 1154 socket_data.Pass());
1008 socket_data->Run(); 1155 socket_data_raw_ptr->Run();
1009 stream_request_.reset(); 1156 stream_request_.reset();
1010 RunUntilIdle(); 1157 RunUntilIdle();
1011 EXPECT_FALSE(has_failed()); 1158 EXPECT_FALSE(has_failed());
1012 EXPECT_FALSE(stream_); 1159 EXPECT_FALSE(stream_);
1013 EXPECT_TRUE(request_info_); 1160 EXPECT_TRUE(request_info_);
1014 EXPECT_FALSE(response_info_); 1161 EXPECT_FALSE(response_info_);
1015 } 1162 }
1016 1163
1017 // Over-size response headers (> 256KB) should not cause a crash. This is a 1164 // Over-size response headers (> 256KB) should not cause a crash. This is a
1018 // regression test for crbug.com/339456. It is based on the layout test 1165 // regression test for crbug.com/339456. It is based on the layout test
(...skipping 12 matching lines...) Expand all
1031 EXPECT_FALSE(response_info_); 1178 EXPECT_FALSE(response_info_);
1032 } 1179 }
1033 1180
1034 // If the remote host closes the connection without sending headers, we should 1181 // If the remote host closes the connection without sending headers, we should
1035 // log the console message "Connection closed before receiving a handshake 1182 // log the console message "Connection closed before receiving a handshake
1036 // response". 1183 // response".
1037 TEST_F(WebSocketStreamCreateTest, NoResponse) { 1184 TEST_F(WebSocketStreamCreateTest, NoResponse) {
1038 std::string request = WebSocketStandardRequest("/", "http://localhost", ""); 1185 std::string request = WebSocketStandardRequest("/", "http://localhost", "");
1039 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)}; 1186 MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)};
1040 MockRead reads[] = {MockRead(ASYNC, 0, 1)}; 1187 MockRead reads[] = {MockRead(ASYNC, 0, 1)};
1041 DeterministicSocketData* socket_data(new DeterministicSocketData( 1188 scoped_ptr<DeterministicSocketData> socket_data(
1042 reads, arraysize(reads), writes, arraysize(writes))); 1189 BuildSocketData(reads, writes));
1043 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); 1190 DeterministicSocketData* socket_data_raw_ptr = socket_data.get();
1044 CreateAndConnectRawExpectations("ws://localhost/", 1191 CreateAndConnectRawExpectations("ws://localhost/",
1045 NoSubProtocols(), 1192 NoSubProtocols(),
1046 "http://localhost", 1193 "http://localhost",
1047 make_scoped_ptr(socket_data)); 1194 socket_data.Pass());
1048 socket_data->RunFor(2); 1195 socket_data_raw_ptr->RunFor(2);
1049 EXPECT_TRUE(has_failed()); 1196 EXPECT_TRUE(has_failed());
1050 EXPECT_FALSE(stream_); 1197 EXPECT_FALSE(stream_);
1051 EXPECT_FALSE(response_info_); 1198 EXPECT_FALSE(response_info_);
1052 EXPECT_EQ("Connection closed before receiving a handshake response", 1199 EXPECT_EQ("Connection closed before receiving a handshake response",
1053 failure_message()); 1200 failure_message());
1054 } 1201 }
1055 1202
1056 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) { 1203 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
1057 ssl_data_.push_back( 1204 ssl_data_.push_back(
1058 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); 1205 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
1059 ssl_data_[0]->cert = 1206 ssl_data_[0]->cert =
1060 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); 1207 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
1061 ASSERT_TRUE(ssl_data_[0]->cert); 1208 ASSERT_TRUE(ssl_data_[0]->cert);
1062 scoped_ptr<DeterministicSocketData> raw_socket_data( 1209 scoped_ptr<DeterministicSocketData> raw_socket_data(BuildNullSocketData());
1063 new DeterministicSocketData(NULL, 0, NULL, 0));
1064 CreateAndConnectRawExpectations("wss://localhost/", 1210 CreateAndConnectRawExpectations("wss://localhost/",
1065 NoSubProtocols(), 1211 NoSubProtocols(),
1066 "http://localhost", 1212 "http://localhost",
1067 raw_socket_data.Pass()); 1213 raw_socket_data.Pass());
1068 RunUntilIdle(); 1214 RunUntilIdle();
1069 EXPECT_FALSE(has_failed()); 1215 EXPECT_FALSE(has_failed());
1070 ASSERT_TRUE(ssl_error_callbacks_); 1216 ASSERT_TRUE(ssl_error_callbacks_);
1071 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID, 1217 ssl_error_callbacks_->CancelSSLRequest(ERR_CERT_AUTHORITY_INVALID,
1072 &ssl_info_); 1218 &ssl_info_);
1073 RunUntilIdle(); 1219 RunUntilIdle();
1074 EXPECT_TRUE(has_failed()); 1220 EXPECT_TRUE(has_failed());
1075 } 1221 }
1076 1222
1077 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) { 1223 TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
1078 scoped_ptr<SSLSocketDataProvider> ssl_data( 1224 scoped_ptr<SSLSocketDataProvider> ssl_data(
1079 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID)); 1225 new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
1080 ssl_data->cert = 1226 ssl_data->cert =
1081 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); 1227 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
1082 ASSERT_TRUE(ssl_data->cert); 1228 ASSERT_TRUE(ssl_data->cert);
1083 ssl_data_.push_back(ssl_data.release()); 1229 ssl_data_.push_back(ssl_data.release());
1084 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK)); 1230 ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK));
1085 ssl_data_.push_back(ssl_data.release()); 1231 ssl_data_.push_back(ssl_data.release());
1086 url_request_context_host_.AddRawExpectations( 1232 url_request_context_host_.AddRawExpectations(BuildNullSocketData());
1087 make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0)));
1088 CreateAndConnectStandard( 1233 CreateAndConnectStandard(
1089 "wss://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); 1234 "wss://localhost/", "/", NoSubProtocols(), "http://localhost", "", "");
1090 RunUntilIdle(); 1235 RunUntilIdle();
1091 ASSERT_TRUE(ssl_error_callbacks_); 1236 ASSERT_TRUE(ssl_error_callbacks_);
1092 ssl_error_callbacks_->ContinueSSLRequest(); 1237 ssl_error_callbacks_->ContinueSSLRequest();
1093 RunUntilIdle(); 1238 RunUntilIdle();
1094 EXPECT_FALSE(has_failed()); 1239 EXPECT_FALSE(has_failed());
1095 EXPECT_TRUE(stream_); 1240 EXPECT_TRUE(stream_);
1096 } 1241 }
1097 1242
1243 // If the server requests authorisation, but we have no credentials, the
1244 // connection should fail cleanly.
1245 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
1246 CreateAndConnectCustomResponse("ws://localhost/",
1247 "/",
1248 NoSubProtocols(),
1249 "http://localhost",
1250 "",
1251 kUnauthorizedResponse);
1252 RunUntilIdle();
1253 EXPECT_TRUE(has_failed());
1254 EXPECT_EQ("HTTP Authentication failed; no valid credentials available",
1255 failure_message());
1256 EXPECT_TRUE(response_info_);
1257 }
1258
1259 TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) {
1260 CreateAndConnectAuthHandshake("ws://foo:bar@localhost/",
1261 "Zm9vOmJhcg==",
1262 WebSocketStandardResponse(std::string()));
1263 RunUntilIdle();
1264 EXPECT_FALSE(has_failed());
1265 EXPECT_TRUE(stream_);
1266 ASSERT_TRUE(response_info_);
1267 EXPECT_EQ(101, response_info_->status_code);
1268 }
1269
1270 TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) {
1271 CreateAndConnectAuthHandshake(
1272 "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse);
1273 RunUntilIdle();
1274 EXPECT_TRUE(has_failed());
1275 EXPECT_TRUE(response_info_);
1276 }
1277
1278 // Digest auth has the same connection semantics as Basic auth, so we can
1279 // generally assume that whatever works for Basic auth will also work for
1280 // Digest. There's just one test here, to confirm that it works at all.
1281 TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) {
1282 AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
1283
1284 CreateAndConnectRawExpectations(
1285 "ws://FooBar:pass@localhost/",
1286 NoSubProtocols(),
1287 "http://localhost",
1288 helper_.BuildSocketData2(kAuthorizedRequest,
1289 WebSocketStandardResponse(std::string())));
1290 RunUntilIdle();
1291 EXPECT_FALSE(has_failed());
1292 EXPECT_TRUE(stream_);
1293 ASSERT_TRUE(response_info_);
1294 EXPECT_EQ(101, response_info_->status_code);
1295 }
1296
1098 TEST_F(WebSocketStreamCreateUMATest, Incomplete) { 1297 TEST_F(WebSocketStreamCreateUMATest, Incomplete) {
1099 const std::string name("Net.WebSocket.HandshakeResult"); 1298 const std::string name("Net.WebSocket.HandshakeResult");
1100 scoped_ptr<base::HistogramSamples> original(GetSamples(name)); 1299 scoped_ptr<base::HistogramSamples> original(GetSamples(name));
1101 1300
1102 { 1301 {
1103 StreamCreation creation; 1302 StreamCreation creation;
1104 creation.CreateAndConnectStandard("ws://localhost/", 1303 creation.CreateAndConnectStandard("ws://localhost/",
1105 "/", 1304 "/",
1106 creation.NoSubProtocols(), 1305 creation.NoSubProtocols(),
1107 "http://localhost", 1306 "http://localhost",
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 if (original) { 1369 if (original) {
1171 samples->Subtract(*original); // Cancel the original values. 1370 samples->Subtract(*original); // Cancel the original values.
1172 } 1371 }
1173 EXPECT_EQ(1, samples->GetCount(INCOMPLETE)); 1372 EXPECT_EQ(1, samples->GetCount(INCOMPLETE));
1174 EXPECT_EQ(0, samples->GetCount(CONNECTED)); 1373 EXPECT_EQ(0, samples->GetCount(CONNECTED));
1175 EXPECT_EQ(0, samples->GetCount(FAILED)); 1374 EXPECT_EQ(0, samples->GetCount(FAILED));
1176 } 1375 }
1177 1376
1178 } // namespace 1377 } // namespace
1179 } // namespace net 1378 } // namespace net
OLDNEW
« net/websockets/websocket_stream.cc ('K') | « net/websockets/websocket_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698