15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iostream>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_frame_builder.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_utils.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::max;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::numeric_limits;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kMaxDecompressedSize = 1024;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(akalin): Make sure expectations on mocks are set before mock
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// functions are called, as interleaving expectations and calls is
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// undefined.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockVisitor : public SpdyFramerVisitorInterface {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnError, void(SpdyFramer* framer));
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId stream_id,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       size_t length,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       bool fin));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const char* data,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       size_t len,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       bool fin));
43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id,
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                              const char* header_data,
45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                              size_t len));
46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MOCK_METHOD6(OnSynStream, void(SpdyStreamId stream_id,
47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 SpdyStreamId associated_stream_id,
48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 SpdyPriority priority,
49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 uint8 slot,
50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 bool fin,
51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 bool unidirectional));
52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin));
53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id,
54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                 SpdyRstStreamStatus status));
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(OnSettings, void(bool clear_persisted));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(OnPing, void(uint32 unique_id));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SpdyGoAwayStatus status));
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MOCK_METHOD2(OnHeaders, void(SpdyStreamId stream_id, bool fin));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId stream_id,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    uint32 delta_window_size));
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  MOCK_METHOD2(OnCredentialFrameData, bool(const char* credential_data,
64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                           size_t len));
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id));
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MOCK_METHOD2(OnPushPromise, void(SpdyStreamId stream_id,
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   SpdyStreamId promised_stream_id));
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass MockDebugVisitor : public SpdyFramerDebugVisitorInterface {
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MOCK_METHOD4(OnSendCompressedFrame, void(SpdyStreamId stream_id,
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           SpdyFrameType type,
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           size_t payload_len,
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                           size_t frame_len));
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MOCK_METHOD3(OnReceiveCompressedFrame, void(SpdyStreamId stream_id,
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                              SpdyFrameType type,
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                              size_t frame_len));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyFramerTestUtil {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decompress a single frame using the decompression context held by
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the SpdyFramer.  The implemention is meant for use only in tests
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and will CHECK fail if the input is anything other than a single,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // well-formed compressed frame.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a new decompressed SpdyFrame.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<class SpdyFrameType> static SpdyFrame* DecompressFrame(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyFramer* framer, const SpdyFrameType& frame) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DecompressionVisitor visitor(framer->protocol_version());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer->set_visitor(&visitor);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK_EQ(frame.size(), framer->ProcessInput(frame.data(), frame.size()));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(SpdyFramer::SPDY_RESET, framer->state());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer->set_visitor(NULL);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* buffer = visitor.ReleaseBuffer();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(buffer != NULL);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFrame* decompressed_frame = new SpdyFrame(buffer, visitor.size(), true);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (framer->protocol_version() == 4) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetFrameLength(decompressed_frame,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     visitor.size(),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     framer->protocol_version());
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetFrameLength(decompressed_frame,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     visitor.size() - framer->GetControlFrameHeaderSize(),
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     framer->protocol_version());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return decompressed_frame;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DecompressionVisitor : public SpdyFramerVisitorInterface {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    explicit DecompressionVisitor(SpdyMajorVersion version)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : version_(version), size_(0), finished_(false) {}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void ResetBuffer() {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(buffer_.get() == NULL);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK_EQ(0u, size_);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(!finished_);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_.reset(new char[kMaxDecompressedSize]);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnError(SpdyFramer* framer) OVERRIDE { LOG(FATAL); }
126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnDataFrameHeader(SpdyStreamId stream_id,
127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                   size_t length,
128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                   bool fin) OVERRIDE {
129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL) << "Unexpected data frame header";
130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnStreamFrameData(SpdyStreamId stream_id,
132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                   const char* data,
133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                   size_t len,
134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                   bool fin) OVERRIDE {
135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL);
136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                          const char* header_data,
140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                          size_t len) OVERRIDE {
141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      CHECK(buffer_.get() != NULL);
142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      CHECK_GE(kMaxDecompressedSize, size_ + len);
143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      CHECK(!finished_);
144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (len != 0) {
145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        memcpy(buffer_.get() + size_, header_data, len);
146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        size_ += len;
147ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      } else {
148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        // Done.
149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        finished_ = true;
150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      }
151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return true;
152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnSynStream(SpdyStreamId stream_id,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SpdyStreamId associated_stream_id,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SpdyPriority priority,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             uint8 slot,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool fin,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             bool unidirectional) OVERRIDE {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyFramer framer(version_);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.set_enable_compression(false);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SpdyHeaderBlock null_headers;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int flags = CONTROL_FLAG_NONE;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (fin) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        flags &= CONTROL_FLAG_FIN;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (unidirectional) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        flags &= CONTROL_FLAG_UNIDIRECTIONAL;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<SpdyFrame> frame(
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          framer.CreateSynStream(stream_id,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 associated_stream_id,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 priority,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 slot,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 static_cast<SpdyControlFlags>(flags),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 false,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &null_headers));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResetBuffer();
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(buffer_.get(), frame->data(), framer.GetSynStreamMinimumSize());
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_ += framer.GetSynStreamMinimumSize();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyFramer framer(version_);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.set_enable_compression(false);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SpdyHeaderBlock null_headers;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int flags = CONTROL_FLAG_NONE;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (fin) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        flags &= CONTROL_FLAG_FIN;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<SpdyFrame> frame(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          framer.CreateHeaders(stream_id,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               static_cast<SpdyControlFlags>(flags),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &null_headers));
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResetBuffer();
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(buffer_.get(), frame->data(), framer.GetHeadersMinimumSize());
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_ += framer.GetSynStreamMinimumSize();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnRstStream(SpdyStreamId stream_id,
202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             SpdyRstStreamStatus status) OVERRIDE {
203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL);
204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnSetting(SpdySettingsIds id,
206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           uint8 flags,
207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           uint32 value) OVERRIDE {
208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL);
209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnPing(uint32 unique_id) OVERRIDE {
211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL);
212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                          SpdyGoAwayStatus status) OVERRIDE {
215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL);
216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyFramer framer(version_);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.set_enable_compression(false);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SpdyHeaderBlock null_headers;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int flags = CONTROL_FLAG_NONE;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (fin) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        flags &= CONTROL_FLAG_FIN;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<SpdyFrame> frame(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          framer.CreateHeaders(stream_id,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               static_cast<SpdyControlFlags>(flags),
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &null_headers));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResetBuffer();
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memcpy(buffer_.get(), frame->data(), framer.GetHeadersMinimumSize());
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      size_ += framer.GetHeadersMinimumSize();
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) {
237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL);
238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    virtual bool OnCredentialFrameData(const char* /*credential_data*/,
240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                       size_t /*len*/) OVERRIDE {
241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      LOG(FATAL) << "Unexpected CREDENTIAL Frame";
242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return false;
243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual void OnPushPromise(SpdyStreamId stream_id,
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               SpdyStreamId promised_stream_id) OVERRIDE {
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      SpdyFramer framer(version_);
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      framer.set_enable_compression(false);
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const SpdyHeaderBlock null_headers;
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scoped_ptr<SpdyFrame> frame(
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          framer.CreatePushPromise(stream_id, promised_stream_id,
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   &null_headers));
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ResetBuffer();
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      memcpy(buffer_.get(), frame->data(), framer.GetPushPromiseMinimumSize());
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      size_ += framer.GetPushPromiseMinimumSize();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    char* ReleaseBuffer() {
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      CHECK(finished_);
260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return buffer_.release();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnWindowUpdate(SpdyStreamId stream_id,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                uint32 delta_window_size) OVERRIDE {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(FATAL);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t size() const {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(finished_);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return size_;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdyMajorVersion version_;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<char[]> buffer_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t size_;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool finished_;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestSpdyVisitor : public SpdyFramerVisitorInterface,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        public SpdyFramerDebugVisitorInterface {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kDefaultCredentialBufferSize = 16 * 1024;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  explicit TestSpdyVisitor(SpdyMajorVersion version)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : framer_(version),
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      use_compression_(false),
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_count_(0),
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syn_frame_count_(0),
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      syn_reply_frame_count_(0),
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      headers_frame_count_(0),
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      goaway_count_(0),
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      setting_count_(0),
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_window_update_stream_(0),
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_window_update_delta_(0),
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      last_push_promise_stream_(0),
3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      last_push_promise_promised_stream_(0),
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_bytes_(0),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fin_frame_count_(0),
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fin_flag_count_(0),
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zero_length_data_frame_count_(0),
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      control_frame_header_data_count_(0),
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zero_length_control_frame_header_data_count_(0),
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_frame_count_(0),
3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      last_payload_len_(0),
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      last_frame_len_(0),
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header_buffer_(new char[kDefaultHeaderBufferSize]),
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header_buffer_length_(0),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header_buffer_size_(kDefaultHeaderBufferSize),
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header_stream_id_(-1),
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      header_control_type_(DATA),
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header_buffer_valid_(false),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      credential_buffer_(new char[kDefaultCredentialBufferSize]),
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      credential_buffer_length_(0),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      credential_buffer_size_(kDefaultCredentialBufferSize) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnError(SpdyFramer* f) OVERRIDE {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "SpdyFramer Error: "
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << SpdyFramer::ErrorCodeToString(f->error_code());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_count_++;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 size_t length,
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) OVERRIDE {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_frame_count_++;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    header_stream_id_ = stream_id;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnStreamFrameData(SpdyStreamId stream_id,
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const char* data,
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 size_t len,
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) OVERRIDE {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(header_stream_id_, stream_id);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len == 0)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++zero_length_data_frame_count_;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_bytes_ += len;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::cerr << "OnStreamFrameData(" << stream_id << ", \"";
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len > 0) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t i = 0 ; i < len; ++i) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::cerr << std::hex << (0xFF & (unsigned int)data[i]) << std::dec;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::cerr << "\", " << len << ")\n";
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                        const char* header_data,
358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                        size_t len) OVERRIDE {
359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ++control_frame_header_data_count_;
360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CHECK_EQ(header_stream_id_, stream_id);
361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (len == 0) {
362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      ++zero_length_control_frame_header_data_count_;
363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      // Indicates end-of-header-block.
364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      CHECK(header_buffer_valid_);
365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      size_t parsed_length = framer_.ParseHeaderBlockInBuffer(
366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          header_buffer_.get(), header_buffer_length_, &headers_);
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      DCHECK_EQ(header_buffer_length_, parsed_length);
368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return true;
369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const size_t available = header_buffer_size_ - header_buffer_length_;
371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (len > available) {
372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      header_buffer_valid_ = false;
373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return false;
374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    memcpy(header_buffer_.get() + header_buffer_length_, header_data, len);
376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    header_buffer_length_ += len;
377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return true;
378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSynStream(SpdyStreamId stream_id,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyStreamId associated_stream_id,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyPriority priority,
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           uint8 credential_slot,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool fin,
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           bool unidirectional) OVERRIDE {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syn_frame_count_++;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitHeaderStreaming(SYN_STREAM, stream_id);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fin) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fin_flag_count_++;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    syn_reply_frame_count_++;
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    InitHeaderStreaming(SYN_REPLY, stream_id);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fin) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fin_flag_count_++;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void OnRstStream(SpdyStreamId stream_id,
402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           SpdyRstStreamStatus status) OVERRIDE {
403ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    fin_frame_count_++;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnSetting(SpdySettingsIds id,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         uint8 flags,
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         uint32 value) OVERRIDE {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setting_count_++;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnPing(uint32 unique_id) OVERRIDE {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(FATAL);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        SpdyGoAwayStatus status) OVERRIDE {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goaway_count_++;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
421ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE {
422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    headers_frame_count_++;
423ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    InitHeaderStreaming(HEADERS, stream_id);
424ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (fin) {
425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      fin_flag_count_++;
426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
428ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWindowUpdate(SpdyStreamId stream_id,
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32 delta_window_size) OVERRIDE {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_window_update_stream_ = stream_id;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_window_update_delta_ = delta_window_size;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool OnCredentialFrameData(const char* credential_data,
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     size_t len) OVERRIDE {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len == 0) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!framer_.ParseCredentialData(credential_buffer_.get(),
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       credential_buffer_length_,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &credential_)) {
441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        LOG(INFO) << "Error parsing credential data.";
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++error_count_;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t available =
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        credential_buffer_size_ - credential_buffer_length_;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len > available) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(credential_buffer_.get() + credential_buffer_length_,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           credential_data, len);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential_buffer_length_ += len;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void OnPushPromise(SpdyStreamId stream_id,
458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             SpdyStreamId promised_stream_id) OVERRIDE {
459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    InitHeaderStreaming(PUSH_PROMISE, stream_id);
460ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    last_push_promise_stream_ = stream_id;
461ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    last_push_promise_promised_stream_ = promised_stream_id;
462ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void OnSendCompressedFrame(SpdyStreamId stream_id,
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     SpdyFrameType type,
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     size_t payload_len,
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     size_t frame_len) OVERRIDE {
4687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    last_payload_len_ = payload_len;
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    last_frame_len_ = frame_len;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id,
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                        SpdyFrameType type,
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                        size_t frame_len) OVERRIDE {
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    last_frame_len_ = frame_len;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convenience function which runs a framer simulation with particular input.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SimulateInFramer(const unsigned char* input, size_t size) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer_.set_enable_compression(use_compression_);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer_.set_visitor(this);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t input_remaining = size;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* input_ptr = reinterpret_cast<const char*>(input);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (input_remaining > 0 &&
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // To make the tests more interesting, we feed random (amd small) chunks
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // into the framer.  This simulates getting strange-sized reads from
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the socket.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const size_t kMaxReadSize = 32;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t bytes_read =
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (rand() % min(input_remaining, kMaxReadSize)) + 1;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t bytes_processed = framer_.ProcessInput(input_ptr, bytes_read);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      input_remaining -= bytes_processed;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      input_ptr += bytes_processed;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void InitHeaderStreaming(SpdyFrameType header_control_type,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyStreamId stream_id) {
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_GE(header_control_type, FIRST_CONTROL_TYPE);
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_LE(header_control_type, LAST_CONTROL_TYPE);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(header_buffer_.get(), 0, header_buffer_size_);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_buffer_length_ = 0;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_stream_id_ = stream_id;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_control_type_ = header_control_type;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_buffer_valid_ = true;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override the default buffer size (16K). Call before using the framer!
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_header_buffer_size(size_t header_buffer_size) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_buffer_size_ = header_buffer_size;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_buffer_.reset(new char[header_buffer_size]);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t header_data_chunk_max_size() {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SpdyFramer::kHeaderDataChunkMaxSize;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer_;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool use_compression_;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Counters from the visitor callbacks.
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_count_;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int syn_frame_count_;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int syn_reply_frame_count_;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int headers_frame_count_;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int goaway_count_;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int setting_count_;
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyStreamId last_window_update_stream_;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 last_window_update_delta_;
5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyStreamId last_push_promise_stream_;
5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyStreamId last_push_promise_promised_stream_;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data_bytes_;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fin_frame_count_;  // The count of RST_STREAM type frames received.
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fin_flag_count_;  // The count of frames with the FIN flag set.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int zero_length_data_frame_count_;  // The count of zero-length data frames.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int control_frame_header_data_count_;  // The count of chunks received.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The count of zero-length control frame header data chunks received.
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int zero_length_control_frame_header_data_count_;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data_frame_count_;
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t last_payload_len_;
5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t last_frame_len_;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Header block streaming state:
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> header_buffer_;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t header_buffer_length_;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t header_buffer_size_;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyStreamId header_stream_id_;
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdyFrameType header_control_type_;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool header_buffer_valid_;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers_;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<char[]> credential_buffer_;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t credential_buffer_length_;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t credential_buffer_size_;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyCredential credential_;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Retrieves serialized headers from SYN_STREAM frame.
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Does not check that the given frame is a SYN_STREAM.
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::StringPiece GetSerializedHeaders(const SpdyFrame* frame,
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const SpdyFramer& framer) {
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::StringPiece(frame->data() + framer.GetSynStreamMinimumSize(),
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           frame->size() - framer.GetSynStreamMinimumSize());
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::test::SetFrameLength;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::test::SetFrameFlags;
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::test::CompareCharArraysWithHexError;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::test::SpdyFramerTestUtil;
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::test::TestSpdyVisitor;
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::test::GetSerializedHeaders;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class SpdyFramerTest : public ::testing::TestWithParam<SpdyMajorVersion> {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    spdy_version_ = GetParam();
58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    spdy_version_ch_ = static_cast<unsigned char>(spdy_version_);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CompareFrame(const string& description,
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const SpdyFrame& actual_frame,
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const unsigned char* expected,
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const int expected_len) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char* actual =
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<const unsigned char*>(actual_frame.data());
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompareCharArraysWithHexError(
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        description, actual, actual_frame.size(), expected, expected_len);
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CompareFrames(const string& description,
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const SpdyFrame& expected_frame,
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const SpdyFrame& actual_frame) {
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompareCharArraysWithHexError(
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        description,
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reinterpret_cast<const unsigned char*>(expected_frame.data()),
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        expected_frame.size(),
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reinterpret_cast<const unsigned char*>(actual_frame.data()),
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        actual_frame.size());
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the two header blocks have equivalent content.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CompareHeaderBlocks(const SpdyHeaderBlock* expected,
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const SpdyHeaderBlock* actual) {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected->size() != actual->size()) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Expected " << expected->size() << " headers; actually got "
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << actual->size() << ".";
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (SpdyHeaderBlock::const_iterator it = expected->begin();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != expected->end();
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++it) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyHeaderBlock::const_iterator it2 = actual->find(it->first);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it2 == actual->end()) {
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Expected header name '" << it->first << "'.";
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it->second.compare(it2->second) != 0) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Expected header named '" << it->first
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << "' to have a value of '" << it->second
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << "'. The actual value received was '" << it2->second
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << "'.";
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddSpdySettingFromWireFormat(SettingsMap* settings,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    uint32 key,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    uint32 value) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SettingsFlagsAndId flags_and_id =
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SettingsFlagsAndId::FromWireFormat(spdy_version_, key);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdySettingsIds id = static_cast<SpdySettingsIds>(flags_and_id.id());
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdySettingsFlags flags =
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<SpdySettingsFlags>(flags_and_id.flags());
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(settings->find(id) == settings->end());
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    settings->insert(std::make_pair(id, SettingsFlagsAndValue(flags, value)));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsSpdy2() { return spdy_version_ == SPDY2; }
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsSpdy3() { return spdy_version_ == SPDY3; }
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsSpdy4() { return spdy_version_ == SPDY4; }
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Version of SPDY protocol to be used.
65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdyMajorVersion spdy_version_;
65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  unsigned char spdy_version_ch_;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// All tests are run with 3 different SPDY versions: SPDY/2, SPDY/3, SPDY/4.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(SpdyFramerTests,
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SpdyFramerTest,
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        ::testing::Values(SPDY2, SPDY3, SPDY4));
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we can encode and decode a SpdyHeaderBlock in serialized form.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["alpha"] = "beta";
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["gamma"] = "charlie";
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Encode the header block into a SynStream frame.
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> frame(
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,  // stream id
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // associated stream id
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,  // priority
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // credential slot
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false,  // compress
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(frame.get() != NULL);
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringPiece serialized_headers =
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSerializedHeaders(frame.get(), framer);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock new_headers;
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              serialized_headers.size(),
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              &new_headers));
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(headers.size(), new_headers.size());
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(headers["alpha"], new_headers["alpha"]);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(headers["gamma"], new_headers["gamma"]);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if there's not a full frame, we fail to parse it.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["alpha"] = "beta";
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["gamma"] = "charlie";
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Encode the header block into a SynStream frame.
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> frame(
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,  // stream id
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // associated stream id
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,  // priority
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // credential slot
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false,  // compress
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(frame.get() != NULL);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringPiece serialized_headers =
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSerializedHeaders(frame.get(), framer);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock new_headers;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               serialized_headers.size() - 2,
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               &new_headers));
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, OutOfOrderHeaders) {
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Frame builder with plentiful buffer size.
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrameBuilder frame(1024);
72590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (spdy_version_ < 4) {
72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteUInt32(3);  // stream_id
72890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
72990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteFramePrefix(framer, SYN_STREAM, CONTROL_FLAG_NONE, 3);
73090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame.WriteUInt32(0);  // Associated stream id
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame.WriteUInt16(0);  // Priority.
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteUInt16(2);  // Number of headers.
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("gamma");
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("gamma");
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("alpha");
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("alpha");
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteUInt32(2);  // Number of headers.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("gamma");
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("gamma");
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("alpha");
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("alpha");
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // write the length
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame.RewriteLength(framer);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock new_headers;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(frame.take());
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringPiece serialized_headers =
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSerializedHeaders(control_frame.get(), framer);
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              serialized_headers.size(),
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              &new_headers));
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
760ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that if we receive a SYN_STREAM with stream ID zero, we signal an error
761ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// (but don't crash).
762ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdyFramerTest, SynStreamWithStreamIdZero) {
763ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  testing::StrictMock<net::test::MockVisitor> visitor;
764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyFramer framer(spdy_version_);
765ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  framer.set_visitor(&visitor);
766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
767ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyHeaderBlock headers;
768ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  headers["alpha"] = "beta";
769ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(
770ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      framer.CreateSynStream(0,  // stream id
771ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             0,  // associated stream id
772ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             1,  // priority
773ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             0,  // credential slot
774ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             CONTROL_FLAG_NONE,
775ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             true,  // compress
776ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             &headers));
777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(frame.get() != NULL);
778ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // We shouldn't have to read the whole frame before we signal an error.
780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
782ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(framer.HasError());
783a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
784a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that if we receive a SYN_REPLY with stream ID zero, we signal an error
788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// (but don't crash).
789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdyFramerTest, SynReplyWithStreamIdZero) {
790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  testing::StrictMock<net::test::MockVisitor> visitor;
791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyFramer framer(spdy_version_);
792ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  framer.set_visitor(&visitor);
793ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyHeaderBlock headers;
795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  headers["alpha"] = "beta";
796ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(
797ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      framer.CreateSynReply(0,  // stream id
798ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                            CONTROL_FLAG_NONE,
799ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                            true,  // compress
800ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                            &headers));
801ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(frame.get() != NULL);
802ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
803ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // We shouldn't have to read the whole frame before we signal an error.
804ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
805ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
806ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(framer.HasError());
807a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
808a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
809ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
810ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
811ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that if we receive a HEADERS with stream ID zero, we signal an error
812ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// (but don't crash).
813ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdyFramerTest, HeadersWithStreamIdZero) {
814ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  testing::StrictMock<net::test::MockVisitor> visitor;
815ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyFramer framer(spdy_version_);
816ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  framer.set_visitor(&visitor);
817ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
818ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyHeaderBlock headers;
819ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  headers["alpha"] = "beta";
820ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(
821ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      framer.CreateHeaders(0,  // stream id
822ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           CONTROL_FLAG_NONE,
823ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           true,  // compress
824ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                           &headers));
825ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(frame.get() != NULL);
826ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
827ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // We shouldn't have to read the whole frame before we signal an error.
828ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
829ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
830ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(framer.HasError());
831a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
832a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
833ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
834ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
835ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that if we receive a PUSH_PROMISE with stream ID zero, we signal an
836ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// error (but don't crash).
837ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) {
838ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (spdy_version_ < SPDY4) {
839ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
840ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
841ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
842ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  testing::StrictMock<net::test::MockVisitor> visitor;
843ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyFramer framer(spdy_version_);
844ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  framer.set_visitor(&visitor);
845ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
846ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyHeaderBlock headers;
847ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  headers["alpha"] = "beta";
848ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(
849ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      framer.CreatePushPromise(0,  // stream id
850ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               4,  // promised stream id
851ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               &headers));
852ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(frame.get() != NULL);
853ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
854ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // We shouldn't have to read the whole frame before we signal an error.
855ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
856ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
857ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(framer.HasError());
858a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
859a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
860ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
861ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
862ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that if we receive a PUSH_PROMISE with promised stream ID zero, we
863ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// signal an error (but don't crash).
864ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) {
865ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (spdy_version_ < SPDY4) {
866ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
867ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
868ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
869ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  testing::StrictMock<net::test::MockVisitor> visitor;
870ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyFramer framer(spdy_version_);
871ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  framer.set_visitor(&visitor);
872ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
873ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyHeaderBlock headers;
874ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  headers["alpha"] = "beta";
875ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(
876ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      framer.CreatePushPromise(3,  // stream id
877ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               0,  // promised stream id
878ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               &headers));
879ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(frame.get() != NULL);
880ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
881ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // We shouldn't have to read the whole frame before we signal an error.
882ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
883ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
884ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(framer.HasError());
885a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
886a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
887ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
888ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateCredential) {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "CREDENTIAL frame";
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x0A,
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x33,
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 0x00, 0x00,
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x05, 'p',  'r',
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  'f',  0x00,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x06, 'a',
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ' ',  'c',  'e',  'r',
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      't',  0x00, 0x00, 0x00,
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0C, 'a',  'n',  'o',
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      't',  'h',  'e',  'r',
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ' ',  'c',  'e',  'r',
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  0x00, 0x00, 0x00,
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0A, 'f',  'i',  'n',
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'a',  'l',  ' ',  'c',
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'e',  'r',  't',
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
91290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x3b, 0x0A, 0x00,
91390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 0x00, 0x00,
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x05, 'p',  'r',
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  'f',  0x00,
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x06, 'a',
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ' ',  'c',  'e',  'r',
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  0x00, 0x00, 0x00,
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0C, 'a',  'n',  'o',
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  'h',  'e',  'r',
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ' ',  'c',  'e',  'r',
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  0x00, 0x00, 0x00,
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0A, 'f',  'i',  'n',
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'a',  'l',  ' ',  'c',
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'e',  'r',  't',
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyCredential credential;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.slot = 3;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.proof = "proof";
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.certs.push_back("a cert");
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.certs.push_back("another cert");
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.certs.push_back("final cert");
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ParseCredentialFrameData) {
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
94890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x0A,
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x33,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 0x00, 0x00,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x05, 'p',  'r',
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  'f',  0x00,
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x06, 'a',
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ' ',  'c',  'e',  'r',
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      't',  0x00, 0x00, 0x00,
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0C, 'a',  'n',  'o',
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      't',  'h',  'e',  'r',
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ' ',  'c',  'e',  'r',
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      't',  0x00,  0x00, 0x00,
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0A, 'f',  'i',  'n',
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'a',  'l',  ' ',  'c',
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'e',  'r',  't',
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x37, 0x0A, 0x00,
96690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 0x00, 0x00,
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x05, 'p',  'r',
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  'f',  0x00,
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x06, 'a',
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ' ',  'c',  'e',  'r',
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  0x00, 0x00, 0x00,
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0C, 'a',  'n',  'o',
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  'h',  'e',  'r',
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ' ',  'c',  'e',  'r',
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      't',  0x00,  0x00, 0x00,
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0A, 'f',  'i',  'n',
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'a',  'l',  ' ',  'c',
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'e',  'r',  't',
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyCredential credential;
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(SpdyFramer::ParseCredentialData(
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<const char*>(kV4FrameData) +
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              framer.GetControlFrameHeaderSize(),
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          arraysize(kV4FrameData) - framer.GetControlFrameHeaderSize(),
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &credential));
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(SpdyFramer::ParseCredentialData(
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          reinterpret_cast<const char*>(kV3FrameData) +
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              framer.GetControlFrameHeaderSize(),
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          arraysize(kV3FrameData) - framer.GetControlFrameHeaderSize(),
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &credential));
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3u, credential.slot);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("proof", credential.proof);
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("a cert", credential.certs.front());
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.certs.erase(credential.certs.begin());
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("another cert", credential.certs.front());
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.certs.erase(credential.certs.begin());
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("final cert", credential.certs.front());
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    credential.certs.erase(credential.certs.begin());
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(credential.certs.empty());
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, DuplicateHeader) {
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Frame builder with plentiful buffer size.
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrameBuilder frame(1024);
101290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (spdy_version_ < 4) {
101390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
101490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteUInt32(3);  // stream_id
101590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
101690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteFramePrefix(framer, SYN_STREAM, CONTROL_FLAG_NONE, 3);
101790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame.WriteUInt32(0);  // associated stream id
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame.WriteUInt16(0);  // Priority.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteUInt16(2);  // Number of headers.
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("name");
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("value1");
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("name");
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("value2");
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteUInt32(2);  // Number of headers.
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("name");
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("value1");
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("name");
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("value2");
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // write the length
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame.RewriteLength(framer);
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock new_headers;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(false);
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(frame.take());
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringPiece serialized_headers =
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSerializedHeaders(control_frame.get(), framer);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should fail because duplicate headers are verboten by the spec.
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               serialized_headers.size(),
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               &new_headers));
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, MultiValueHeader) {
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Frame builder with plentiful buffer size.
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrameBuilder frame(1024);
105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (spdy_version_ < 4) {
105490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE);
105590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteUInt32(3);  // stream_id
105690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
105790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    frame.WriteFramePrefix(framer, SYN_STREAM, CONTROL_FLAG_NONE, 3);
105890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame.WriteUInt32(0);  // associated stream id
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame.WriteUInt16(0);  // Priority.
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string value("value1\0value2");
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteUInt16(1);  // Number of headers.
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString("name");
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteString(value);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteUInt32(1);  // Number of headers.
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32("name");
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frame.WriteStringPiece32(value);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // write the length
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frame.RewriteLength(framer);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock new_headers;
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(false);
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(frame.take());
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringPiece serialized_headers =
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSerializedHeaders(control_frame.get(), framer);
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              serialized_headers.size(),
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              &new_headers));
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(new_headers.find("name") != new_headers.end());
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(value, new_headers.find("name")->second);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, BasicCompression) {
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["server"] = "SpdyServer 1.0";
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["status"] = "200";
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["version"] = "HTTP/1.1";
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["content-type"] = "text/html";
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["content-length"] = "12";
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TestSpdyVisitor> visitor(new TestSpdyVisitor(spdy_version_));
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_debug_visitor(visitor.get());
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> frame1(
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,  // stream id
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // associated stream id
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,  // priority
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // credential slot
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             true,  // compress
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
11087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t uncompressed_size1 = visitor->last_payload_len_;
11097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t compressed_size1 =
11107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy2()) {
11127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(139u, uncompressed_size1);
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_SYSTEM_ZLIB)
11147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(155u, compressed_size1);
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else  // !defined(USE_SYSTEM_ZLIB)
11167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(135u, compressed_size1);
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
11197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(165u, uncompressed_size1);
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_SYSTEM_ZLIB)
11217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(181u, compressed_size1);
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else  // !defined(USE_SYSTEM_ZLIB)
11237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(117u, compressed_size1);
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> frame2(
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,  // stream id
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // associated stream id
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,  // priority
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // credential slot
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             true,  // compress
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
11347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t uncompressed_size2 = visitor->last_payload_len_;
11357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t compressed_size2 =
11367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expect the second frame to be more compact than the first.
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(frame2->size(), frame1->size());
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decompress the first frame
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> frame3(SpdyFramerTestUtil::DecompressFrame(
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &framer, *frame1.get()));
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decompress the second frame
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visitor.reset(new TestSpdyVisitor(spdy_version_));
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_debug_visitor(visitor.get());
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> frame4(SpdyFramerTestUtil::DecompressFrame(
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &framer, *frame2.get()));
11507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t uncompressed_size4 =
11517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      frame4->size() - framer.GetSynStreamMinimumSize();
11527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t compressed_size4 =
11537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy2()) {
11557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(139u, uncompressed_size4);
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_SYSTEM_ZLIB)
11577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(149u, compressed_size4);
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else  // !defined(USE_SYSTEM_ZLIB)
11597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(101u, compressed_size4);
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
11627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(165u, uncompressed_size4);
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_SYSTEM_ZLIB)
11647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(175u, compressed_size4);
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else  // !defined(USE_SYSTEM_ZLIB)
11667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(102u, compressed_size4);
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(uncompressed_size1, uncompressed_size2);
11717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(uncompressed_size1, uncompressed_size4);
11727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(compressed_size2, compressed_size4);
11737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expect frames 3 & 4 to be the same.
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompareFrames("Uncompressed SYN_STREAM", *frame3, *frame4);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expect frames 3 to be the same as a uncompressed frame created
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from scratch.
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> uncompressed_frame(
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,  // stream id
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // associated stream id
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,  // priority
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,  // credential slot
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false,  // compress
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompareFrames("Uncompressed SYN_STREAM", *frame3, *uncompressed_frame);
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, CompressEmptyHeaders) {
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See crbug.com/172383
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyHeaderBlock headers;
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["server"] = "SpdyServer 1.0";
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["status"] = "200";
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["version"] = "HTTP/1.1";
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["content-type"] = "text/html";
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["content-length"] = "12";
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["x-empty-header"] = "";
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(true);
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> frame1(
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.CreateSynStream(1,  // stream id
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,  // associated stream id
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             1,  // priority
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,  // credential slot
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             CONTROL_FLAG_NONE,
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,  // compress
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             &headers));
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, Basic) {
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV2Input[] = {
121690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #1
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x14,
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', 'h',
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'v', 'v',
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x08,  // HEADERS on Stream #1
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x18,
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', '2',
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'v', '2',
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', '3',
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'v', '3',
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x0c,
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
123990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #3
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x0c,
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x04,
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x03,  // RST_STREAM on Stream #1
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
126290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x03,  // RST_STREAM on Stream #3
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV3Input[] = {
126990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #1
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1a,
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x01, 0x00, 0x00,
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', 'h',
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'v', 'v',
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x08,  // HEADERS on Stream #1
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x20,
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h', '2',
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'v', '2', 0x00, 0x00,
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', '3',
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'v', '3',
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x0c,
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
129790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #3
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x0e,
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00,
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x04,
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x03,  // RST_STREAM on Stream #1
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,           // DATA on Stream #3
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x03,  // RST_STREAM on Stream #3
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4Input[] = {
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x1e, 0x01, 0x00,           // SYN_STREAM #1
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x01, 0x00, 0x00,
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'h', 'h',
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'v', 'v',
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x24, 0x08, 0x00,           // HEADERS on Stream #1
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  '2',  0x00, 0x00,
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'v',  '2',
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'h',  '3',  0x00, 0x00,
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'v', '3',
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x14, 0x00, 0x00,           // DATA on Stream #1
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x12, 0x01, 0x00,           // SYN Stream #3
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00,
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x10, 0x00, 0x00,           // DATA on Stream #3
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x00, 0x00,           // DATA on Stream #1
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x03, 0x00,           // RST_STREAM on Stream #1
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x08, 0x00, 0x00,           // DATA on Stream #3
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x03, 0x00,           // RST_STREAM on Stream #3
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSpdy3()) {
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV4Input, sizeof(kV4Input));
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, visitor.syn_frame_count_);
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.headers_frame_count_);
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(24, visitor.data_bytes_);
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, visitor.fin_frame_count_);
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_flag_count_);
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, visitor.data_frame_count_);
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the FIN flag on a data frame signifies EOF.
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, FinOnDataFrame) {
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV2Input[] = {
140390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #1
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x14,
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', 'h',
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'v', 'v',
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x02,  // SYN REPLY Stream #1
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x10,
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'a', 'a',
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'b', 'b',
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x0c,
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1, with EOF
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0x00, 0x00, 0x04,
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV3Input[] = {
142990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #1
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1a,
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x01, 0x00, 0x00,
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', 'h',
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'v',  'v',
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x02,  // SYN REPLY Stream #1
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x14,
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'a',  'a',  0x00, 0x00,
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'b', 'b',
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x0c,
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,           // DATA on Stream #1, with EOF
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0x00, 0x00, 0x04,
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4Input[] = {
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x1e, 0x01, 0x00,           // SYN_STREAM #1
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x01, 0x00, 0x00,
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'h', 'h',
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'v',  'v',
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x18, 0x02, 0x00,           // SYN REPLY Stream #1
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'a',  'a',  0x00, 0x00,
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'b', 'b',
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x14, 0x00, 0x00,           // DATA on Stream #1
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x00, 0x01,           // DATA on Stream #1, with FIN
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xde, 0xad, 0xbe, 0xef,
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSpdy3()) {
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV4Input, sizeof(kV4Input));
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_frame_count_);
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.headers_frame_count_);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(16, visitor.data_bytes_);
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_frame_count_);
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_flag_count_);
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, visitor.data_frame_count_);
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the FIN flag on a SYN reply frame signifies EOF.
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, FinOnSynReplyFrame) {
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV2Input[] = {
150890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #1
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x14,
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', 'h',
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'v', 'v',
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
151690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x02,  // SYN REPLY Stream #1
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x01, 0x00, 0x00, 0x10,
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'a', 'a',
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'b', 'b',
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV3Input[] = {
152490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x01,  // SYN Stream #1
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1a,
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x01, 0x00, 0x00,
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x02, 'h', 'h',
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'v', 'v',
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
153490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x02,  // SYN REPLY Stream #1
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x01, 0x00, 0x00, 0x14,
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'a', 'a',   0x00, 0x00,
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'b', 'b',
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4Input[] = {
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x1e, 0x01, 0x00,           // SYN_STREAM #1
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x01, 0x00, 0x00,
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'h', 'h',
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'v', 'v',
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x18, 0x02, 0x01,           // SYN_REPLY #1, with FIN
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'a', 'a',   0x00, 0x00,
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x02, 'b', 'b',
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSpdy3()) {
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV4Input, sizeof(kV4Input));
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_frame_count_);
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.headers_frame_count_);
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.data_bytes_);
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_frame_count_);
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.fin_flag_count_);
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.data_frame_count_);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, HeaderCompression) {
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer send_framer(spdy_version_);
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer recv_framer(spdy_version_);
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  send_framer.set_enable_compression(true);
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  recv_framer.set_enable_compression(true);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader1[] = "header1";
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader2[] = "header2";
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader3[] = "header3";
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue1[] = "value1";
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue2[] = "value2";
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue3[] = "value3";
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SYN_STREAM #1
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock block;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader1] = kValue1;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader2] = kValue2;
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyControlFlags flags(CONTROL_FLAG_NONE);
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdySynStreamIR syn_ir_1(1);
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syn_ir_1.SetHeader(kHeader1, kValue1);
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  syn_ir_1.SetHeader(kHeader2, kValue2);
1602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> syn_frame_1(send_framer.SerializeFrame(syn_ir_1));
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(syn_frame_1.get() != NULL);
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SYN_STREAM #2
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader3] = kValue3;
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> syn_frame_2(
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      send_framer.CreateSynStream(3,  // stream id
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // associated stream id
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // priority
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // credential slot
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  flags,
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  true,  // compress
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &block));
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(syn_frame_2.get() != NULL);
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start decompressing
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> decompressed;
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> uncompressed;
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::StringPiece serialized_headers;
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock decompressed_headers;
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decompress SYN_STREAM #1
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &recv_framer, *syn_frame_1.get()));
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(decompressed.get() != NULL);
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized_headers = GetSerializedHeaders(decompressed.get(), send_framer);
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   serialized_headers.size(),
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &decompressed_headers));
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, decompressed_headers.size());
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue1, decompressed_headers[kHeader1]);
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decompress SYN_STREAM #2
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &recv_framer, *syn_frame_2.get()));
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(decompressed.get() != NULL);
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized_headers = GetSerializedHeaders(decompressed.get(), send_framer);
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decompressed_headers.clear();
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   serialized_headers.size(),
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &decompressed_headers));
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3u, decompressed_headers.size());
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue1, decompressed_headers[kHeader1]);
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue3, decompressed_headers[kHeader3]);
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify we don't leak when we leave streams unclosed
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, UnclosedStreamDataCompressors) {
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer send_framer(spdy_version_);
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  send_framer.set_enable_compression(true);
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader1[] = "header1";
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader2[] = "header2";
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue1[] = "value1";
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue2[] = "value2";
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock block;
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader1] = kValue1;
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader2] = kValue2;
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyControlFlags flags(CONTROL_FLAG_NONE);
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> syn_frame(
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      send_framer.CreateSynStream(1,  // stream id
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // associated stream id
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // priority
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // credential slot
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  flags,
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  true,  // compress
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &block));
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(syn_frame.get() != NULL);
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char bytes[] = "this is a test test test test test!";
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> send_frame(
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      send_framer.CreateDataFrame(
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1, bytes, arraysize(bytes),
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(send_frame.get() != NULL);
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the inputs through the framer.
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char* data;
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data = reinterpret_cast<const unsigned char*>(syn_frame->data());
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visitor.SimulateInFramer(data, syn_frame->size());
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data = reinterpret_cast<const unsigned char*>(send_frame->data());
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visitor.SimulateInFramer(data, send_frame->size());
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_frame_count_);
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.headers_frame_count_);
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_frame_count_);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_flag_count_);
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.data_frame_count_);
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify we can decompress the stream even if handed over to the
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// framer 1 byte at a time.
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer send_framer(spdy_version_);
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  send_framer.set_enable_compression(true);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader1[] = "header1";
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kHeader2[] = "header2";
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue1[] = "value1";
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kValue2[] = "value2";
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock block;
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader1] = kValue1;
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  block[kHeader2] = kValue2;
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyControlFlags flags(CONTROL_FLAG_NONE);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> syn_frame(
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      send_framer.CreateSynStream(1,  // stream id
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // associated stream id
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // priority
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  0,  // credential slot
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  flags,
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  true,  // compress
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &block));
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(syn_frame.get() != NULL);
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char bytes[] = "this is a test test test test test!";
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> send_frame(
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      send_framer.CreateDataFrame(
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1, bytes, arraysize(bytes),
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(send_frame.get() != NULL);
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the inputs through the framer.
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char* data;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data = reinterpret_cast<const unsigned char*>(syn_frame->data());
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t idx = 0; idx < syn_frame->size(); ++idx) {
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(data + idx, 1);
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0, visitor.error_count_);
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data = reinterpret_cast<const unsigned char*>(send_frame->data());
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t idx = 0; idx < send_frame->size(); ++idx) {
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(data + idx, 1);
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0, visitor.error_count_);
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_frame_count_);
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.syn_reply_frame_count_);
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.headers_frame_count_);
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_frame_count_);
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.fin_flag_count_);
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.data_frame_count_);
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, WindowUpdateFrame) {
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x12345678));
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV3FrameData[] = {  // Also applies for V2.
176790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x09,
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x12, 0x34, 0x56, 0x78
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4FrameData[] = {
17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x09, 0x00,
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x12, 0x34, 0x56, 0x78
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
17812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateDataFrame) {
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "'hello' data frame, no FIN";
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x05,
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'h',  'e',  'l',  'l',
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o'
17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0d, 0x00, 0x00,
17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'h',  'e',  'l',  'l',
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o'
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char bytes[] = "hello";
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, bytes, strlen(bytes), DATA_FLAG_NONE));
18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyDataIR data_ir(1);
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_ir.SetDataShallow(base::StringPiece(bytes, strlen(bytes)));
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    frame.reset(framer.SerializeDataFrameHeader(data_ir));
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompareCharArraysWithHexError(
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kDescription,
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reinterpret_cast<const unsigned char*>(frame->data()),
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.GetDataFrameMinimumSize(),
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IsSpdy4() ? kV4FrameData : kV3FrameData,
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.GetDataFrameMinimumSize());
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Data frame with negative data byte, no FIN";
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xff
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x09, 0x00, 0x00,
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, "\xff", 1, DATA_FLAG_NONE));
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "'hello' data frame, with FIN";
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x05,
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'h', 'e', 'l', 'l',
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o'
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0d, 0x00, 0x01,
18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'h',  'e',  'l',  'l',
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o'
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, "hello", 5, DATA_FLAG_FIN));
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Empty data frame";
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x08, 0x00, 0x00,
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, "", 0, DATA_FLAG_NONE));
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Data frame with max stream ID";
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x05,
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'h',  'e',  'l',  'l',
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o'
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0d, 0x00, 0x01,
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'h',  'e',  'l',  'l',
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o'
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0x7fffffff, "hello", 5, DATA_FLAG_FIN));
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       CompareFrame(
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!IsSpdy4()) {
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This test does not apply to SPDY 4 because the max frame size is smaller
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // than 4MB.
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Large data frame";
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kDataSize = 4 * 1024 * 1024;  // 4 MB
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string kData(kDataSize, 'A');
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kFrameHeader[] = {
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x40, 0x00, 0x00,
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kFrameSize = arraysize(kFrameHeader) + kDataSize;
1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<unsigned char[]> expected_frame_data(
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new unsigned char[kFrameSize]);
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(expected_frame_data.get(), kFrameHeader, arraysize(kFrameHeader));
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(expected_frame_data.get() + arraysize(kFrameHeader), 'A', kDataSize);
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, kData.data(), kData.size(), DATA_FLAG_FIN));
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompareFrame(kDescription, *frame, expected_frame_data.get(), kFrameSize);
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateSynStreamUncompressed) {
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(false);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "SYN_STREAM frame, lowest pri, slot 2, no FIN";
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kPri = IsSpdy2() ? 0xC0 : 0xE0;
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kCre = IsSpdy2() ? 0 : 2;
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
195690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x20,
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPri, 0x00, 0x00, 0x02,
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x03, 'f',
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x03,
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'b',  'a',  'r'
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
196890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x2a,
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPri, kCre, 0x00, 0x00,
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x02, 0x00, 0x00,
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x00, 0x00,
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'f',  'o',  'o',
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'b',
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'a',  'r'
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
19822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x2e, 0x01, 0x00,
19842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kPri, kCre, 0x00, 0x00,
19872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x02, 0x00, 0x00,
19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'b',  'a',
19892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'r',  0x00, 0x00, 0x00,
19902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 'f',  'o',  'o',
19912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
19922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'f',  'o',  'o',  0x00,
19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'b',
19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'a',  'r'
19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        framer.CreateSynStream(1,  // stream id
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0,  // associated stream id
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               framer.GetLowestPriority(),
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               kCre,  // credential slot
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               CONTROL_FLAG_NONE,
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false,  // compress
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &headers));
20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
20082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
20092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
20102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "SYN_STREAM frame with a 0-length header name, highest pri, FIN, "
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "max stream ID";
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
2019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    headers[std::string()] = "foo";
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
202390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x1D,
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'f',  'o',  'o',
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r'
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
203590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x27,
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x02, 0x00, 0x00,
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'f',  'o',
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  0x00, 0x00, 0x00,
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'f',  'o',  'o',
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'b',  'a',  'r'
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
20482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
20492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x2b, 0x01, 0x01,
20502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
20532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x02, 0x00, 0x00,
20542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
20552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'f',  'o',
20562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  0x00, 0x00, 0x00,
20572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 'f',  'o',  'o',
20582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
20592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'b',  'a',  'r'
20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        framer.CreateSynStream(0x7fffffff,  // stream id
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0x7fffffff,  // associated stream id
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               framer.GetHighestPriority(),
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0,  // credential slot
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               CONTROL_FLAG_FIN,
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false,  // compress
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &headers));
20692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
20712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
20722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
20742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "SYN_STREAM frame with a 0-length header val, high pri, FIN, "
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "max stream ID";
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "";
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kPri = IsSpdy2() ? 0x40 : 0x20;
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
208990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x1D,
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPri, 0x00, 0x00, 0x02,
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x03, 'f',
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x03,
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
210190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x27,
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPri, 0x00, 0x00, 0x00,
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x02, 0x00, 0x00,
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x00, 0x00,
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'f',  'o',  'o',
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x2b, 0x01, 0x01,
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kPri, 0x00, 0x00, 0x00,
21192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x02, 0x00, 0x00,
21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'b',  'a',
21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'r',  0x00, 0x00, 0x00,
21222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 'f',  'o',  'o',
21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'f',  'o',  'o',  0x00,
21252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00
21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        framer.CreateSynStream(0x7fffffff,  // stream id
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0x7fffffff,  // associated stream id
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               1,  // priority
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0,  // credential slot
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               CONTROL_FLAG_FIN,
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               false,  // compress
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &headers));
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(phajdan.jr): Clean up after we no longer need
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to workaround http://crbug.com/139744.
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_SYSTEM_ZLIB)
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(true);
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "SYN_STREAM frame, low pri, no FIN";
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SpdyPriority priority = IsSpdy2() ? 2 : 4;
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
216290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x36,
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x80, 0x00, 0x38, 0xea,
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xdf, 0xa2, 0x51, 0xb2,
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x62, 0x60, 0x62, 0x60,
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x4e, 0x4a, 0x2c, 0x62,
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x60, 0x06, 0x08, 0xa0,
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xb4, 0xfc, 0x7c, 0x80,
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x62, 0x60, 0x4e,
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xcb, 0xcf, 0x67, 0x60,
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x06, 0x08, 0xa0, 0xa4,
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xc4, 0x22, 0x80, 0x00,
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x02, 0x00, 0x00, 0x00,
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff, 0xff,
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
218090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x01,
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x37,
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x80, 0x00, 0x38, 0xEA,
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xE3, 0xC6, 0xA7, 0xC2,
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x02, 0xE5, 0x0E, 0x50,
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xC2, 0x4B, 0x4A, 0x04,
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xE5, 0x0B, 0x66, 0x80,
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x4A, 0xCB, 0xCF,
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x07, 0x08, 0x20, 0x10,
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x95, 0x96, 0x9F, 0x0F,
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xA2, 0x00, 0x02, 0x28,
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x29, 0xB1, 0x08, 0x20,
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x80, 0x00, 0x00, 0x00,
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0xFF, 0xFF,
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
21972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x3b, 0x01, 0x00,
21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
22012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x80, 0x00, 0x38, 0xea,
22022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xe3, 0xc6, 0xa7, 0xc2,
22032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x02, 0xe5, 0x0e, 0x50,
22042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xc2, 0x4b, 0x4a, 0x04,
22052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xe5, 0x0b, 0x66, 0x80,
22062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x4a, 0xcb, 0xcf,
22072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x07, 0x08, 0x20, 0x10,
22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x95, 0x96, 0x9f, 0x0f,
22092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xa2, 0x00, 0x02, 0x28,
22102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x29, 0xb1, 0x08, 0x20,
22112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x80, 0x00, 0x00, 0x00,
22122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0xff, 0xff,
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        framer.CreateSynStream(1,  // stream id
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0,  // associated stream id
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               priority,
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               0,  // credential slot
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               CONTROL_FLAG_NONE,
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               true,  // compress
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &headers));
22222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
22232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
22242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
22252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
22262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
22272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
22282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateSynReplyUncompressed) {
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(false);
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "SYN_REPLY frame, no FIN";
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
224590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x1C,
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x03, 'f',
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x03,
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'b',  'a',  'r'
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
225690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x24,
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'b',  'a',  'r',  0x00,
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'f',
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x00,
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'f',  'o',
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  0x00, 0x00, 0x00,
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'b',  'a',  'r'
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
22682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
22692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x28, 0x02, 0x00,
22702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
22712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
22722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
22732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'b',  'a',  'r',  0x00,
22742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'f',
22752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  0x00, 0x00,
22762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'f',  'o',
22772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  0x00, 0x00, 0x00,
22782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 'b',  'a',  'r'
22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, CONTROL_FLAG_NONE, false, &headers));
22822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
22832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
22842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
22852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
22862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
22872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
22882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "SYN_REPLY frame with a 0-length header name, FIN, max stream ID";
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
2296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    headers[std::string()] = "foo";
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
230090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x19,
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'f',  'o',  'o',
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r'
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
231190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x21,
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'f',
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x00,
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r'
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
23232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
23242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x25, 0x02, 0x01,
23252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
23262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
23272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
23282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
23292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'f',  'o',  'o',  0x00,
23302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'f',
23312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  0x00, 0x00,
23322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'b',  'a',
23332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'r'
23342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
23372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
23382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
23392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
23402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
23412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
23422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
23432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "SYN_REPLY frame with a 0-length header val, FIN, max stream ID";
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "";
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
235590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x19,
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x03, 'f',
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x03,
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
236690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x21,
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'b',  'a',  'r',  0x00,
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'f',
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x00,
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'f',  'o',
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  0x00, 0x00, 0x00,
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
23782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
23792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x25, 0x02, 0x01,
23802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
23812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
23822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
23832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'b',  'a',  'r',  0x00,
23842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'f',
23852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  0x00, 0x00,
23862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'f',  'o',
23872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  0x00, 0x00, 0x00,
23882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00
23892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
23922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
23932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
23942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
23952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
23962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
23972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
23982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(phajdan.jr): Clean up after we no longer need
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to workaround http://crbug.com/139744.
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_SYSTEM_ZLIB)
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateSynReplyCompressed) {
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(true);
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "SYN_REPLY frame, no FIN";
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
241790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x32,
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x38, 0xea,
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xdf, 0xa2, 0x51, 0xb2,
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x62, 0x60, 0x62, 0x60,
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x4e, 0x4a, 0x2c, 0x62,
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x60, 0x06, 0x08, 0xa0,
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xb4, 0xfc, 0x7c, 0x80,
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x62, 0x60, 0x4e,
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xcb, 0xcf, 0x67, 0x60,
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x06, 0x08, 0xa0, 0xa4,
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xc4, 0x22, 0x80, 0x00,
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x02, 0x00, 0x00, 0x00,
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff, 0xff,
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
243490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x02,
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x31,
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x38, 0xea, 0xe3, 0xc6,
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xa7, 0xc2, 0x02, 0xe5,
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0e, 0x50, 0xc2, 0x4b,
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x4a, 0x04, 0xe5, 0x0b,
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x66, 0x80, 0x00, 0x4a,
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xcb, 0xcf, 0x07, 0x08,
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x20, 0x10, 0x95, 0x96,
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x9f, 0x0f, 0xa2, 0x00,
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x02, 0x28, 0x29, 0xb1,
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x08, 0x20, 0x80, 0x00,
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0xff,
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff,
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
24502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
24512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x35, 0x02, 0x00,
24522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x38, 0xea, 0xe3, 0xc6,
24542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xa7, 0xc2, 0x02, 0xe5,
24552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0e, 0x50, 0xc2, 0x4b,
24562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x4a, 0x04, 0xe5, 0x0b,
24572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x66, 0x80, 0x00, 0x4a,
24582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xcb, 0xcf, 0x07, 0x08,
24592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x20, 0x10, 0x95, 0x96,
24602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x9f, 0x0f, 0xa2, 0x00,
24612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x02, 0x28, 0x29, 0xb1,
24622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x08, 0x20, 0x80, 0x00,
24632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0xff,
24642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xff,
24652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, CONTROL_FLAG_NONE, true, &headers));
24682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
24692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
24702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
24712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
24722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
24732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
24742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateRstStream) {
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "RST_STREAM frame";
24842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
248590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x03,
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
24902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0c, 0x03, 0x00,
24922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
24942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
24952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
24962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.CreateRstStream(1, RST_STREAM_PROTOCOL_ERROR));
24972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
24982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
24992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
25002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
25012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "RST_STREAM frame with max stream ID";
25062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
250790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x03,
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
25122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
25132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0c, 0x03, 0x00,
25142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
25152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
25162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
25172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(
25182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        0x7FFFFFFF, RST_STREAM_PROTOCOL_ERROR));
25192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
25202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
25212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
25222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
25232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "RST_STREAM frame with max status code";
25282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
252990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x03,
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x06,
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
25342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
25352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0c, 0x03, 0x00,
25362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
25372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x06,
25382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
25392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(
25402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        0x7FFFFFFF, RST_STREAM_INTERNAL_ERROR));
25412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
25422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
25432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
25442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
25452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateSettings) {
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Network byte order SETTINGS frame";
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 kValue = 0x0a0b0c0d;
25562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdySettingsFlags kFlags = static_cast<SpdySettingsFlags>(0x01);
25572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdySettingsIds kId = static_cast<SpdySettingsIds>(0x020304);
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SettingsMap settings;
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    settings[kId] = SettingsFlagsAndValue(kFlags, kValue);
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kFlags, settings[kId].first);
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kValue, settings[kId].second);
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV2FrameData[] = {
256690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x04,
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x0c,
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
25692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x04, 0x03, 0x02, 0x01,
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0a, 0x0b, 0x0c, 0x0d,
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
25722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {
257390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x04,
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x0c,
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
25762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x01, 0x02, 0x03, 0x04,
25772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0a, 0x0b, 0x0c, 0x0d,
25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
258090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x14, 0x04, 0x00,
258190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
25822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
25832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x01, 0x02, 0x03, 0x04,
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0a, 0x0b, 0x0c, 0x0d,
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
25882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
25892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
25912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
25942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Basic SETTINGS frame";
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SettingsMap settings;
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddSpdySettingFromWireFormat(
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &settings, 0x00000000, 0x00000001);  // 1st Setting
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddSpdySettingFromWireFormat(
26042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &settings, 0x01000001, 0x00000002);  // 2nd Setting
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddSpdySettingFromWireFormat(
26062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &settings, 0x02000002, 0x00000003);  // 3rd Setting
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddSpdySettingFromWireFormat(
26082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &settings, 0x03000003, 0xff000004);  // 4th Setting
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
261190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x04,
26122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x24,
26132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x04,
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,  // 1st Setting
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
26162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x01, 0x00, 0x00, 0x01,  // 2nd Setting
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
26182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x02, 0x00, 0x00, 0x02,  // 3rd Setting
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
26202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 0x00, 0x00, 0x03,  // 4th Setting
26212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xff, 0x00, 0x00, 0x04,
26222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
26232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
262490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x2c, 0x04, 0x00,
262590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
26262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x04,
26272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,  // 1st Setting
26282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
26292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x01, 0x00, 0x00, 0x01,  // 2nd Setting
26302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
26312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x02, 0x00, 0x00, 0x02,  // 3rd Setting
26322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
26332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 0x00, 0x00, 0x03,  // 4th Setting
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff, 0x00, 0x00, 0x04,
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
26362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
26372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
26382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
26392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
26402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "Empty SETTINGS frame";
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SettingsMap settings;
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
265090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x04,
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x04,
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
26542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
265590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x0c, 0x04, 0x00,
265690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
26572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
26582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
26602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
26612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
26622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
26632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
26642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreatePingFrame) {
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "PING frame";
26732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
267490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x06,
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x04,
26762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x12, 0x34, 0x56, 0x78,
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
26782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
267990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x0c, 0x06, 0x00,
268090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
26812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x12, 0x34, 0x56, 0x78,
26822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
26832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreatePingFrame(0x12345678u));
26842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
26852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
26862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
26872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
26882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateGoAway) {
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "GOAWAY frame";
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
269890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x07,
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x04,
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
270390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x07,
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
27082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
270990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x10, 0x07, 0x00,
271090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0, GOAWAY_OK));
27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
27162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
27172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
27182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
27192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
27202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
27212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "GOAWAY frame with max stream ID, status";
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
272790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x07,
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x04,
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
273290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x07,
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
27372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
273890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x10, 0x07, 0x00,
273990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
27402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
27412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
27422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0x7FFFFFFF,
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    GOAWAY_INTERNAL_ERROR));
27452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
27462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
27472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
27492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(false);
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "HEADERS frame, no FIN";
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
276790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x1C,
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x03, 'f',
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x03,
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'b',  'a',  'r'
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
277890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x24,
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'b',  'a',  'r',  0x00,
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'f',
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x00,
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'f',  'o',
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  0x00, 0x00, 0x00,
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'b',  'a',  'r'
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
27902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
27912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x28, 0x08, 0x00,
27922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
27932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
27942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
27952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'b',  'a',  'r',  0x00,
27962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'f',
27972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  0x00, 0x00,
27982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'f',  'o',
27992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  0x00, 0x00, 0x00,
28002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x03, 'b',  'a',  'r'
28012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, CONTROL_FLAG_NONE, false, &headers));
28042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
28052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
28062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
28072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
28082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
28092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
28102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "HEADERS frame with a 0-length header name, FIN, max stream ID";
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
2818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    headers[std::string()] = "foo";
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
282290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x19,
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x03, 'f',  'o',  'o',
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r'
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
283390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x21,
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'f',
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x00,
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r'
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
28452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
28462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x25, 0x08, 0x01,
28472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
28482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x00,
28502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
28512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'f',  'o',  'o',  0x00,
28522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'f',
28532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  0x00, 0x00,
28542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'b',  'a',
28552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'r'
28562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
28592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
28602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
28612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
28622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
28632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
28642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
28652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] =
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "HEADERS frame with a 0-length header val, FIN, max stream ID";
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "";
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
287790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x19,
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'b',  'a',
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'r',  0x00, 0x03, 'f',
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x03,
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'f',  'o',  'o',  0x00,
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
288890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x01, 0x00, 0x00, 0x21,
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'b',  'a',  'r',  0x00,
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x03, 'f',
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  'o',  0x00, 0x00,
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x03, 'f',  'o',
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'o',  0x00, 0x00, 0x00,
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
29002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
29012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x25, 0x08, 0x01,
29022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
29032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x02,
29042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x03,
29052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'b',  'a',  'r',  0x00,
29062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x03, 'f',
29072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  'o',  0x00, 0x00,
29082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x03, 'f',  'o',
29092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'o',  0x00, 0x00, 0x00,
29102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00
29112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
29142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
29152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
29162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
29172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
29182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
29192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
29202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(phajdan.jr): Clean up after we no longer need
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to workaround http://crbug.com/139744.
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_SYSTEM_ZLIB)
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateHeadersCompressed) {
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_enable_compression(true);
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "HEADERS frame, no FIN";
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyHeaderBlock headers;
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["bar"] = "foo";
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    headers["foo"] = "bar";
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV2FrameData[] = {
293990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x32,
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x38, 0xea,
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xdf, 0xa2, 0x51, 0xb2,
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x62, 0x60, 0x62, 0x60,
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x4e, 0x4a, 0x2c, 0x62,
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x60, 0x06, 0x08, 0xa0,
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xb4, 0xfc, 0x7c, 0x80,
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x62, 0x60, 0x4e,
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xcb, 0xcf, 0x67, 0x60,
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x06, 0x08, 0xa0, 0xa4,
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xc4, 0x22, 0x80, 0x00,
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x02, 0x00, 0x00, 0x00,
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff, 0xff,
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char kV3FrameData[] = {
295690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x08,
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x31,
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x38, 0xea, 0xe3, 0xc6,
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xa7, 0xc2, 0x02, 0xe5,
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x0e, 0x50, 0xc2, 0x4b,
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x4a, 0x04, 0xe5, 0x0b,
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x66, 0x80, 0x00, 0x4a,
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xcb, 0xcf, 0x07, 0x08,
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x20, 0x10, 0x95, 0x96,
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x9f, 0x0f, 0xa2, 0x00,
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x02, 0x28, 0x29, 0xb1,
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x08, 0x20, 0x80, 0x00,
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0xff,
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0xff,
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
29722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
29732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x35, 0x08, 0x00,
29742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
29752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x38, 0xea, 0xe3, 0xc6,
29762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xa7, 0xc2, 0x02, 0xe5,
29772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x0e, 0x50, 0xc2, 0x4b,
29782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x4a, 0x04, 0xe5, 0x0b,
29792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x66, 0x80, 0x00, 0x4a,
29802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xcb, 0xcf, 0x07, 0x08,
29812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x20, 0x10, 0x95, 0x96,
29822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x9f, 0x0f, 0xa2, 0x00,
29832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x02, 0x28, 0x29, 0xb1,
29842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x08, 0x20, 0x80, 0x00,
29852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0xff,
29862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0xff
29872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, CONTROL_FLAG_NONE, true, &headers));
29902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy2()) {
29912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV2FrameData, arraysize(kV2FrameData));
29922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (IsSpdy3()) {
29932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
29942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
29952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
29962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(USE_SYSTEM_ZLIB)
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CreateWindowUpdate) {
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "WINDOW_UPDATE frame";
30062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
300790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x09,
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
30122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
30132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0c, 0x09, 0x00,
30142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
30172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        framer.CreateWindowUpdate(1, 1));
30192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
30202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
30212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
30222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
30232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
30282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
302990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x09,
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
30342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
30352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0c, 0x09, 0x00,
30362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
30372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(0x7FFFFFFF, 1));
30402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
30412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
30422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
30432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
30442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
30492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV3FrameData[] = {  // Also applies for V2.
305090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      0x80, spdy_version_ch_, 0x00, 0x09,
30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x08,
30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
30552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const unsigned char kV4FrameData[] = {
30562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x0c, 0x09, 0x00,
30572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x00, 0x00, 0x00, 0x01,
30582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0x7f, 0xff, 0xff, 0xff,
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
30602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x7FFFFFFF));
30612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsSpdy4()) {
30622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
30632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
30642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
30652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyFramerTest, SerializeBlocked) {
3070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (spdy_version_ < SPDY4) {
3071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
3072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
3073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
3075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char kDescription[] = "BLOCKED frame";
3077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const unsigned char kFrameData[] = {
3078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00, 0x08, 0x0b, 0x00,
3079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
3080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
3081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SpdyBlockedIR blocked_ir(0);
3082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
3083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
3084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30877dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
30887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (spdy_version_ < SPDY4) {
30897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
30907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
30917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
30927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyFramer framer(spdy_version_);
30937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  framer.set_enable_compression(false);
30947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
30957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const char kDescription[] = "PUSH_PROMISE frame";
30967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyHeaderBlock headers;
30977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  headers["bar"] = "foo";
30987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  headers["foo"] = "bar";
30997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const unsigned char kFrameData[] = {
31017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x2C, 0x0C, 0x00,  // length = 44, type = 12, flags = 0
31027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0x2A,  // stream id = 42
31037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0x39,  // promised stream id = 57
31047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0x02,  // start of uncompressed header block
31057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0x03,
31067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    'b',  'a',  'r',  0x00,
31077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x03, 'f',
31087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    'o',  'o',  0x00, 0x00,
31097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x03, 'f',  'o',
31107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    'o',  0x00, 0x00, 0x00,
31117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x03, 'b',  'a',  'r'    // end of uncompressed header block
31127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  };
31137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(framer.CreatePushPromise(
31157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      42, 57, &headers));
31167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
31177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
31187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31197dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_P(SpdyFramerTest, CreatePushPromiseCompressed) {
31207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (spdy_version_ < SPDY4) {
31217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
31227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
31237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyFramer framer(spdy_version_);
31257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  framer.set_enable_compression(true);
31267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const char kDescription[] = "PUSH_PROMISE frame";
31287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyHeaderBlock headers;
31297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  headers["bar"] = "foo";
31307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  headers["foo"] = "bar";
31317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const unsigned char kFrameData[] = {
31337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x39, 0x0C, 0x00,  // length = 57, type = 12, flags = 0
31347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0x2A,  // stream id = 42
31357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0x39,  // promised stream id = 57
31367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x38, 0xea, 0xe3, 0xc6,  // start of compressed header block
31377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0xa7, 0xc2, 0x02, 0xe5,
31387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x0e, 0x50, 0xc2, 0x4b,
31397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x4a, 0x04, 0xe5, 0x0b,
31407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x66, 0x80, 0x00, 0x4a,
31417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0xcb, 0xcf, 0x07, 0x08,
31427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x20, 0x10, 0x95, 0x96,
31437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x9f, 0x0f, 0xa2, 0x00,
31447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x02, 0x28, 0x29, 0xb1,
31457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x08, 0x20, 0x80, 0x00,
31467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0x00, 0x00, 0x00, 0xff,
31477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    0xff                     // end of compressed header block
31487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  };
31497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<SpdySerializedFrame> frame(framer.CreatePushPromise(
31517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      42, 57, &headers));
31527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
31537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
31547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCompressedSynStreamHeaderBlock) {
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["aa"] = "vv";
31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["bb"] = "ww";
31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
31602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // associated_stream_id
31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,                     // priority
31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // credential_slot
31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             true,                  // compress
31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
31732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_frame_count_);
31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCompressedSynReplyHeaderBlock) {
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["alpha"] = "beta";
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["gamma"] = "delta";
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
31832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynReply(1,                     // stream_id
31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            CONTROL_FLAG_NONE,
31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            true,                  // compress
31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &headers));
31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
31932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_reply_frame_count_);
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["alpha"] = "beta";
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["gamma"] = "delta";
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
32032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateHeaders(1,                     // stream_id
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           CONTROL_FLAG_NONE,
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           true,                  // compress
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           &headers));
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
32132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.headers_frame_count_);
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // control_frame_header_data_count_ depends on the random sequence
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // produced by rand(), so adding, removing or running single tests
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alters this value.  The best we can do is assert that it happens
32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at least twice.
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(2, visitor.control_frame_header_data_count_);
32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["alpha"] = "beta";
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["gamma"] = "delta";
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
32302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateHeaders(1,                     // stream_id
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           CONTROL_FLAG_FIN,
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           true,                  // compress
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           &headers));
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
32402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.headers_frame_count_);
32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // control_frame_header_data_count_ depends on the random sequence
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // produced by rand(), so adding, removing or running single tests
32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alters this value.  The best we can do is assert that it happens
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at least twice.
32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(2, visitor.control_frame_header_data_count_);
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
32532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First find the size of the header value in order to just reach the control
32542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame max size.
32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
32562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
32572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyHeaderBlock headers;
32582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["aa"] = "";
32592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
32602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
32612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,                     // associated_stream_id
32622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             1,                     // priority
32632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,                     // credential_slot
32642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             CONTROL_FLAG_NONE,
32652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             false,                 // compress
32662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             &headers));
32672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t kBigValueSize =
32682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.GetControlFrameBufferMaxSize() - control_frame->size();
32692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a frame at exatly that size.
32712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string big_value(kBigValueSize, 'x');
32722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["aa"] = big_value.c_str();
32732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  control_frame.reset(
32742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
32752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,                     // associated_stream_id
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,                     // priority
32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // credential_slot
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false,                 // compress
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
32822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(framer.GetControlFrameBufferMaxSize(), control_frame->size());
32832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
32872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(visitor.header_buffer_valid_);
32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.syn_frame_count_);
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
32932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LT(kBigValueSize, visitor.header_buffer_length_);
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ControlFrameTooLarge) {
32972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First find the size of the header value in order to just reach the control
32982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame max size.
32992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
33002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
33022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  headers["aa"] = "";
33032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
33042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
33052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,                     // associated_stream_id
33062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             1,                     // priority
33072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             0,                     // credential_slot
33082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             CONTROL_FLAG_NONE,
33092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             false,                 // compress
33102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             &headers));
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kBigValueSize =
33122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.GetControlFrameBufferMaxSize() - control_frame->size() + 1;
33132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a frame at exatly that size.
33152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string big_value(kBigValueSize, 'x');
33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["aa"] = big_value.c_str();
33172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  control_frame.reset(
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // associated_stream_id
33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,                     // priority
33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // credential_slot
33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false,                 // compress
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
33262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(framer.GetControlFrameBufferMaxSize() + 1,
33272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            control_frame->size());
33282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
33322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(visitor.header_buffer_valid_);
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
3336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            visitor.framer_.error_code())
3337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.syn_frame_count_);
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, visitor.header_buffer_length_);
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the framer stops delivering header data chunks once the visitor
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// declares it doesn't want any more. This is important to guard against
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "zip bomb" types of attacks.
33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kHeaderBufferChunks = 4;
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kHeaderBufferSize =
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks;
33502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t kBigValueSize = kHeaderBufferSize * 2;
33512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string big_value(kBigValueSize, 'x');
33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["aa"] = big_value.c_str();
33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
33542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // associated_stream_id
33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,                     // priority
33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // credential_slot
33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_FIN,      // half close
33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             true,                  // compress
33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.set_header_buffer_size(kHeaderBufferSize);
33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
33682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(visitor.header_buffer_valid_);
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
3372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            visitor.framer_.error_code())
3373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The framer should have stoped delivering chunks after the visitor
33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // signaled "stop" by returning false from OnControlFrameHeaderData().
33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // control_frame_header_data_count_ depends on the random sequence
33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // produced by rand(), so adding, removing or running single tests
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alters this value.  The best we can do is assert that it happens
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at least kHeaderBufferChunks + 1.
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(kHeaderBufferChunks + 1,
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<unsigned>(visitor.control_frame_header_data_count_));
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The framer should not have sent half-close to the visitor.
33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) {
33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers["aa"] = "alpha beta gamma delta";
33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
33942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_enable_compression(false);
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct a SYN_STREAM control frame without compressing the header block,
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and have the framer try to decompress it. This will cause the framer to
33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deal with a decompression error.
33982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateSynStream(1,                     // stream_id
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // associated_stream_id
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             1,                     // priority
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             0,                     // credential_slot
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CONTROL_FLAG_NONE,
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false,                 // compress
34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &headers));
34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = true;
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
34102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
3412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_DECOMPRESS_FAILURE, visitor.framer_.error_code())
3413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, visitor.header_buffer_length_);
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a GoAway frame that has a few extra bytes at the end.
34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We create enough overhead to overflow the framer's control frame buffer.
34202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_GE(250u, SpdyFramer::kControlFrameBufferSize);
34212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char length =  1 + SpdyFramer::kControlFrameBufferSize;
34222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV3FrameData[] = {  // Also applies for V2.
342390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x07,
34242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, length,
34252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
34262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
34272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
34282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4FrameData[] = {
34292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, static_cast<uint8>(length + 4), 0x07, 0x00,
34302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
34312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
34322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
34342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t pad_length =
34352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      length + framer.GetControlFrameHeaderSize() -
34362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (IsSpdy4() ? sizeof(kV4FrameData) : sizeof(kV3FrameData));
34372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string pad('A', pad_length);
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
34412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV4FrameData, sizeof(kV4FrameData));
34422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
34432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
34442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const unsigned char*>(pad.c_str()),
34472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pad.length());
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);  // This generated an error.
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME,
3451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            visitor.framer_.error_code())
3452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.goaway_count_);  // Frame not parsed.
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
34602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetFrameLength(control_frame.get(), 0, spdy_version_);
34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
34652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.GetControlFrameHeaderSize());
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should generate an error, since zero-len settings frames are unsupported.
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests handling of SETTINGS frames with invalid length.
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadBogusLenSettingsFrame) {
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a setting to pad the frame so that we don't get a buffer overflow when
34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calling SimulateInFramer() below.
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_UPLOAD_BANDWIDTH] =
34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(SETTINGS_FLAG_PLEASE_PERSIST, 0x00000002);
34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
34792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t kNewLength = 5;
34802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetFrameLength(control_frame.get(), kNewLength, spdy_version_);
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
34852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      framer.GetControlFrameHeaderSize() + kNewLength);
34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should generate an error, since zero-len settings frames are unsupported.
34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests handling of SETTINGS frames larger than the frame buffer size.
34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySettingsFlags flags = SETTINGS_FLAG_PLEASE_PERSIST;
34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_UPLOAD_BANDWIDTH] =
34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(flags, 0x00000002);
34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_DOWNLOAD_BANDWIDTH] =
34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(flags, 0x00000003);
34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_ROUND_TRIP_TIME] = SettingsFlagsAndValue(flags, 0x00000004);
35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(SpdyFramer::kControlFrameBufferSize,
35022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            control_frame->size());
35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read all at once.
35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
35092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(settings.size(), static_cast<unsigned>(visitor.setting_count_));
35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read data in small chunks.
35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t framed_data = 0;
35152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t unframed_data = control_frame->size();
35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t kReadChunkSize = 5;  // Read five bytes at a time.
35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (unframed_data > 0) {
35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t to_read = min(kReadChunkSize, unframed_data);
35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(
35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<unsigned char*>(control_frame->data() + framed_data),
35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        to_read);
35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unframed_data -= to_read;
35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framed_data += to_read;
35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(settings.size() * 2, static_cast<unsigned>(visitor.setting_count_));
35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests handling of SETTINGS frame with duplicate entries.
35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV2FrameData[] = {
353490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x04,
35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1C,
35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0x00, 0x00, 0x00,  // 1st Setting
35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0x00, 0x00, 0x00,  // 2nd (duplicate) Setting
35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 0x00, 0x00, 0x00,  // 3rd (unprocessed) Setting
35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV3FrameData[] = {
354590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x04,
35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1C,
35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,  // 1st Setting
35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,  // 2nd (duplicate) Setting
35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,  // 3rd (unprocessed) Setting
35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
35552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4FrameData[] = {
355690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x24, 0x04, 0x00,
355790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
35582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,  // 1st Setting
35602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
35612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,  // 2nd (duplicate) Setting
35622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,  // 3rd (unprocessed) Setting
35642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
35712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSpdy3()) {
35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
35732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
35742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV4FrameData, sizeof(kV4FrameData));
35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.setting_count_);
35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests handling of SETTINGS frame with entries out of order.
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV2FrameData[] = {
358590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x04,
35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1C,
35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 0x00, 0x00, 0x00,  // 1st Setting
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0x00, 0x00, 0x00,  // 2nd (out of order) Setting
35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 0x00, 0x00, 0x00,  // 3rd (unprocessed) Setting
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kV3FrameData[] = {
359690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x04,
35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x1C,
35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,  // 1st Setting
36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x01,  // 2nd (out of order) Setting
36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x01, 0x03,  // 3rd (unprocessed) Setting
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
36062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4FrameData[] = {
360790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x24, 0x04, 0x00,
360890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
36092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
36102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,  // 1st Setting
36112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x02,
36122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,  // 2nd (out of order) Setting
36132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
36142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x01, 0x03,  // 3rd (unprocessed) Setting
36152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x03,
36162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSpdy2()) {
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
36222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSpdy3()) {
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
36242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
36252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor.SimulateInFramer(kV4FrameData, sizeof(kV4FrameData));
36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.setting_count_);
36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadWindowUpdate) {
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
36332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateWindowUpdate(1, 2));
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
36382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
36392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, visitor.last_window_update_stream_);
36402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2u, visitor.last_window_update_delta_);
36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCredentialFrame) {
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyCredential credential;
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.slot = 3;
36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.proof = "proof";
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("a cert");
36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("another cert");
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("final cert");
36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateCredentialFrame(credential));
36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data()),
36582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      control_frame->size());
36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
36602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(control_frame->size() - framer.GetControlFrameHeaderSize(),
36612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            visitor.credential_buffer_length_);
36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(credential.slot, visitor.credential_.slot);
36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(credential.proof, visitor.credential_.proof);
36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < credential.certs.size(); i++) {
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCredentialFrameOneByteAtATime) {
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyCredential credential;
36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.slot = 3;
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.proof = "proof";
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("a cert");
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("another cert");
36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("final cert");
36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateCredentialFrame(credential));
36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read one byte at a time to make sure we handle edge cases
36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* data =
36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data());
36862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t idx = 0; idx < control_frame->size(); ++idx) {
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    visitor.SimulateInFramer(data + idx, 1);
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0, visitor.error_count_);
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
36912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(control_frame->size() - framer.GetControlFrameHeaderSize(),
36922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            visitor.credential_buffer_length_);
36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(credential.slot, visitor.credential_.slot);
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(credential.proof, visitor.credential_.proof);
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < credential.certs.size(); i++) {
36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCredentialFrameWithNoPayload) {
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyCredential credential;
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.slot = 3;
37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.proof = "proof";
37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("a cert");
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("another cert");
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("final cert");
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateCredentialFrame(credential));
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
37142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetFrameLength(control_frame.get(), 0, spdy_version_);
37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* data =
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data());
37172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visitor.SimulateInFramer(data, framer.GetControlFrameHeaderSize());
37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) {
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyCredential credential;
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.slot = 3;
37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.proof = "proof";
37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("a cert");
37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("another cert");
37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("final cert");
37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateCredentialFrame(credential));
37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* data =
37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data());
37362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t offset = framer.GetControlFrameHeaderSize() + 4;
37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[offset] = 0xFF;  // Proof length is past the end of the frame
37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
37392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data, control_frame->size());
37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadCredentialFrameWithCorruptCertificate) {
37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyCredential credential;
37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.slot = 3;
37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.proof = "proof";
37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("a cert");
37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("another cert");
37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  credential.certs.push_back("final cert");
37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> control_frame(
37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framer.CreateCredentialFrame(credential));
37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(control_frame.get() != NULL);
37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* data =
37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<unsigned char*>(control_frame->data());
37582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t offset = framer.GetCredentialMinimumSize() + 1;
37592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data[offset] = 0xFF;  // Proof length is past the end of the frame
37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(
37612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data, control_frame->size());
37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Regression test for parsing issue found in b/8278897.
3766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_P(SpdyFramerTest, ReadCredentialFrameFollowedByAnotherFrame) {
3767ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyCredential credential;
3768ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  credential.slot = 3;
3769ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  credential.proof = "proof";
3770ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  credential.certs.push_back("a cert");
3771ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  credential.certs.push_back("another cert");
3772ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  credential.certs.push_back("final cert");
3773ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SpdyFramer framer(spdy_version_);
3774ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdyFrame> credential_frame(
3775ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      framer.CreateCredentialFrame(credential));
3776ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_TRUE(credential_frame.get() != NULL);
3777ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  TestSpdyVisitor visitor(spdy_version_);
3778ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  visitor.use_compression_ = false;
3779ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  string multiple_frame_data(credential_frame->data(),
3780ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                             credential_frame->size());
3781ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<SpdyFrame> goaway_frame(framer.CreateGoAway(0, GOAWAY_OK));
3782ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  multiple_frame_data.append(string(goaway_frame->data(),
3783ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    goaway_frame->size()));
3784ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  visitor.SimulateInFramer(
3785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      reinterpret_cast<unsigned const char*>(multiple_frame_data.data()),
3786ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      multiple_frame_data.length());
3787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(0, visitor.error_count_);
3788ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(credential_frame->size() - framer.GetControlFrameHeaderSize(),
3789ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            visitor.credential_buffer_length_);
3790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(credential.slot, visitor.credential_.slot);
3791ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(credential.proof, visitor.credential_.proof);
3792ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
3793ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for (size_t i = 0; i < credential.certs.size(); i++) {
3794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
3795ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
3796ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
3797ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
37987dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
37997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (spdy_version_ < 4) {
38007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
38017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
38027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
38037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyHeaderBlock headers;
38047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  headers["foo"] = "bar";
38057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  headers["bar"] = "foofoo";
38067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SpdyFramer framer(spdy_version_);
38077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<SpdyFrame> frame(framer.CreatePushPromise(42, 57, &headers));
38087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(frame.get() != NULL);
38097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestSpdyVisitor visitor(spdy_version_);
38107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  visitor.use_compression_ = true;
38117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  visitor.SimulateInFramer(
38127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      reinterpret_cast<unsigned char*>(frame->data()),
38137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      frame->size());
38147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(42u, visitor.last_push_promise_stream_);
38157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(57u, visitor.last_push_promise_promised_stream_);
38167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
38177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
38187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadGarbage) {
38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char garbage_frame[256];
38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(garbage_frame, ~0, sizeof(garbage_frame));
38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame));
38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ReadGarbageWithValidVersion) {
38302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
38312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Not valid for SPDY 4 since there is no version field.
38322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
38332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
38352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kFrameData[] = {
383690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0xff, 0xff,
38372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xff, 0xff, 0xff, 0xff,
38382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestSpdyVisitor visitor(spdy_version_);
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visitor.use_compression_ = false;
38412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  visitor.SimulateInFramer(kFrameData, arraysize(kFrameData));
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, SizesTest) {
38462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
38472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(8u, framer.GetDataFrameMinimumSize());
38482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
38492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(8u, framer.GetSynReplyMinimumSize());
38502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12u, framer.GetRstStreamSize());
385190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(12u, framer.GetSettingsMinimumSize());
385290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(12u, framer.GetPingSize());
385390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(16u, framer.GetGoAwaySize());
38542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(8u, framer.GetHeadersMinimumSize());
38552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12u, framer.GetWindowUpdateSize());
385690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(10u, framer.GetCredentialMinimumSize());
3857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(8u, framer.GetBlockedSize());
38587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_EQ(12u, framer.GetPushPromiseMinimumSize());
385990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(8u, framer.GetFrameMinimumSize());
3860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(65535u, framer.GetFrameMaximumSize());
3861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(65527u, framer.GetDataFrameMaximumPayload());
38622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
38632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(8u, framer.GetControlFrameHeaderSize());
38642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(18u, framer.GetSynStreamMinimumSize());
38652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(IsSpdy2() ? 14u : 12u, framer.GetSynReplyMinimumSize());
38662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(16u, framer.GetRstStreamSize());
38672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12u, framer.GetSettingsMinimumSize());
38682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(12u, framer.GetPingSize());
38692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(IsSpdy2() ? 12u : 16u, framer.GetGoAwaySize());
38702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(IsSpdy2() ? 14u : 12u, framer.GetHeadersMinimumSize());
38712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(16u, framer.GetWindowUpdateSize());
38722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(10u, framer.GetCredentialMinimumSize());
3873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(8u, framer.GetFrameMinimumSize());
3874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(16777215u, framer.GetFrameMaximumSize());
3875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(16777207u, framer.GetDataFrameMaximumPayload());
38762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
38772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
38782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, StateToStringTest) {
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("ERROR",
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(SpdyFramer::SPDY_ERROR));
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("AUTO_RESET",
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(SpdyFramer::SPDY_AUTO_RESET));
38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("RESET",
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(SpdyFramer::SPDY_RESET));
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("READING_COMMON_HEADER",
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_READING_COMMON_HEADER));
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("CONTROL_FRAME_PAYLOAD",
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_CONTROL_FRAME_PAYLOAD));
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("IGNORE_REMAINING_PAYLOAD",
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_IGNORE_REMAINING_PAYLOAD));
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("FORWARD_STREAM_FRAME",
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_FORWARD_STREAM_FRAME));
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK",
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK));
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK",
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_CONTROL_FRAME_HEADER_BLOCK));
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SPDY_CREDENTIAL_FRAME_PAYLOAD",
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD));
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD));
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("UNKNOWN_STATE",
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::StateToString(
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD + 1));
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, ErrorCodeToStringTest) {
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("NO_ERROR",
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_NO_ERROR));
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("INVALID_CONTROL_FRAME",
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE",
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("ZLIB_INIT_FAILURE",
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_ZLIB_INIT_FAILURE));
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("UNSUPPORTED_VERSION",
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_UNSUPPORTED_VERSION));
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("DECOMPRESS_FAILURE",
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_DECOMPRESS_FAILURE));
39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("COMPRESS_FAILURE",
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_COMPRESS_FAILURE));
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SPDY_INVALID_DATA_FRAME_FLAGS",
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS));
39392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("SPDY_INVALID_CONTROL_FRAME_FLAGS",
39402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::ErrorCodeToString(
39412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS));
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("UNKNOWN_ERROR",
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SpdyFramer::ErrorCodeToString(SpdyFramer::LAST_ERROR));
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, StatusCodeToStringTest) {
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("INVALID",
39482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_INVALID));
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("PROTOCOL_ERROR",
39502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_PROTOCOL_ERROR));
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("INVALID_STREAM",
39522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_INVALID_STREAM));
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("REFUSED_STREAM",
39542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_REFUSED_STREAM));
39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("UNSUPPORTED_VERSION",
39562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_UNSUPPORTED_VERSION));
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("CANCEL",
39582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_CANCEL));
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("INTERNAL_ERROR",
39602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_INTERNAL_ERROR));
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("FLOW_CONTROL_ERROR",
39622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_FLOW_CONTROL_ERROR));
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("UNKNOWN_STATUS",
39642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               SpdyFramer::StatusCodeToString(RST_STREAM_NUM_STATUS_CODES));
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(SpdyFramerTest, FrameTypeToStringTest) {
3968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_STREQ("DATA",
3969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(DATA));
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SYN_STREAM",
3971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(SYN_STREAM));
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SYN_REPLY",
3973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(SYN_REPLY));
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("RST_STREAM",
3975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(RST_STREAM));
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("SETTINGS",
3977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(SETTINGS));
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("NOOP",
3979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(NOOP));
39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("PING",
3981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(PING));
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("GOAWAY",
3983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(GOAWAY));
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("HEADERS",
3985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(HEADERS));
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("WINDOW_UPDATE",
3987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(WINDOW_UPDATE));
39887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_STREQ("PUSH_PROMISE",
39897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               SpdyFramer::FrameTypeToString(PUSH_PROMISE));
39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ("CREDENTIAL",
3991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               SpdyFramer::FrameTypeToString(CREDENTIAL));
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, CatchProbableHttpResponse) {
39952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
39962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(hkhalil): catch probable HTTP response in SPDY 4?
39972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
39982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyFramer framer(spdy_version_);
40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer.set_visitor(&visitor);
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(visitor, OnError(_));
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer.ProcessInput("HTTP/1.1", 8);
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(framer.probable_http_response());
40072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
4008a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
4009a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        << SpdyFramer::ErrorCodeToString(framer.error_code());
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyFramer framer(spdy_version_);
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer.set_visitor(&visitor);
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(visitor, OnError(_));
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer.ProcessInput("HTTP/1.0", 8);
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(framer.probable_http_response());
40192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
4020a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
4021a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        << SpdyFramer::ErrorCodeToString(framer.error_code());
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, DataFrameFlags) {
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyFramer framer(spdy_version_);
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framer.set_visitor(&visitor);
40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        framer.CreateDataFrame(1, "hello", 5, DATA_FLAG_NONE));
40352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
40362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~DATA_FLAG_FIN) {
40382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
40392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
40402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
40412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false));
40422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (flags & DATA_FLAG_FIN) {
40432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true));
40442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
40452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
40462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
40482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~DATA_FLAG_FIN) {
40492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
40502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS,
4051a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4052a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
40532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
40542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4055a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4056a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
40572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
40582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
40592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
40602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, SynStreamFrameFlags) {
40622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
40632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
40642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
40667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    testing::StrictMock<test::MockDebugVisitor> debug_visitor;
40672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
40682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
40697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    framer.set_debug_visitor(&debug_visitor);
40702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_CALL(debug_visitor, OnSendCompressedFrame(8, SYN_STREAM, _, _));
40722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyHeaderBlock headers;
40742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    headers["foo"] = "bar";
40752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
40762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.CreateSynStream(8, 3, 1, 0, CONTROL_FLAG_NONE, true, &headers));
40772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
40782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
40802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
40812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
40827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(8, SYN_STREAM, _));
40832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnSynStream(8, 3, 1, 0, flags & CONTROL_FLAG_FIN,
40842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       flags & CONTROL_FLAG_UNIDIRECTIONAL));
40852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnControlFrameHeaderData(8, _, _))
40862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillRepeatedly(testing::Return(true));
40872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (flags & DATA_FLAG_FIN) {
40882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true));
40892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
40902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
40912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
40932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
40942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
40952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4096a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4097a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
40982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
40992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
41022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
41032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
41042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
41052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, SynReplyFrameFlags) {
41072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
41082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
41092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
41112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
41122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
41132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyHeaderBlock headers;
41152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    headers["foo"] = "bar";
41162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
41172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.CreateSynReply(37, CONTROL_FLAG_NONE, true, &headers));
41182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
41192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~CONTROL_FLAG_FIN) {
41212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
41222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
41232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnSynReply(37, flags & CONTROL_FLAG_FIN));
41242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnControlFrameHeaderData(37, _, _))
41252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillRepeatedly(testing::Return(true));
41262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (flags & DATA_FLAG_FIN) {
41272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true));
41282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
41292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
41302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
41322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~CONTROL_FLAG_FIN) {
41332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
41342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
41372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
41382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
41412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
41422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
41432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
41442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
41462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
41472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
41482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
41502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
41512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
41522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(13, RST_STREAM_CANCEL));
41542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
41552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
41572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
41582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
41592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnRstStream(13, RST_STREAM_CANCEL));
41602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
41612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
41632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
41642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
41652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
41682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
41692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
41722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
41732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
41742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
41752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, SettingsFrameFlags) {
41772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
41782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
41792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
41812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
41822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
41832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SettingsMap settings;
41852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings[SETTINGS_UPLOAD_BANDWIDTH] =
41862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::make_pair(SETTINGS_FLAG_NONE, 54321);
41872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
41882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
41892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
41912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
41922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_CALL(visitor, OnSettings(
4194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          flags & SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS));
41952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnSetting(SETTINGS_UPLOAD_BANDWIDTH,
41962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     SETTINGS_FLAG_NONE, 54321));
41972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
41982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
42002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
42012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
42022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
42052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
42062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
42092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
42102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
42122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, GoawayFrameFlags) {
42142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
42152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
42162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
42182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
42192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
42202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(97, GOAWAY_OK));
42222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
42232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
42252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
42262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
42272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnGoAway(97, GOAWAY_OK));
42282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
42292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
42312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
42322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
42332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
42362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
42372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
42402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
42412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
42432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, HeadersFrameFlags) {
42452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
42462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
42472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
42492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
42502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
42512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyHeaderBlock headers;
42532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    headers["foo"] = "bar";
42542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(
42552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.CreateHeaders(57, CONTROL_FLAG_NONE, true, &headers));
42562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
42572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~CONTROL_FLAG_FIN) {
42592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
42602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
42612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnHeaders(57, flags & CONTROL_FLAG_FIN));
42622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _))
42632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillRepeatedly(testing::Return(true));
42642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (flags & DATA_FLAG_FIN) {
42652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true));
42662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
42672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
42682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
42702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags & ~CONTROL_FLAG_FIN) {
42712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
42722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
42752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
42762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
42792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
42802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
42822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, PingFrameFlags) {
42842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
42852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
42862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
42882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
42892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
42902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreatePingFrame(42));
42922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
42932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
42952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
42962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
42972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnPing(42));
42982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
42992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
43012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
43022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
43032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
43062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
43072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
43102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
43112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
43122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
43132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
43152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
43162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
43172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
43192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
43202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
43212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(4, 1024));
43232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
43262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
43272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
43282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnWindowUpdate(4, 1024));
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
43322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
43332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
43342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
43372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
43382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
43412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
43422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
43432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
43442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43457dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_P(SpdyFramerTest, PushPromiseFrameFlags) {
43467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (spdy_version_ < SPDY4) {
43477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
43487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
43497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (int flags = 0; flags < 256; ++flags) {
43517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SCOPED_TRACE(testing::Message() << "Flags " << flags);
43527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    testing::StrictMock<net::test::MockVisitor> visitor;
43547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    testing::StrictMock<net::test::MockDebugVisitor> debug_visitor;
43557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SpdyFramer framer(spdy_version_);
43567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    framer.set_visitor(&visitor);
43577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    framer.set_debug_visitor(&debug_visitor);
43587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_CALL(debug_visitor, OnSendCompressedFrame(42, PUSH_PROMISE, _, _));
43607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SpdyHeaderBlock headers;
43627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    headers["foo"] = "bar";
43637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<SpdyFrame> frame(framer.CreatePushPromise(42, 57, &headers));
43647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SetFrameFlags(frame.get(), flags, spdy_version_);
43657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (flags != 0) {
43677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_CALL(visitor, OnError(_));
43687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
43697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, PUSH_PROMISE, _));
43707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_CALL(visitor, OnPushPromise(42, 57));
43717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_CALL(visitor, OnControlFrameHeaderData(42, _, _))
43727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          .WillRepeatedly(testing::Return(true));
43737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
43747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    framer.ProcessInput(frame->data(), frame->size());
43767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (flags != 0) {
43777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
43787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
43817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
43827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
43857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
43867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
43877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
43887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
43892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, CredentialFrameFlags) {
43902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int flags = 0; flags < 256; ++flags) {
43912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SCOPED_TRACE(testing::Message() << "Flags " << flags);
43922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    testing::StrictMock<test::MockVisitor> visitor;
43942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyFramer framer(spdy_version_);
43952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.set_visitor(&visitor);
43962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyCredential credential;
43982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
43992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameFlags(frame.get(), flags, spdy_version_);
44002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
44022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnError(_));
44032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
44042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(visitor, OnCredentialFrameData(_, _))
44052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillRepeatedly(testing::Return(true));
44062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
44072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(frame->data(), frame->size());
44092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (flags != 0) {
44102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
44112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
4412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                framer.error_code())
4413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
44142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
44152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          << SpdyFramer::ErrorCodeToString(framer.error_code());
44182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, EmptySynStream) {
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyHeaderBlock headers;
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::StrictMock<test::MockVisitor> visitor;
44267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  testing::StrictMock<test::MockDebugVisitor> debug_visitor;
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_visitor(&visitor);
44297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  framer.set_debug_visitor(&debug_visitor);
44307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
44317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(debug_visitor, OnSendCompressedFrame(1, SYN_STREAM, _, _));
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame>
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frame(framer.CreateSynStream(1, 0, 1, 0, CONTROL_FLAG_NONE, true,
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   &headers));
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adjust size to remove the name/value block.
44372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
44382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameLength(
44392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        frame.get(),
44402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.GetSynStreamMinimumSize(),
44412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        spdy_version_);
44422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
44432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetFrameLength(
44442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        frame.get(),
44452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        framer.GetSynStreamMinimumSize() - framer.GetControlFrameHeaderSize(),
44462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        spdy_version_);
44472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(1, SYN_STREAM, _));
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(visitor, OnSynStream(1, 0, 1, 0, false, false));
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(visitor, OnControlFrameHeaderData(1, NULL, 0));
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.ProcessInput(frame->data(), framer.GetSynStreamMinimumSize());
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(SpdyFramerTest, SettingsFlagsAndId) {
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kId = 0x020304;
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kFlags = 0x01;
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kWireFormat = htonl(IsSpdy2() ? 0x04030201 : 0x01020304);
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsFlagsAndId id_and_flags =
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndId::FromWireFormat(spdy_version_, kWireFormat);
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kId, id_and_flags.id());
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kFlags, id_and_flags.flags());
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(spdy_version_));
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test handling of a RST_STREAM with out-of-bounds status codes.
44722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, RstStreamStatusBounds) {
44732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(0xff, RST_STREAM_NUM_STATUS_CODES);
44742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV3RstStreamInvalid[] = {
447690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x03,
44772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
44782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
44792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, RST_STREAM_INVALID
44802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
44812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4RstStreamInvalid[] = {
44822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x03, 0x00,
44832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
44842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, RST_STREAM_INVALID
44852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
44862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV3RstStreamNumStatusCodes[] = {
448890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x03,
44892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
44902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
44912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, RST_STREAM_NUM_STATUS_CODES
44922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
44932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4RstStreamNumStatusCodes[] = {
44942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x0c, 0x03, 0x00,
44952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x01,
44962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, RST_STREAM_NUM_STATUS_CODES
44972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
44982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::StrictMock<test::MockVisitor> visitor;
45002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
45012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_visitor(&visitor);
45022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID));
45042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
45052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(reinterpret_cast<const char*>(kV4RstStreamInvalid),
45062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        arraysize(kV4RstStreamInvalid));
45072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
45082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(reinterpret_cast<const char*>(kV3RstStreamInvalid),
45092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        arraysize(kV3RstStreamInvalid));
45102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
45112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
45142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(visitor, OnRstStream(1, RST_STREAM_INVALID));
45162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy4()) {
45172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(
45182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reinterpret_cast<const char*>(kV4RstStreamNumStatusCodes),
45192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        arraysize(kV4RstStreamNumStatusCodes));
45202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
45212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(
45222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reinterpret_cast<const char*>(kV3RstStreamNumStatusCodes),
45232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        arraysize(kV3RstStreamNumStatusCodes));
45242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
45252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
45282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
45292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests handling of a GOAWAY frame with out-of-bounds stream ID.
45312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
45322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV2FrameData[] = {
453390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x07,
45342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x04,
45352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xff, 0xff, 0xff, 0xff,
45362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
45372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV3FrameData[] = {
453890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x80, spdy_version_ch_, 0x00, 0x07,
45392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x08,
45402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xff, 0xff, 0xff, 0xff,
45412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
45422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
45432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned char kV4FrameData[] = {
454490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x10, 0x07, 0x00,
454590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
45462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0xff, 0xff, 0xff, 0xff,
45472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
45482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
45492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::StrictMock<test::MockVisitor> visitor;
45512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFramer framer(spdy_version_);
45522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_visitor(&visitor);
45532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
45542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(visitor, OnGoAway(0x7fffffff, GOAWAY_OK));
45552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsSpdy2()) {
45562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(reinterpret_cast<const char*>(kV2FrameData),
45572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        arraysize(kV2FrameData));
45582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (IsSpdy3()) {
45592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(reinterpret_cast<const char*>(kV3FrameData),
45602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        arraysize(kV3FrameData));
45612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
45622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    framer.ProcessInput(reinterpret_cast<const char*>(kV4FrameData),
45632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        arraysize(kV4FrameData));
45642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
45652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
45682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
45692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_P(SpdyFramerTest, OnBlocked) {
4571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (spdy_version_ < SPDY4) {
4572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
4573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const SpdyStreamId kStreamId = 0;
4576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::StrictMock<test::MockVisitor> visitor;
4578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SpdyFramer framer(spdy_version_);
4579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  framer.set_visitor(&visitor);
4580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(visitor, OnBlocked(kStreamId));
4582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SpdyBlockedIR blocked_ir(0);
4584eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
4585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  framer.ProcessInput(frame->data(), framer.GetBlockedSize());
4586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state());
4588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
4589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      << SpdyFramer::ErrorCodeToString(framer.error_code());
4590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
4591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
4593