• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "net/websockets/websocket_handshake_handler.h"
6 
7 #include <string>
8 
9 #include "net/socket/next_proto.h"
10 #include "net/spdy/spdy_header_block.h"
11 #include "net/spdy/spdy_websocket_test_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "url/gurl.h"
14 
15 namespace net {
16 
17 namespace {
18 
19 class WebSocketHandshakeHandlerSpdyTest
20     : public ::testing::Test,
21       public ::testing::WithParamInterface<NextProto> {
22  protected:
WebSocketHandshakeHandlerSpdyTest()23   WebSocketHandshakeHandlerSpdyTest() : spdy_util_(GetParam()) {}
24 
25   SpdyWebSocketTestUtil spdy_util_;
26 };
27 
28 INSTANTIATE_TEST_CASE_P(
29     NextProto,
30     WebSocketHandshakeHandlerSpdyTest,
31     testing::Values(kProtoDeprecatedSPDY2,
32                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
33 
TEST_P(WebSocketHandshakeHandlerSpdyTest,RequestResponse)34 TEST_P(WebSocketHandshakeHandlerSpdyTest, RequestResponse) {
35   WebSocketHandshakeRequestHandler request_handler;
36 
37   static const char kHandshakeRequestMessage[] =
38       "GET /demo HTTP/1.1\r\n"
39       "Host: example.com\r\n"
40       "Upgrade: websocket\r\n"
41       "Connection: Upgrade\r\n"
42       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
43       "Origin: http://example.com\r\n"
44       "Sec-WebSocket-Protocol: sample\r\n"
45       "Sec-WebSocket-Extensions: foo\r\n"
46       "Sec-WebSocket-Version: 13\r\n"
47       "\r\n";
48 
49   EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage,
50                                            strlen(kHandshakeRequestMessage)));
51 
52   GURL url("ws://example.com/demo");
53   std::string challenge;
54   SpdyHeaderBlock headers;
55   ASSERT_TRUE(request_handler.GetRequestHeaderBlock(url,
56                                                     &headers,
57                                                     &challenge,
58                                                     spdy_util_.spdy_version()));
59 
60   EXPECT_EQ(url.path(), spdy_util_.GetHeader(headers, "path"));
61   EXPECT_TRUE(spdy_util_.GetHeader(headers, "upgrade").empty());
62   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Upgrade").empty());
63   EXPECT_TRUE(spdy_util_.GetHeader(headers, "connection").empty());
64   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Connection").empty());
65   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Sec-WebSocket-Key").empty());
66   EXPECT_TRUE(spdy_util_.GetHeader(headers, "sec-websocket-key").empty());
67   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Sec-WebSocket-Version").empty());
68   EXPECT_TRUE(spdy_util_.GetHeader(headers, "sec-webSocket-version").empty());
69   EXPECT_EQ("example.com", spdy_util_.GetHeader(headers, "host"));
70   EXPECT_EQ("http://example.com", spdy_util_.GetHeader(headers, "origin"));
71   EXPECT_EQ("sample", spdy_util_.GetHeader(headers, "sec-websocket-protocol"));
72   EXPECT_EQ("foo", spdy_util_.GetHeader(headers, "sec-websocket-extensions"));
73   EXPECT_EQ("ws", spdy_util_.GetHeader(headers, "scheme"));
74   EXPECT_EQ("WebSocket/13", spdy_util_.GetHeader(headers, "version"));
75 
76   static const char expected_challenge[] = "dGhlIHNhbXBsZSBub25jZQ==";
77 
78   EXPECT_EQ(expected_challenge, challenge);
79 
80   headers.clear();
81 
82   spdy_util_.SetHeader("status", "101 Switching Protocols", &headers);
83   spdy_util_.SetHeader("sec-websocket-protocol", "sample", &headers);
84   spdy_util_.SetHeader("sec-websocket-extensions", "foo", &headers);
85 
86   WebSocketHandshakeResponseHandler response_handler;
87   EXPECT_TRUE(response_handler.ParseResponseHeaderBlock(
88       headers, challenge, spdy_util_.spdy_version()));
89   EXPECT_TRUE(response_handler.HasResponse());
90 
91   // Note that order of sec-websocket-* is sensitive with hash_map order.
92   static const char kHandshakeResponseExpectedMessage[] =
93       "HTTP/1.1 101 Switching Protocols\r\n"
94       "Upgrade: websocket\r\n"
95       "Connection: Upgrade\r\n"
96       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
97       "sec-websocket-extensions: foo\r\n"
98       "sec-websocket-protocol: sample\r\n"
99       "\r\n";
100 
101   EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse());
102 }
103 
TEST_P(WebSocketHandshakeHandlerSpdyTest,RequestResponseWithCookies)104 TEST_P(WebSocketHandshakeHandlerSpdyTest, RequestResponseWithCookies) {
105   WebSocketHandshakeRequestHandler request_handler;
106 
107   // Note that websocket won't use multiple headers in request now.
108   static const char kHandshakeRequestMessage[] =
109       "GET /demo HTTP/1.1\r\n"
110       "Host: example.com\r\n"
111       "Upgrade: websocket\r\n"
112       "Connection: Upgrade\r\n"
113       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
114       "Origin: http://example.com\r\n"
115       "Sec-WebSocket-Protocol: sample\r\n"
116       "Sec-WebSocket-Extensions: foo\r\n"
117       "Sec-WebSocket-Version: 13\r\n"
118       "Cookie: WK-websocket-test=1; WK-websocket-test-httponly=1\r\n"
119       "\r\n";
120 
121   EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage,
122                                            strlen(kHandshakeRequestMessage)));
123 
124   GURL url("ws://example.com/demo");
125   std::string challenge;
126   SpdyHeaderBlock headers;
127   ASSERT_TRUE(request_handler.GetRequestHeaderBlock(url,
128                                                     &headers,
129                                                     &challenge,
130                                                     spdy_util_.spdy_version()));
131 
132   EXPECT_EQ(url.path(), spdy_util_.GetHeader(headers, "path"));
133   EXPECT_TRUE(spdy_util_.GetHeader(headers, "upgrade").empty());
134   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Upgrade").empty());
135   EXPECT_TRUE(spdy_util_.GetHeader(headers, "connection").empty());
136   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Connection").empty());
137   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Sec-WebSocket-Key").empty());
138   EXPECT_TRUE(spdy_util_.GetHeader(headers, "sec-websocket-key").empty());
139   EXPECT_TRUE(spdy_util_.GetHeader(headers, "Sec-WebSocket-Version").empty());
140   EXPECT_TRUE(spdy_util_.GetHeader(headers, "sec-webSocket-version").empty());
141   EXPECT_EQ("example.com", spdy_util_.GetHeader(headers, "host"));
142   EXPECT_EQ("http://example.com", spdy_util_.GetHeader(headers, "origin"));
143   EXPECT_EQ("sample", spdy_util_.GetHeader(headers, "sec-websocket-protocol"));
144   EXPECT_EQ("foo", spdy_util_.GetHeader(headers, "sec-websocket-extensions"));
145   EXPECT_EQ("ws", spdy_util_.GetHeader(headers, "scheme"));
146   EXPECT_EQ("WebSocket/13", spdy_util_.GetHeader(headers, "version"));
147   EXPECT_EQ("WK-websocket-test=1; WK-websocket-test-httponly=1",
148             headers["cookie"]);
149 
150   const char expected_challenge[] = "dGhlIHNhbXBsZSBub25jZQ==";
151 
152   EXPECT_EQ(expected_challenge, challenge);
153 
154   headers.clear();
155 
156   spdy_util_.SetHeader("status", "101 Switching Protocols", &headers);
157   spdy_util_.SetHeader("sec-websocket-protocol", "sample", &headers);
158   spdy_util_.SetHeader("sec-websocket-extensions", "foo", &headers);
159   std::string cookie = "WK-websocket-test=1";
160   cookie.append(1, '\0');
161   cookie += "WK-websocket-test-httponly=1; HttpOnly";
162   headers["set-cookie"] = cookie;
163 
164 
165   WebSocketHandshakeResponseHandler response_handler;
166   EXPECT_TRUE(response_handler.ParseResponseHeaderBlock(
167       headers, challenge, spdy_util_.spdy_version()));
168   EXPECT_TRUE(response_handler.HasResponse());
169 
170   // Note that order of sec-websocket-* is sensitive with hash_map order.
171   static const char kHandshakeResponseExpectedMessage[] =
172       "HTTP/1.1 101 Switching Protocols\r\n"
173       "Upgrade: websocket\r\n"
174       "Connection: Upgrade\r\n"
175       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
176       "sec-websocket-extensions: foo\r\n"
177       "sec-websocket-protocol: sample\r\n"
178       "set-cookie: WK-websocket-test=1\r\n"
179       "set-cookie: WK-websocket-test-httponly=1; HttpOnly\r\n"
180       "\r\n";
181 
182   EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse());
183 }
184 
185 }  // namespace
186 
187 }  // namespace net
188