websocket_handshake_draft75_unittest.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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 <string>
6#include <vector>
7
8#include "base/scoped_ptr.h"
9#include "net/websockets/websocket_handshake_draft75.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/platform_test.h"
13
14namespace net {
15
16TEST(WebSocketHandshakeDraft75Test, Connect) {
17  const std::string kExpectedClientHandshakeMessage =
18      "GET /demo HTTP/1.1\r\n"
19      "Upgrade: WebSocket\r\n"
20      "Connection: Upgrade\r\n"
21      "Host: example.com\r\n"
22      "Origin: http://example.com\r\n"
23      "WebSocket-Protocol: sample\r\n"
24      "\r\n";
25
26  scoped_ptr<WebSocketHandshakeDraft75> handshake(
27      new WebSocketHandshakeDraft75(GURL("ws://example.com/demo"),
28                                    "http://example.com",
29                                    "ws://example.com/demo",
30                                    "sample"));
31  EXPECT_EQ(WebSocketHandshake::MODE_INCOMPLETE, handshake->mode());
32  EXPECT_EQ(kExpectedClientHandshakeMessage,
33            handshake->CreateClientHandshakeMessage());
34
35  const char kResponse[] = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
36      "Upgrade: WebSocket\r\n"
37      "Connection: Upgrade\r\n"
38      "WebSocket-Origin: http://example.com\r\n"
39      "WebSocket-Location: ws://example.com/demo\r\n"
40      "WebSocket-Protocol: sample\r\n"
41      "\r\n";
42
43  EXPECT_EQ(WebSocketHandshake::MODE_INCOMPLETE, handshake->mode());
44  // too short
45  EXPECT_EQ(-1, handshake->ReadServerHandshake(kResponse, 16));
46  EXPECT_EQ(WebSocketHandshake::MODE_INCOMPLETE, handshake->mode());
47  // only status line
48  EXPECT_EQ(-1, handshake->ReadServerHandshake(
49      kResponse,
50      WebSocketHandshakeDraft75::kServerHandshakeHeaderLength));
51  EXPECT_EQ(WebSocketHandshake::MODE_NORMAL, handshake->mode());
52  // by upgrade header
53  EXPECT_EQ(-1, handshake->ReadServerHandshake(
54      kResponse,
55      WebSocketHandshakeDraft75::kServerHandshakeHeaderLength +
56      WebSocketHandshakeDraft75::kUpgradeHeaderLength));
57  EXPECT_EQ(WebSocketHandshake::MODE_NORMAL, handshake->mode());
58  // by connection header
59  EXPECT_EQ(-1, handshake->ReadServerHandshake(
60      kResponse,
61      WebSocketHandshakeDraft75::kServerHandshakeHeaderLength +
62      WebSocketHandshakeDraft75::kUpgradeHeaderLength +
63      WebSocketHandshakeDraft75::kConnectionHeaderLength));
64  EXPECT_EQ(WebSocketHandshake::MODE_NORMAL, handshake->mode());
65
66  EXPECT_EQ(-1, handshake->ReadServerHandshake(
67      kResponse, sizeof(kResponse) - 2));
68  EXPECT_EQ(WebSocketHandshake::MODE_NORMAL, handshake->mode());
69
70  int handshake_length = strlen(kResponse);
71  EXPECT_EQ(handshake_length, handshake->ReadServerHandshake(
72      kResponse, sizeof(kResponse) - 1));  // -1 for terminating \0
73  EXPECT_EQ(WebSocketHandshake::MODE_CONNECTED, handshake->mode());
74}
75
76TEST(WebSocketHandshakeDraft75Test, ServerSentData) {
77  const std::string kExpectedClientHandshakeMessage =
78      "GET /demo HTTP/1.1\r\n"
79      "Upgrade: WebSocket\r\n"
80      "Connection: Upgrade\r\n"
81      "Host: example.com\r\n"
82      "Origin: http://example.com\r\n"
83      "WebSocket-Protocol: sample\r\n"
84      "\r\n";
85  scoped_ptr<WebSocketHandshakeDraft75> handshake(
86      new WebSocketHandshakeDraft75(GURL("ws://example.com/demo"),
87                                    "http://example.com",
88                                    "ws://example.com/demo",
89                                    "sample"));
90  EXPECT_EQ(WebSocketHandshake::MODE_INCOMPLETE, handshake->mode());
91  EXPECT_EQ(kExpectedClientHandshakeMessage,
92            handshake->CreateClientHandshakeMessage());
93
94  const char kResponse[] ="HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
95      "Upgrade: WebSocket\r\n"
96      "Connection: Upgrade\r\n"
97      "WebSocket-Origin: http://example.com\r\n"
98      "WebSocket-Location: ws://example.com/demo\r\n"
99      "WebSocket-Protocol: sample\r\n"
100      "\r\n"
101      "\0Hello\xff";
102
103  int handshake_length = strlen(kResponse);
104  EXPECT_EQ(handshake_length, handshake->ReadServerHandshake(
105      kResponse, sizeof(kResponse) - 1));  // -1 for terminating \0
106  EXPECT_EQ(WebSocketHandshake::MODE_CONNECTED, handshake->mode());
107}
108
109TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_Simple) {
110  scoped_ptr<WebSocketHandshakeDraft75> handshake(
111      new WebSocketHandshakeDraft75(GURL("ws://example.com/demo"),
112                                    "http://example.com",
113                                    "ws://example.com/demo",
114                                    "sample"));
115  EXPECT_EQ("GET /demo HTTP/1.1\r\n"
116            "Upgrade: WebSocket\r\n"
117            "Connection: Upgrade\r\n"
118            "Host: example.com\r\n"
119            "Origin: http://example.com\r\n"
120            "WebSocket-Protocol: sample\r\n"
121            "\r\n",
122            handshake->CreateClientHandshakeMessage());
123}
124
125TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_PathAndQuery) {
126  scoped_ptr<WebSocketHandshakeDraft75> handshake(
127      new WebSocketHandshakeDraft75(GURL("ws://example.com/Test?q=xxx&p=%20"),
128                                    "http://example.com",
129                                    "ws://example.com/demo",
130                                    "sample"));
131  // Path and query should be preserved as-is.
132  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
133              testing::HasSubstr("GET /Test?q=xxx&p=%20 HTTP/1.1\r\n"));
134}
135
136TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_Host) {
137  scoped_ptr<WebSocketHandshakeDraft75> handshake(
138      new WebSocketHandshakeDraft75(GURL("ws://Example.Com/demo"),
139                                    "http://Example.Com",
140                                    "ws://Example.Com/demo",
141                                    "sample"));
142  // Host should be lowercased
143  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
144              testing::HasSubstr("Host: example.com\r\n"));
145  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
146              testing::HasSubstr("Origin: http://example.com\r\n"));
147}
148
149TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_TrimPort80) {
150  scoped_ptr<WebSocketHandshakeDraft75> handshake(
151      new WebSocketHandshakeDraft75(GURL("ws://example.com:80/demo"),
152                                    "http://example.com",
153                                    "ws://example.com/demo",
154                                    "sample"));
155  // :80 should be trimmed as it's the default port for ws://.
156  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
157              testing::HasSubstr("Host: example.com\r\n"));
158}
159
160TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_TrimPort443) {
161  scoped_ptr<WebSocketHandshakeDraft75> handshake(
162      new WebSocketHandshakeDraft75(GURL("wss://example.com:443/demo"),
163                                    "http://example.com",
164                                    "wss://example.com/demo",
165                                    "sample"));
166  // :443 should be trimmed as it's the default port for wss://.
167  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
168              testing::HasSubstr("Host: example.com\r\n"));
169}
170
171TEST(WebSocketHandshakeDraft75Test,
172     CreateClientHandshakeMessage_NonDefaultPortForWs) {
173  scoped_ptr<WebSocketHandshakeDraft75> handshake(
174      new WebSocketHandshakeDraft75(GURL("ws://example.com:8080/demo"),
175                                    "http://example.com",
176                                    "wss://example.com/demo",
177                                    "sample"));
178  // :8080 should be preserved as it's not the default port for ws://.
179  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
180              testing::HasSubstr("Host: example.com:8080\r\n"));
181}
182
183TEST(WebSocketHandshakeDraft75Test,
184     CreateClientHandshakeMessage_NonDefaultPortForWss) {
185  scoped_ptr<WebSocketHandshakeDraft75> handshake(
186      new WebSocketHandshakeDraft75(GURL("wss://example.com:4443/demo"),
187                                    "http://example.com",
188                                    "wss://example.com/demo",
189                                    "sample"));
190  // :4443 should be preserved as it's not the default port for wss://.
191  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
192              testing::HasSubstr("Host: example.com:4443\r\n"));
193}
194
195TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_WsBut443) {
196  scoped_ptr<WebSocketHandshakeDraft75> handshake(
197      new WebSocketHandshakeDraft75(GURL("ws://example.com:443/demo"),
198                                    "http://example.com",
199                                    "ws://example.com/demo",
200                                    "sample"));
201  // :443 should be preserved as it's not the default port for ws://.
202  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
203              testing::HasSubstr("Host: example.com:443\r\n"));
204}
205
206TEST(WebSocketHandshakeDraft75Test, CreateClientHandshakeMessage_WssBut80) {
207  scoped_ptr<WebSocketHandshakeDraft75> handshake(
208      new WebSocketHandshakeDraft75(GURL("wss://example.com:80/demo"),
209                                    "http://example.com",
210                                    "wss://example.com/demo",
211                                    "sample"));
212  // :80 should be preserved as it's not the default port for wss://.
213  EXPECT_THAT(handshake->CreateClientHandshakeMessage(),
214              testing::HasSubstr("Host: example.com:80\r\n"));
215}
216
217}  // namespace net
218