153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/*
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * modification, are permitted provided that the following conditions are
653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * met:
753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *     * Redistributions of source code must retain the above copyright
953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * notice, this list of conditions and the following disclaimer.
1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *     * Redistributions in binary form must reproduce the above
1153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
1253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * in the documentation and/or other materials provided with the
1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * distribution.
1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * contributors may be used to endorse or promote products derived from
1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * this software without specific prior written permission.
1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "config.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/websockets/WebSocketPerMessageDeflate.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/StringHash.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <algorithm>
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <gtest/gtest.h>
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include <iterator>
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
40e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)namespace blink {
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace {
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestDeflateHelloTakeOver)
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeText;
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "Hello", 5, WebSocketFrame::Final);
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f2(opcode, "Hello", 5, WebSocketFrame::Final);
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(7u, f1.payloadLength);
5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", f1.payload, f1.payloadLength));
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.compress);
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.final);
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetDeflateBuffer();
5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f2));
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(5u, f2.payloadLength);
6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x00\x11\x00\x00", f2.payload, f2.payloadLength));
6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.compress);
6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
6453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageTest, TestDeflateHelloNoTakeOver)
6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
6753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::DoNotTakeOverContext);
6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeText;
7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "Hello", 5, WebSocketFrame::Final);
7153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f2(opcode, "Hello", 5, WebSocketFrame::Final);
7253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(7u, f1.payloadLength);
7553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", f1.payload, f1.payloadLength));
7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.compress);
7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.final);
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetDeflateBuffer();
8053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f2));
8153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(7u, f2.payloadLength);
8253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", f2.payload, f2.payloadLength));
8353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.compress);
8453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestDeflateInflateMultipleFrame)
8853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
8953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
90bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame::OpCode text = WebSocketFrame::OpCodeText;
9153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::DoNotTakeOverContext);
92bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    size_t length = 64 * 1024;
9353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::string payload;
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::string expected;
9553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::string actual;
9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::string inflated;
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Generate string by a linear congruential generator.
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    uint64_t r = 0;
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (size_t i = 0; i < length; ++i) {
10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        payload += 'a' + (r % 25);
10153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        r = (r * 12345 + 1103515245) % (static_cast<uint64_t>(1) << 31);
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
104bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame frame(text, &payload[0], payload.size(), WebSocketFrame::Final);
10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(frame));
10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(frame.final);
10753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(frame.compress);
10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    expected = std::string(frame.payload, frame.payloadLength);
10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (size_t i = 0; i < length; ++i) {
110bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        WebSocketFrame::OpCode opcode = !i ? text : WebSocketFrame::OpCodeContinuation;
11153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        c.resetDeflateBuffer();
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        WebSocketFrame frame(opcode, &payload[i], 1);
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        frame.final = (i == length - 1);
11453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT_TRUE(c.deflate(frame));
11653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT_EQ(i == length - 1, frame.final);
11753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT_EQ(!i, frame.compress);
11853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        actual += std::string(frame.payload, frame.payloadLength);
11953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(expected, actual);
12153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (size_t i = 0; i < actual.size(); ++i) {
123bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        WebSocketFrame::OpCode opcode = !i ? text : WebSocketFrame::OpCodeContinuation;
12453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        c.resetInflateBuffer();
12553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        WebSocketFrame frame(opcode, &actual[i], 1);
126bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        frame.final = (i == actual.size() - 1);
12753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        frame.compress = !i;
12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT_TRUE(c.inflate(frame));
130bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        ASSERT_EQ(i == actual.size() - 1, frame.final);
13153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        ASSERT_FALSE(frame.compress);
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        inflated += std::string(frame.payload, frame.payloadLength);
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(payload, inflated);
13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestDeflateBinary)
13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
14053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
14153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeBinary;
14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "Hello", 5, WebSocketFrame::Final);
14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
14553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(7u, f1.payloadLength);
14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", f1.payload, f1.payloadLength));
14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(opcode, f1.opCode);
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.compress);
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.final);
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestDeflateEmptyFrame)
15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
15553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
156bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f1(WebSocketFrame::OpCodeText, "Hello", 5);
157bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f2(WebSocketFrame::OpCodeContinuation, "", 0, WebSocketFrame::Final);
15853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
15953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
16053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0u, f1.payloadLength);
16153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.final);
16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.compress);
16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetDeflateBuffer();
16553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f2));
16653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(7u, f2.payloadLength);
16753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", f2.payload, f2.payloadLength));
16853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestDeflateEmptyMessages)
1735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){
1745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    WebSocketPerMessageDeflate c;
1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
176bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f1(WebSocketFrame::OpCodeText, "", 0);
177bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f2(WebSocketFrame::OpCodeContinuation, "", 0, WebSocketFrame::Final);
178bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f3(WebSocketFrame::OpCodeText, "", 0, WebSocketFrame::Final);
179bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f4(WebSocketFrame::OpCodeText, "", 0, WebSocketFrame::Final);
180bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f5(WebSocketFrame::OpCodeText, "Hello", 5, WebSocketFrame::Final);
1815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
1835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_EQ(0u, f1.payloadLength);
1845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_FALSE(f1.final);
1855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_TRUE(f1.compress);
1865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    c.resetDeflateBuffer();
1885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f2));
18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_EQ(1u, f2.payloadLength);
19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    EXPECT_EQ(0, memcmp("\x00", f2.payload, f2.payloadLength));
1915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_TRUE(f2.final);
1925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
1935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    c.resetDeflateBuffer();
1955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f3));
196bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    EXPECT_EQ(0u, f3.payloadLength);
1975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_TRUE(f3.final);
198bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    EXPECT_FALSE(f3.compress);
1995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    c.resetDeflateBuffer();
2015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f4));
202bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    EXPECT_EQ(0u, f4.payloadLength);
2035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_TRUE(f4.final);
204bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    EXPECT_FALSE(f4.compress);
2055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    c.resetDeflateBuffer();
2075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f5));
2085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_EQ(7u, f5.payloadLength);
2095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", f5.payload, f5.payloadLength));
2105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_TRUE(f5.final);
2115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    EXPECT_TRUE(f5.compress);
2125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
2135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestControlMessage)
21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
21853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeClose;
21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "Hello", 5, WebSocketFrame::Final);
22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.final);
22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.compress);
22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("Hello"), std::string(f1.payload, f1.payloadLength));
22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestDeflateControlMessageBetweenTextFrames)
22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
23153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode close = WebSocketFrame::OpCodeClose;
23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode text = WebSocketFrame::OpCodeText;
233bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame::OpCode continuation = WebSocketFrame::OpCodeContinuation;
23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(text, "Hello", 5);
23553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f2(close, "close", 5, WebSocketFrame::Final);
236bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f3(continuation, "", 0, WebSocketFrame::Final);
23753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
23853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::vector<char> compressed;
23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
24053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.final);
24153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.compress);
24253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::copy(&f1.payload[0], &f1.payload[f1.payloadLength], std::inserter(compressed, compressed.end()));
24353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
24453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetDeflateBuffer();
24553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f2));
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("close"), std::string(f2.payload, f2.payloadLength));
24953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
25053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetDeflateBuffer();
25153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f3));
25253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f3.final);
25353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f3.compress);
25453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::copy(&f3.payload[0], &f3.payload[f3.payloadLength], std::inserter(compressed, compressed.end()));
25553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
25653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(7u, compressed.size());
25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0, memcmp("\xf2\x48\xcd\xc9\xc9\x07\x00", &compressed[0], compressed.size()));
25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
26053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestInflate)
26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
26253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
26353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
26453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeText;
265bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame::OpCode continuation = WebSocketFrame::OpCodeContinuation;
26653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::string expected = "HelloHi!Hello";
26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::string actual;
26853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "\xf2\x48\xcd\xc9\xc9\x07\x00", 7, WebSocketFrame::Final | WebSocketFrame::Compress);
269bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f2(continuation, "Hi!", 3, WebSocketFrame::Final);
27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f3(opcode, "\xf2\x00\x11\x00\x00", 5, WebSocketFrame::Final | WebSocketFrame::Compress);
27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f1));
27353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(5u, f1.payloadLength);
27453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("Hello"), std::string(f1.payload, f1.payloadLength));
27553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.compress);
27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f1.final);
27753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
27853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetInflateBuffer();
27953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f2));
28053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(3u, f2.payloadLength);
28153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("Hi!"), std::string(f2.payload, f2.payloadLength));
28253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
28353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
28453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetInflateBuffer();
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f3));
28753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(5u, f3.payloadLength);
28853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("Hello"), std::string(f3.payload, f3.payloadLength));
28953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f3.compress);
29053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f3.final);
29153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
293f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestInflateMultipleBlocksOverMultipleFrames)
294f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
295f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WebSocketPerMessageDeflate c;
296f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
297f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeText;
298f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WebSocketFrame::OpCode continuation = WebSocketFrame::OpCodeContinuation;
299f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    std::string expected = "HelloHello";
300f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    std::string actual;
301f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WebSocketFrame f1(opcode, "\xf2\x48\xcd\xc9\xc9\x07\x00\x00\x00\xff\xff", 11, WebSocketFrame::Compress);
302f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WebSocketFrame f2(continuation, "\xf2\x00\x11\x00\x00", 5, WebSocketFrame::Final);
303f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
304f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f1));
305f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(f1.compress);
306f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(f1.final);
307f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    actual += std::string(f1.payload, f1.payloadLength);
308f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
309f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    c.resetInflateBuffer();
310f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f2));
311f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
312f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_TRUE(f2.final);
313f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    actual += std::string(f2.payload, f2.payloadLength);
314f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
315f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    EXPECT_EQ(expected, actual);
316f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
317f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestInflateEmptyFrame)
31953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
32153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeText;
323bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame::OpCode continuation = WebSocketFrame::OpCodeContinuation;
32453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "", 0, WebSocketFrame::Compress);
325bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    WebSocketFrame f2(continuation, "\xf2\x48\xcd\xc9\xc9\x07\x00", 7, WebSocketFrame::Final);
32653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
32753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f1));
32853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(0u, f1.payloadLength);
32953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.compress);
33053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.final);
33153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetInflateBuffer();
33353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f2));
33453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(5u, f2.payloadLength);
33553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("Hello"), std::string(f2.payload, f2.payloadLength));
33653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
33753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
33853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
33953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
34053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestInflateControlMessageBetweenTextFrames)
34153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
34253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
34353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.enable(8, WebSocketDeflater::TakeOverContext);
34453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode close = WebSocketFrame::OpCodeClose;
34553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode text = WebSocketFrame::OpCodeText;
34653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(text, "\xf2\x48", 2, WebSocketFrame::Compress);
34753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f2(close, "close", 5, WebSocketFrame::Final);
34853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f3(text, "\xcd\xc9\xc9\x07\x00", 5, WebSocketFrame::Final);
34953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
35053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::vector<char> decompressed;
35153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f1));
35253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.final);
35353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f1.compress);
35453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::copy(&f1.payload[0], &f1.payload[f1.payloadLength], std::inserter(decompressed, decompressed.end()));
35553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
35653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetInflateBuffer();
35753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f2));
35853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f2.final);
35953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f2.compress);
36053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("close"), std::string(f2.payload, f2.payloadLength));
36153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
36253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    c.resetInflateBuffer();
36353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f3));
36453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    std::copy(&f3.payload[0], &f3.payload[f3.payloadLength], std::inserter(decompressed, decompressed.end()));
36553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_TRUE(f3.final);
36653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_FALSE(f3.compress);
36753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
36853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    EXPECT_EQ(std::string("Hello"), std::string(&decompressed[0], decompressed.size()));
36953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
37053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
37153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestNotEnabled)
37253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
37353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketPerMessageDeflate c;
37453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame::OpCode opcode = WebSocketFrame::OpCodeClose;
37553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f1(opcode, "Hello", 5, WebSocketFrame::Final | WebSocketFrame::Compress);
37653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    WebSocketFrame f2(opcode, "\xf2\x48\xcd\xc9\xc9\x07\x00", 7, WebSocketFrame::Final | WebSocketFrame::Compress);
37753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
37853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // deflate and inflate return true and do nothing if it is not enabled.
37953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.deflate(f1));
38053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(f1.compress);
38153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(c.inflate(f2));
38253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT_TRUE(f2.compress);
38353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
38453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
38553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool processResponse(const HashMap<String, String>& serverParameters)
38653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
38753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return WebSocketPerMessageDeflate().createExtensionProcessor()->processResponse(serverParameters);
38853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
38953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
39053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestValidNegotiationResponse)
39153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
39253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
39353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
39453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_TRUE(processResponse(params));
39553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
39653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
39753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
398bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "15");
39953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_TRUE(processResponse(params));
40053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
40153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
40253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
403bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "8");
40453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_TRUE(processResponse(params));
40553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
40653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
40753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
408bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "15");
409bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_no_context_takeover", String());
41053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_TRUE(processResponse(params));
41153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
412521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    {
413bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_no_context_takeover should be ignored.
414521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        HashMap<String, String> params;
415bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_no_context_takeover", String());
416521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        EXPECT_TRUE(processResponse(params));
417521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
418521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    {
419bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_max_window_bits should be ignored.
420521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        HashMap<String, String> params;
421bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_max_window_bits", "15");
422521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        EXPECT_TRUE(processResponse(params));
423521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
42453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
42553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
42653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestInvalidNegotiationResponse)
42753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
42853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
42953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
43053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        params.add("method", "deflate");
43153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
43253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
43353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
43453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
43553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        params.add("foo", "");
43653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
43753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
43853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
43953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
44053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        params.add("foo", "bar");
44153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
44253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
44353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
44453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
445bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "");
44653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
44753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
44853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
44953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
450bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "16");
45153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
45253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
45353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
45453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
455bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "7");
45653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
45753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
45853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
45953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
460bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "+15");
46153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
46253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
46353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
46453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
465bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "0x9");
46653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
46753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
46853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
46953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
470bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("client_max_window_bits", "08");
47153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
47253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
47353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
474bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_no_context_takeover should be verified though it is not used.
47553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
476bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_no_context_takeover", "foo");
47753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
47853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
47953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    {
480bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_max_window_bits should be verified though it is not used.
48153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        HashMap<String, String> params;
482bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_max_window_bits", "7");
483521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        EXPECT_FALSE(processResponse(params));
484521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
485521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    {
486bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_max_window_bits should be verified though it is not used.
487521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        HashMap<String, String> params;
488bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_max_window_bits", "bar");
489521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        EXPECT_FALSE(processResponse(params));
490521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
491521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    {
492bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_max_window_bits should be verified though it is not used.
493521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        HashMap<String, String> params;
494bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_max_window_bits", "16");
495521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        EXPECT_FALSE(processResponse(params));
496521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
497521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    {
498bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Unsolicited server_max_window_bits should be verified though it is not used.
499521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        HashMap<String, String> params;
500bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        params.add("server_max_window_bits", "08");
50153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        EXPECT_FALSE(processResponse(params));
50253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
50353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
50453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
50553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)TEST(WebSocketPerMessageDeflateTest, TestNegotiationRequest)
50653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
50753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    String actual = WebSocketPerMessageDeflate().createExtensionProcessor()->handshakeString();
508bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    EXPECT_EQ(String("permessage-deflate; client_max_window_bits"), actual);
50953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
510e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
51153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} // namespace
512e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink
513