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

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