1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/spdy/spdy_websocket_test_util.h" 6 7 #include "net/spdy/buffered_spdy_framer.h" 8 #include "net/spdy/spdy_http_utils.h" 9 10 namespace net { 11 12 static const int kDefaultAssociatedStreamId = 0; 13 static const bool kDefaultCompressed = false; 14 static const char* const kDefaultDataPointer = NULL; 15 static const uint32 kDefaultDataLength = 0; 16 static const char** const kDefaultExtraHeaders = NULL; 17 static const int kDefaultExtraHeaderCount = 0; 18 19 SpdyWebSocketTestUtil::SpdyWebSocketTestUtil( 20 NextProto protocol) : spdy_util_(protocol) {} 21 22 std::string SpdyWebSocketTestUtil::GetHeader(const SpdyHeaderBlock& headers, 23 const std::string& key) const { 24 SpdyHeaderBlock::const_iterator it = headers.find(GetHeaderKey(key)); 25 return (it == headers.end()) ? "" : it->second; 26 } 27 28 void SpdyWebSocketTestUtil::SetHeader( 29 const std::string& key, 30 const std::string& value, 31 SpdyHeaderBlock* headers) const { 32 (*headers)[GetHeaderKey(key)] = value; 33 } 34 35 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdyWebSocketSynStream( 36 int stream_id, 37 const char* path, 38 const char* host, 39 const char* origin) { 40 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); 41 SetHeader("path", path, headers.get()); 42 SetHeader("host", host, headers.get()); 43 SetHeader("version", "WebSocket/13", headers.get()); 44 SetHeader("scheme", "ws", headers.get()); 45 SetHeader("origin", origin, headers.get()); 46 return spdy_util_.ConstructSpdyControlFrame(headers.Pass(), 47 /*compressed*/ false, 48 stream_id, 49 HIGHEST, 50 SYN_STREAM, 51 CONTROL_FLAG_NONE, 52 0); 53 } 54 55 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdyWebSocketSynReply( 56 int stream_id) { 57 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); 58 SetHeader("status", "101", headers.get()); 59 return spdy_util_.ConstructSpdyControlFrame(headers.Pass(), 60 false, 61 stream_id, 62 LOWEST, 63 SYN_REPLY, 64 CONTROL_FLAG_NONE, 65 0); 66 } 67 68 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdyWebSocketHandshakeRequestFrame( 69 scoped_ptr<SpdyHeaderBlock> headers, 70 SpdyStreamId stream_id, 71 RequestPriority request_priority) { 72 // SPDY SYN_STREAM control frame header. 73 const SpdyHeaderInfo kSynStreamHeader = { 74 SYN_STREAM, 75 stream_id, 76 kDefaultAssociatedStreamId, 77 ConvertRequestPriorityToSpdyPriority(request_priority, 2), 78 kSpdyCredentialSlotUnused, 79 CONTROL_FLAG_NONE, 80 kDefaultCompressed, 81 RST_STREAM_INVALID, 82 kDefaultDataPointer, 83 kDefaultDataLength, 84 DATA_FLAG_NONE 85 }; 86 87 // Construct SPDY SYN_STREAM control frame. 88 return spdy_util_.ConstructSpdyFrame( 89 kSynStreamHeader, 90 headers.Pass()); 91 } 92 93 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdyWebSocketHandshakeResponseFrame( 94 scoped_ptr<SpdyHeaderBlock> headers, 95 SpdyStreamId stream_id, 96 RequestPriority request_priority) { 97 // SPDY SYN_REPLY control frame header. 98 const SpdyHeaderInfo kSynReplyHeader = { 99 SYN_REPLY, 100 stream_id, 101 kDefaultAssociatedStreamId, 102 ConvertRequestPriorityToSpdyPriority(request_priority, 2), 103 kSpdyCredentialSlotUnused, 104 CONTROL_FLAG_NONE, 105 kDefaultCompressed, 106 RST_STREAM_INVALID, 107 kDefaultDataPointer, 108 kDefaultDataLength, 109 DATA_FLAG_NONE 110 }; 111 112 // Construct SPDY SYN_REPLY control frame. 113 return spdy_util_.ConstructSpdyFrame( 114 kSynReplyHeader, 115 headers.Pass()); 116 } 117 118 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdyWebSocketHeadersFrame( 119 int stream_id, 120 const char* length, 121 bool fin) { 122 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); 123 SetHeader("opcode", "1", headers.get()); // text frame 124 SetHeader("length", length, headers.get()); 125 SetHeader("fin", fin ? "1" : "0", headers.get()); 126 return spdy_util_.ConstructSpdyControlFrame(headers.Pass(), 127 /*compression*/ false, 128 stream_id, 129 LOWEST, 130 HEADERS, 131 CONTROL_FLAG_NONE, 132 0); 133 } 134 135 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdyWebSocketDataFrame( 136 const char* data, 137 int len, 138 SpdyStreamId stream_id, 139 bool fin) { 140 141 // Construct SPDY data frame. 142 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 143 return framer.CreateDataFrame( 144 stream_id, 145 data, 146 len, 147 fin ? DATA_FLAG_FIN : DATA_FLAG_NONE); 148 } 149 150 SpdyFrame* SpdyWebSocketTestUtil::ConstructSpdySettings( 151 const SettingsMap& settings) const { 152 return spdy_util_.ConstructSpdySettings(settings); 153 } 154 155 SpdyMajorVersion SpdyWebSocketTestUtil::spdy_version() const { 156 return spdy_util_.spdy_version(); 157 } 158 159 std::string SpdyWebSocketTestUtil::GetHeaderKey( 160 const std::string& key) const { 161 return (spdy_util_.is_spdy2() ? "" : ":") + key; 162 } 163 164 } // namespace net 165