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 15namespace net { 16 17namespace { 18 19class WebSocketHandshakeHandlerSpdyTest 20 : public ::testing::Test, 21 public ::testing::WithParamInterface<NextProto> { 22 protected: 23 WebSocketHandshakeHandlerSpdyTest() : spdy_util_(GetParam()) {} 24 25 SpdyWebSocketTestUtil spdy_util_; 26}; 27 28INSTANTIATE_TEST_CASE_P( 29 NextProto, 30 WebSocketHandshakeHandlerSpdyTest, 31 testing::Values(kProtoDeprecatedSPDY2, 32 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4)); 33 34TEST_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 104TEST_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