Home | History | Annotate | Download | only in websockets
      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:
     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 
     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 
    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