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

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