• 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 #include <vector>
9 
10 #include "base/basictypes.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "net/http/http_response_headers.h"
14 #include "net/http/http_util.h"
15 #include "url/gurl.h"
16 
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace {
20 
21 const char* const kCookieHeaders[] = {
22   "cookie", "cookie2"
23 };
24 
25 const char* const kSetCookieHeaders[] = {
26   "set-cookie", "set-cookie2"
27 };
28 
29 }  // namespace
30 
31 namespace net {
32 
TEST(WebSocketHandshakeRequestHandlerTest,SimpleRequest)33 TEST(WebSocketHandshakeRequestHandlerTest, SimpleRequest) {
34   WebSocketHandshakeRequestHandler handler;
35 
36   static const char kHandshakeRequestMessage[] =
37       "GET /demo HTTP/1.1\r\n"
38       "Host: example.com\r\n"
39       "Upgrade: websocket\r\n"
40       "Connection: Upgrade\r\n"
41       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
42       "Sec-WebSocket-Origin: http://example.com\r\n"
43       "Sec-WebSocket-Protocol: sample\r\n"
44       "Sec-WebSocket-Version: 13\r\n"
45       "\r\n";
46 
47   EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage,
48                                    strlen(kHandshakeRequestMessage)));
49 
50   handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders));
51 
52   EXPECT_EQ(kHandshakeRequestMessage, handler.GetRawRequest());
53 }
54 
TEST(WebSocketHandshakeRequestHandlerTest,ReplaceRequestCookies)55 TEST(WebSocketHandshakeRequestHandlerTest, ReplaceRequestCookies) {
56   WebSocketHandshakeRequestHandler handler;
57 
58   static const char kHandshakeRequestMessage[] =
59       "GET /demo HTTP/1.1\r\n"
60       "Host: example.com\r\n"
61       "Upgrade: websocket\r\n"
62       "Connection: Upgrade\r\n"
63       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
64       "Sec-WebSocket-Origin: http://example.com\r\n"
65       "Sec-WebSocket-Protocol: sample\r\n"
66       "Sec-WebSocket-Version: 13\r\n"
67       "Cookie: WK-websocket-test=1\r\n"
68       "\r\n";
69 
70   EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage,
71                                    strlen(kHandshakeRequestMessage)));
72 
73   handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders));
74 
75   handler.AppendHeaderIfMissing("Cookie",
76                                 "WK-websocket-test=1; "
77                                 "WK-websocket-test-httponly=1");
78 
79   static const char kHandshakeRequestExpectedMessage[] =
80       "GET /demo HTTP/1.1\r\n"
81       "Host: example.com\r\n"
82       "Upgrade: websocket\r\n"
83       "Connection: Upgrade\r\n"
84       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
85       "Sec-WebSocket-Origin: http://example.com\r\n"
86       "Sec-WebSocket-Protocol: sample\r\n"
87       "Sec-WebSocket-Version: 13\r\n"
88       "Cookie: WK-websocket-test=1; WK-websocket-test-httponly=1\r\n"
89       "\r\n";
90 
91   EXPECT_EQ(kHandshakeRequestExpectedMessage, handler.GetRawRequest());
92 }
93 
TEST(WebSocketHandshakeResponseHandlerTest,SimpleResponse)94 TEST(WebSocketHandshakeResponseHandlerTest, SimpleResponse) {
95   WebSocketHandshakeResponseHandler handler;
96 
97   static const char kHandshakeResponseMessage[] =
98       "HTTP/1.1 101 Switching Protocols\r\n"
99       "Upgrade: websocket\r\n"
100       "Connection: Upgrade\r\n"
101       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
102       "Sec-WebSocket-Protocol: sample\r\n"
103       "\r\n";
104 
105   EXPECT_EQ(strlen(kHandshakeResponseMessage),
106             handler.ParseRawResponse(kHandshakeResponseMessage,
107                                      strlen(kHandshakeResponseMessage)));
108   EXPECT_TRUE(handler.HasResponse());
109 
110   handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders));
111 
112   EXPECT_EQ(kHandshakeResponseMessage, handler.GetResponse());
113 }
114 
TEST(WebSocketHandshakeResponseHandlerTest,ReplaceResponseCookies)115 TEST(WebSocketHandshakeResponseHandlerTest, ReplaceResponseCookies) {
116   WebSocketHandshakeResponseHandler handler;
117 
118   static const char kHandshakeResponseMessage[] =
119       "HTTP/1.1 101 Switching Protocols\r\n"
120       "Upgrade: websocket\r\n"
121       "Connection: Upgrade\r\n"
122       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
123       "Sec-WebSocket-Protocol: sample\r\n"
124       "Set-Cookie: WK-websocket-test-1\r\n"
125       "Set-Cookie: WK-websocket-test-httponly=1; HttpOnly\r\n"
126       "\r\n";
127 
128   EXPECT_EQ(strlen(kHandshakeResponseMessage),
129             handler.ParseRawResponse(kHandshakeResponseMessage,
130                                      strlen(kHandshakeResponseMessage)));
131   EXPECT_TRUE(handler.HasResponse());
132   std::vector<std::string> cookies;
133   handler.GetHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders), &cookies);
134   ASSERT_EQ(2U, cookies.size());
135   EXPECT_EQ("WK-websocket-test-1", cookies[0]);
136   EXPECT_EQ("WK-websocket-test-httponly=1; HttpOnly", cookies[1]);
137   handler.RemoveHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders));
138 
139   static const char kHandshakeResponseExpectedMessage[] =
140       "HTTP/1.1 101 Switching Protocols\r\n"
141       "Upgrade: websocket\r\n"
142       "Connection: Upgrade\r\n"
143       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
144       "Sec-WebSocket-Protocol: sample\r\n"
145       "\r\n";
146 
147   EXPECT_EQ(kHandshakeResponseExpectedMessage, handler.GetResponse());
148 }
149 
TEST(WebSocketHandshakeResponseHandlerTest,BadResponse)150 TEST(WebSocketHandshakeResponseHandlerTest, BadResponse) {
151   WebSocketHandshakeResponseHandler handler;
152 
153   static const char kBadMessage[] = "\n\n\r\net-Location: w";
154   EXPECT_EQ(2U, handler.ParseRawResponse(kBadMessage, strlen(kBadMessage)));
155   EXPECT_TRUE(handler.HasResponse());
156   EXPECT_EQ("\n\n", handler.GetResponse());
157 }
158 
TEST(WebSocketHandshakeResponseHandlerTest,BadResponse2)159 TEST(WebSocketHandshakeResponseHandlerTest, BadResponse2) {
160   WebSocketHandshakeResponseHandler handler;
161 
162   static const char kBadMessage[] = "\n\r\n\r\net-Location: w";
163   EXPECT_EQ(3U, handler.ParseRawResponse(kBadMessage, strlen(kBadMessage)));
164   EXPECT_TRUE(handler.HasResponse());
165   EXPECT_EQ("\n\r\n", handler.GetResponse());
166 }
167 
TEST(WebSocketHandshakeHandlerTest,HttpRequestResponse)168 TEST(WebSocketHandshakeHandlerTest, HttpRequestResponse) {
169   WebSocketHandshakeRequestHandler request_handler;
170 
171   static const char kHandshakeRequestMessage[] =
172       "GET /demo HTTP/1.1\r\n"
173       "Host: example.com\r\n"
174       "Upgrade: websocket\r\n"
175       "Connection: Upgrade\r\n"
176       "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
177       "Sec-WebSocket-Origin: http://example.com\r\n"
178       "Sec-WebSocket-Protocol: sample\r\n"
179       "Sec-WebSocket-Version: 13\r\n"
180       "\r\n";
181 
182   EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage,
183                                            strlen(kHandshakeRequestMessage)));
184 
185   GURL url("ws://example.com/demo");
186   std::string challenge;
187   const HttpRequestInfo& request_info =
188       request_handler.GetRequestInfo(url, &challenge);
189 
190   EXPECT_EQ(url, request_info.url);
191   EXPECT_EQ("GET", request_info.method);
192   EXPECT_FALSE(request_info.extra_headers.HasHeader("Upgrade"));
193   EXPECT_FALSE(request_info.extra_headers.HasHeader("Connection"));
194   EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key"));
195   std::string value;
196   EXPECT_TRUE(request_info.extra_headers.GetHeader("Host", &value));
197   EXPECT_EQ("example.com", value);
198   EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Origin",
199                                                    &value));
200   EXPECT_EQ("http://example.com", value);
201   EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Protocol",
202                                                    &value));
203   EXPECT_EQ("sample", value);
204 
205   EXPECT_EQ("dGhlIHNhbXBsZSBub25jZQ==", challenge);
206 
207   static const char kHandshakeResponseHeader[] =
208       "HTTP/1.1 101 Switching Protocols\r\n"
209       "Sec-WebSocket-Protocol: sample\r\n";
210 
211   std::string raw_headers =
212       HttpUtil::AssembleRawHeaders(kHandshakeResponseHeader,
213                                    strlen(kHandshakeResponseHeader));
214   HttpResponseInfo response_info;
215   response_info.headers = new HttpResponseHeaders(raw_headers);
216 
217   EXPECT_TRUE(StartsWithASCII(response_info.headers->GetStatusLine(),
218                               "HTTP/1.1 101 ", false));
219   EXPECT_FALSE(response_info.headers->HasHeader("Upgrade"));
220   EXPECT_FALSE(response_info.headers->HasHeader("Connection"));
221   EXPECT_FALSE(response_info.headers->HasHeader("Sec-WebSocket-Accept"));
222   EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Protocol",
223                                                     "sample"));
224 
225   WebSocketHandshakeResponseHandler response_handler;
226 
227   EXPECT_TRUE(response_handler.ParseResponseInfo(response_info, challenge));
228   EXPECT_TRUE(response_handler.HasResponse());
229 
230   static const char kHandshakeResponseExpectedMessage[] =
231       "HTTP/1.1 101 Switching Protocols\r\n"
232       "Upgrade: websocket\r\n"
233       "Connection: Upgrade\r\n"
234       "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
235       "Sec-WebSocket-Protocol: sample\r\n"
236       "\r\n";
237 
238   EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse());
239 }
240 
241 }  // namespace net
242