Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: net/websockets/websocket_channel_test.cc

Issue 23604044: Replace WebSocketFrameChunk with WebSocketFrame (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Hasta la vista, baby Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/websockets/websocket_channel.cc ('k') | net/websockets/websocket_frame.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/websockets/websocket_channel.h" 5 #include "net/websockets/websocket_channel.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <iostream> 9 #include <iostream>
10 #include <string> 10 #include <string>
(...skipping 16 matching lines...) Expand all
27 #include "testing/gmock/include/gmock/gmock.h" 27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "url/gurl.h" 29 #include "url/gurl.h"
30 30
31 // Hacky macros to construct the body of a Close message from a code and a 31 // Hacky macros to construct the body of a Close message from a code and a
32 // string, while ensuring the result is a compile-time constant string. 32 // string, while ensuring the result is a compile-time constant string.
33 // Use like CLOSE_DATA(NORMAL_CLOSURE, "Explanation String") 33 // Use like CLOSE_DATA(NORMAL_CLOSURE, "Explanation String")
34 #define CLOSE_DATA(code, string) WEBSOCKET_CLOSE_CODE_AS_STRING_##code string 34 #define CLOSE_DATA(code, string) WEBSOCKET_CLOSE_CODE_AS_STRING_##code string
35 #define WEBSOCKET_CLOSE_CODE_AS_STRING_NORMAL_CLOSURE "\x03\xe8" 35 #define WEBSOCKET_CLOSE_CODE_AS_STRING_NORMAL_CLOSURE "\x03\xe8"
36 #define WEBSOCKET_CLOSE_CODE_AS_STRING_GOING_AWAY "\x03\xe9" 36 #define WEBSOCKET_CLOSE_CODE_AS_STRING_GOING_AWAY "\x03\xe9"
37 #define WEBSOCKET_CLOSE_CODE_AS_STRING_PROTOCOL_ERROR "\x03\xea"
37 #define WEBSOCKET_CLOSE_CODE_AS_STRING_SERVER_ERROR "\x03\xf3" 38 #define WEBSOCKET_CLOSE_CODE_AS_STRING_SERVER_ERROR "\x03\xf3"
38 39
39 namespace net { 40 namespace net {
40 41
41 // Printing helpers to allow GoogleMock to print frame chunks. These are 42 // Printing helpers to allow GoogleMock to print frames. These are explicitly
42 // explicitly designed to look like the static initialisation format we use in 43 // designed to look like the static initialisation format we use in these
43 // these tests. They have to live in the net namespace in order to be found by 44 // tests. They have to live in the net namespace in order to be found by
44 // GoogleMock; a nested anonymous namespace will not work. 45 // GoogleMock; a nested anonymous namespace will not work.
45 46
46 std::ostream& operator<<(std::ostream& os, const WebSocketFrameHeader& header) { 47 std::ostream& operator<<(std::ostream& os, const WebSocketFrameHeader& header) {
47 return os << "{" << (header.final ? "FINAL_FRAME" : "NOT_FINAL_FRAME") << ", " 48 return os << (header.final ? "FINAL_FRAME" : "NOT_FINAL_FRAME") << ", "
48 << header.opcode << ", " 49 << header.opcode << ", "
49 << (header.masked ? "MASKED" : "NOT_MASKED") << ", " 50 << (header.masked ? "MASKED" : "NOT_MASKED");
50 << header.payload_length << "}";
51 } 51 }
52 52
53 std::ostream& operator<<(std::ostream& os, const WebSocketFrameChunk& chunk) { 53 std::ostream& operator<<(std::ostream& os, const WebSocketFrame& frame) {
54 os << "{"; 54 os << "{" << frame.header << ", ";
55 if (chunk.header) { 55 if (frame.data) {
56 os << *chunk.header; 56 return os << "\"" << base::StringPiece(frame.data->data(),
57 } else { 57 frame.header.payload_length)
58 os << "{NO_HEADER}"; 58 << "\"}";
59 } 59 }
60 return os << ", " << (chunk.final_chunk ? "FINAL_CHUNK" : "NOT_FINAL_CHUNK") 60 return os << "NULL}";
61 << ", \""
62 << base::StringPiece(chunk.data->data(), chunk.data->size())
63 << "\"}";
64 } 61 }
65 62
66 std::ostream& operator<<(std::ostream& os, 63 std::ostream& operator<<(std::ostream& os,
67 const ScopedVector<WebSocketFrameChunk>& vector) { 64 const ScopedVector<WebSocketFrame>& vector) {
68 os << "{"; 65 os << "{";
69 bool first = true; 66 bool first = true;
70 for (ScopedVector<WebSocketFrameChunk>::const_iterator it = vector.begin(); 67 for (ScopedVector<WebSocketFrame>::const_iterator it = vector.begin();
71 it != vector.end(); 68 it != vector.end();
72 ++it) { 69 ++it) {
73 if (!first) { 70 if (!first) {
74 os << ",\n"; 71 os << ",\n";
75 } else { 72 } else {
76 first = false; 73 first = false;
77 } 74 }
78 os << **it; 75 os << **it;
79 } 76 }
80 return os << "}"; 77 return os << "}";
81 } 78 }
82 79
83 std::ostream& operator<<(std::ostream& os, 80 std::ostream& operator<<(std::ostream& os,
84 const ScopedVector<WebSocketFrameChunk>* vector) { 81 const ScopedVector<WebSocketFrame>* vector) {
85 return os << '&' << *vector; 82 return os << '&' << *vector;
86 } 83 }
87 84
88 namespace { 85 namespace {
89 86
90 using ::testing::AnyNumber; 87 using ::testing::AnyNumber;
91 using ::testing::InSequence; 88 using ::testing::InSequence;
92 using ::testing::MockFunction; 89 using ::testing::MockFunction;
93 using ::testing::Return; 90 using ::testing::Return;
94 using ::testing::SaveArg; 91 using ::testing::SaveArg;
95 using ::testing::StrictMock; 92 using ::testing::StrictMock;
96 using ::testing::_; 93 using ::testing::_;
97 94
98 // A selection of characters that have traditionally been mangled in some 95 // A selection of characters that have traditionally been mangled in some
99 // environment or other, for testing 8-bit cleanliness. 96 // environment or other, for testing 8-bit cleanliness.
100 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL 97 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL
101 '\0', // nul 98 '\0', // nul
102 '\x7F', // DEL 99 '\x7F', // DEL
103 '\x80', '\xFF', // NOT VALID UTF-8 100 '\x80', '\xFF', // NOT VALID UTF-8
104 '\x1A', // Control-Z, EOF on DOS 101 '\x1A', // Control-Z, EOF on DOS
105 '\x03', // Control-C 102 '\x03', // Control-C
106 '\x04', // EOT, special for Unix terms 103 '\x04', // EOT, special for Unix terms
107 '\x1B', // ESC, often special 104 '\x1B', // ESC, often special
108 '\b', // backspace 105 '\b', // backspace
109 '\'', // single-quote, special in PHP 106 '\'', // single-quote, special in PHP
110 }; 107 };
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 HttpResponseInfo* response_info, 160 HttpResponseInfo* response_info,
164 const CompletionCallback& callback) OVERRIDE { 161 const CompletionCallback& callback) OVERRIDE {
165 return ERR_IO_PENDING; 162 return ERR_IO_PENDING;
166 } 163 }
167 164
168 virtual int ReadHandshakeResponse( 165 virtual int ReadHandshakeResponse(
169 const CompletionCallback& callback) OVERRIDE { 166 const CompletionCallback& callback) OVERRIDE {
170 return ERR_IO_PENDING; 167 return ERR_IO_PENDING;
171 } 168 }
172 169
173 virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 170 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
174 const CompletionCallback& callback) OVERRIDE { 171 const CompletionCallback& callback) OVERRIDE {
175 return ERR_IO_PENDING; 172 return ERR_IO_PENDING;
176 } 173 }
177 174
178 virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 175 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
179 const CompletionCallback& callback) OVERRIDE { 176 const CompletionCallback& callback) OVERRIDE {
180 return ERR_IO_PENDING; 177 return ERR_IO_PENDING;
181 } 178 }
182 179
183 virtual void Close() OVERRIDE {} 180 virtual void Close() OVERRIDE {}
184 181
185 // Returns the string passed to the constructor. 182 // Returns the string passed to the constructor.
186 virtual std::string GetSubProtocol() const OVERRIDE { return protocol_; } 183 virtual std::string GetSubProtocol() const OVERRIDE { return protocol_; }
187 184
188 // Returns the string passed to the constructor. 185 // Returns the string passed to the constructor.
189 virtual std::string GetExtensions() const OVERRIDE { return extensions_; } 186 virtual std::string GetExtensions() const OVERRIDE { return extensions_; }
190 187
191 private: 188 private:
192 // The string to return from GetSubProtocol(). 189 // The string to return from GetSubProtocol().
193 std::string protocol_; 190 std::string protocol_;
194 191
195 // The string to return from GetExtensions(). 192 // The string to return from GetExtensions().
196 std::string extensions_; 193 std::string extensions_;
197 }; 194 };
198 195
199 // To make the static initialisers easier to read, we use enums rather than 196 // To make the static initialisers easier to read, we use enums rather than
200 // bools. 197 // bools.
201
202 // NO_HEADER means there shouldn't be a header included in the generated
203 // WebSocketFrameChunk. The static initialiser always has a header, but we can
204 // avoid specifying the rest of the fields.
205 enum IsFinal { 198 enum IsFinal {
206 NO_HEADER,
207 NOT_FINAL_FRAME, 199 NOT_FINAL_FRAME,
208 FINAL_FRAME 200 FINAL_FRAME
209 }; 201 };
210 202
211 enum IsMasked { 203 enum IsMasked {
212 NOT_MASKED, 204 NOT_MASKED,
213 MASKED 205 MASKED
214 }; 206 };
215 207
216 enum IsFinalChunk { 208 // This is used to initialise a WebSocketFrame but is statically initialisable.
217 NOT_FINAL_CHUNK, 209 struct InitFrame {
218 FINAL_CHUNK 210 IsFinal final;
219 }; 211 // Reserved fields omitted for now. Add them if you need them.
220 212 WebSocketFrameHeader::OpCode opcode;
221 // This is used to initialise a WebSocketFrameChunk but is statically 213 IsMasked masked;
222 // initialisable.
223 struct InitFrameChunk {
224 struct FrameHeader {
225 IsFinal final;
226 // Reserved fields omitted for now. Add them if you need them.
227 WebSocketFrameHeader::OpCode opcode;
228 IsMasked masked;
229 // payload_length is the length of the whole frame. The length of the data
230 // members from every chunk in the frame must add up to the payload_length.
231 uint64 payload_length;
232 };
233 FrameHeader header;
234
235 // Directly equivalent to WebSocketFrameChunk::final_chunk
236 IsFinalChunk final_chunk;
237 214
238 // Will be used to create the IOBuffer member. Can be NULL for NULL data. Is a 215 // Will be used to create the IOBuffer member. Can be NULL for NULL data. Is a
239 // nul-terminated string for ease-of-use. This means it is not 8-bit clean, 216 // nul-terminated string for ease-of-use. |header.payload_length| is
240 // but this is not an issue for test data. 217 // initialised from |strlen(data)|. This means it is not 8-bit clean, but this
218 // is not an issue for test data.
241 const char* const data; 219 const char* const data;
242 }; 220 };
243 221
244 // For GoogleMock 222 // For GoogleMock
245 std::ostream& operator<<(std::ostream& os, const InitFrameChunk& chunk) { 223 std::ostream& operator<<(std::ostream& os, const InitFrame& frame) {
246 os << "{"; 224 os << "{" << (frame.final == FINAL_FRAME ? "FINAL_FRAME" : "NOT_FINAL_FRAME")
247 if (chunk.header.final != NO_HEADER) { 225 << ", " << frame.opcode << ", "
248 os << "{" << (chunk.header.final == FINAL_FRAME ? "FINAL_FRAME" 226 << (frame.masked == MASKED ? "MASKED" : "NOT_MASKED") << ", ";
249 : "NOT_FINAL_FRAME") << ", " 227 if (frame.data) {
250 << chunk.header.opcode << ", " 228 return os << "\"" << frame.data << "\"}";
251 << (chunk.header.masked == MASKED ? "MASKED" : "NOT_MASKED") << ", "
252 << chunk.header.payload_length << "}";
253
254 } else {
255 os << "{NO_HEADER}";
256 } 229 }
257 return os << ", " << (chunk.final_chunk == FINAL_CHUNK ? "FINAL_CHUNK" 230 return os << "NULL}";
258 : "NOT_FINAL_CHUNK")
259 << ", \"" << chunk.data << "\"}";
260 } 231 }
261 232
262 template <size_t N> 233 template <size_t N>
263 std::ostream& operator<<(std::ostream& os, const InitFrameChunk (&chunks)[N]) { 234 std::ostream& operator<<(std::ostream& os, const InitFrame (&frames)[N]) {
264 os << "{"; 235 os << "{";
265 bool first = true; 236 bool first = true;
266 for (size_t i = 0; i < N; ++i) { 237 for (size_t i = 0; i < N; ++i) {
267 if (!first) { 238 if (!first) {
268 os << ",\n"; 239 os << ",\n";
269 } else { 240 } else {
270 first = false; 241 first = false;
271 } 242 }
272 os << chunks[i]; 243 os << frames[i];
273 } 244 }
274 return os << "}"; 245 return os << "}";
275 } 246 }
276 247
277 // Convert a const array of InitFrameChunks to the format used at 248 // Convert a const array of InitFrame structs to the format used at
278 // runtime. Templated on the size of the array to save typing. 249 // runtime. Templated on the size of the array to save typing.
279 template <size_t N> 250 template <size_t N>
280 ScopedVector<WebSocketFrameChunk> CreateFrameChunkVector( 251 ScopedVector<WebSocketFrame> CreateFrameVector(
281 const InitFrameChunk (&source_chunks)[N]) { 252 const InitFrame (&source_frames)[N]) {
282 ScopedVector<WebSocketFrameChunk> result_chunks; 253 ScopedVector<WebSocketFrame> result_frames;
283 result_chunks.reserve(N); 254 result_frames.reserve(N);
284 for (size_t i = 0; i < N; ++i) { 255 for (size_t i = 0; i < N; ++i) {
285 scoped_ptr<WebSocketFrameChunk> result_chunk(new WebSocketFrameChunk); 256 const InitFrame& source_frame = source_frames[i];
286 size_t chunk_length = 257 scoped_ptr<WebSocketFrame> result_frame(
287 source_chunks[i].data ? strlen(source_chunks[i].data) : 0; 258 new WebSocketFrame(source_frame.opcode));
288 if (source_chunks[i].header.final != NO_HEADER) { 259 size_t frame_length = source_frame.data ? strlen(source_frame.data) : 0;
289 const InitFrameChunk::FrameHeader& source_header = 260 WebSocketFrameHeader& result_header = result_frame->header;
290 source_chunks[i].header; 261 result_header.final = (source_frame.final == FINAL_FRAME);
291 scoped_ptr<WebSocketFrameHeader> result_header( 262 result_header.masked = (source_frame.masked == MASKED);
292 new WebSocketFrameHeader(source_header.opcode)); 263 result_header.payload_length = frame_length;
293 result_header->final = (source_header.final == FINAL_FRAME); 264 if (source_frame.data) {
294 result_header->masked = (source_header.masked == MASKED); 265 result_frame->data = new IOBuffer(frame_length);
295 result_header->payload_length = source_header.payload_length; 266 memcpy(result_frame->data->data(), source_frame.data, frame_length);
296 DCHECK(chunk_length <= source_header.payload_length);
297 result_chunk->header.swap(result_header);
298 } 267 }
299 result_chunk->final_chunk = (source_chunks[i].final_chunk == FINAL_CHUNK); 268 result_frames.push_back(result_frame.release());
300 if (source_chunks[i].data) {
301 result_chunk->data = new IOBufferWithSize(chunk_length);
302 memcpy(result_chunk->data->data(), source_chunks[i].data, chunk_length);
303 }
304 result_chunks.push_back(result_chunk.release());
305 } 269 }
306 return result_chunks.Pass(); 270 return result_frames.Pass();
307 } 271 }
308 272
309 // A GoogleMock action which can be used to respond to call to ReadFrames with 273 // A GoogleMock action which can be used to respond to call to ReadFrames with
310 // some frames. Use like ReadFrames(_, _).WillOnce(ReturnChunks(&chunks)); 274 // some frames. Use like ReadFrames(_, _).WillOnce(ReturnFrames(&frames));
311 // |chunks| is an array of InitFrameChunks needs to be passed by pointer because 275 // |frames| is an array of InitFrame. |frames| needs to be passed by pointer
312 // otherwise it will be reduced to a pointer and lose the array size 276 // because otherwise it will be treated as a pointer and the array size
313 // information. 277 // information will be lost.
314 ACTION_P(ReturnChunks, source_chunks) { 278 ACTION_P(ReturnFrames, source_frames) {
315 *arg0 = CreateFrameChunkVector(*source_chunks); 279 *arg0 = CreateFrameVector(*source_frames);
316 return OK; 280 return OK;
317 } 281 }
318 282
319 // The implementation of a GoogleMock matcher which can be used to compare a 283 // The implementation of a GoogleMock matcher which can be used to compare a
320 // ScopedVector<WebSocketFrameChunk>* against an expectation defined as an array 284 // ScopedVector<WebSocketFrame>* against an expectation defined as an array of
321 // of InitFrameChunks. Although it is possible to compose built-in GoogleMock 285 // InitFrame objects. Although it is possible to compose built-in GoogleMock
322 // matchers to check the contents of a WebSocketFrameChunk, the results are so 286 // matchers to check the contents of a WebSocketFrame, the results are so
323 // unreadable that it is better to use this matcher. 287 // unreadable that it is better to use this matcher.
324 template <size_t N> 288 template <size_t N>
325 class EqualsChunksMatcher 289 class EqualsFramesMatcher
326 : public ::testing::MatcherInterface<ScopedVector<WebSocketFrameChunk>*> { 290 : public ::testing::MatcherInterface<ScopedVector<WebSocketFrame>*> {
327 public: 291 public:
328 EqualsChunksMatcher(const InitFrameChunk (*expect_chunks)[N]) 292 EqualsFramesMatcher(const InitFrame (*expect_frames)[N])
329 : expect_chunks_(expect_chunks) {} 293 : expect_frames_(expect_frames) {}
330 294
331 virtual bool MatchAndExplain(ScopedVector<WebSocketFrameChunk>* actual_chunks, 295 virtual bool MatchAndExplain(ScopedVector<WebSocketFrame>* actual_frames,
332 ::testing::MatchResultListener* listener) const { 296 ::testing::MatchResultListener* listener) const {
333 if (actual_chunks->size() != N) { 297 if (actual_frames->size() != N) {
334 *listener << "the vector size is " << actual_chunks->size(); 298 *listener << "the vector size is " << actual_frames->size();
335 return false; 299 return false;
336 } 300 }
337 for (size_t i = 0; i < N; ++i) { 301 for (size_t i = 0; i < N; ++i) {
338 const WebSocketFrameChunk& actual_chunk = *(*actual_chunks)[i]; 302 const WebSocketFrame& actual_frame = *(*actual_frames)[i];
339 const InitFrameChunk& expected_chunk = (*expect_chunks_)[i]; 303 const InitFrame& expected_frame = (*expect_frames_)[i];
340 // Testing that the absence or presence of a header is the same for both. 304 if (actual_frame.header.final != (expected_frame.final == FINAL_FRAME)) {
341 if ((!actual_chunk.header) != 305 *listener << "the frame is marked as "
342 (expected_chunk.header.final == NO_HEADER)) { 306 << (actual_frame.header.final ? "" : "not ") << "final";
343 *listener << "the header is "
344 << (actual_chunk.header ? "present" : "absent");
345 return false; 307 return false;
346 } 308 }
347 if (actual_chunk.header) { 309 if (actual_frame.header.opcode != expected_frame.opcode) {
348 if (actual_chunk.header->final != 310 *listener << "the opcode is " << actual_frame.header.opcode;
349 (expected_chunk.header.final == FINAL_FRAME)) {
350 *listener << "the frame is marked as "
351 << (actual_chunk.header->final ? "" : "not ") << "final";
352 return false;
353 }
354 if (actual_chunk.header->opcode != expected_chunk.header.opcode) {
355 *listener << "the opcode is " << actual_chunk.header->opcode;
356 return false;
357 }
358 if (actual_chunk.header->masked !=
359 (expected_chunk.header.masked == MASKED)) {
360 *listener << "the frame is "
361 << (actual_chunk.header->masked ? "masked" : "not masked");
362 return false;
363 }
364 if (actual_chunk.header->payload_length !=
365 expected_chunk.header.payload_length) {
366 *listener << "the payload length is "
367 << actual_chunk.header->payload_length;
368 return false;
369 }
370 }
371 if (actual_chunk.final_chunk !=
372 (expected_chunk.final_chunk == FINAL_CHUNK)) {
373 *listener << "the chunk is marked as "
374 << (actual_chunk.final_chunk ? "" : "not ") << "final";
375 return false; 311 return false;
376 } 312 }
377 if (actual_chunk.data->size() != 313 if (actual_frame.header.masked != (expected_frame.masked == MASKED)) {
378 base::checked_numeric_cast<int>(strlen(expected_chunk.data))) { 314 *listener << "the frame is "
379 *listener << "the data size is " << actual_chunk.data->size(); 315 << (actual_frame.header.masked ? "masked" : "not masked");
380 return false; 316 return false;
381 } 317 }
382 if (memcmp(actual_chunk.data->data(), 318 const size_t expected_length =
383 expected_chunk.data, 319 expected_frame.data ? strlen(expected_frame.data) : 0;
384 actual_chunk.data->size()) != 0) { 320 if (actual_frame.header.payload_length != expected_length) {
321 *listener << "the payload length is "
322 << actual_frame.header.payload_length;
323 return false;
324 }
325 if (expected_length != 0 &&
326 memcmp(actual_frame.data->data(),
327 expected_frame.data,
328 actual_frame.header.payload_length) != 0) {
385 *listener << "the data content differs"; 329 *listener << "the data content differs";
386 return false; 330 return false;
387 } 331 }
388 } 332 }
389 return true; 333 return true;
390 } 334 }
391 335
392 virtual void DescribeTo(std::ostream* os) const { 336 virtual void DescribeTo(std::ostream* os) const {
393 *os << "matches " << *expect_chunks_; 337 *os << "matches " << *expect_frames_;
394 } 338 }
395 339
396 virtual void DescribeNegationTo(std::ostream* os) const { 340 virtual void DescribeNegationTo(std::ostream* os) const {
397 *os << "does not match " << *expect_chunks_; 341 *os << "does not match " << *expect_frames_;
398 } 342 }
399 343
400 private: 344 private:
401 const InitFrameChunk (*expect_chunks_)[N]; 345 const InitFrame (*expect_frames_)[N];
402 }; 346 };
403 347
404 // The definition of EqualsChunks GoogleMock matcher. Unlike the ReturnChunks 348 // The definition of EqualsFrames GoogleMock matcher. Unlike the ReturnFrames
405 // action, this can take the array by reference. 349 // action, this can take the array by reference.
406 template <size_t N> 350 template <size_t N>
407 ::testing::Matcher<ScopedVector<WebSocketFrameChunk>*> EqualsChunks( 351 ::testing::Matcher<ScopedVector<WebSocketFrame>*> EqualsFrames(
408 const InitFrameChunk (&chunks)[N]) { 352 const InitFrame (&frames)[N]) {
409 return ::testing::MakeMatcher(new EqualsChunksMatcher<N>(&chunks)); 353 return ::testing::MakeMatcher(new EqualsFramesMatcher<N>(&frames));
410 } 354 }
411 355
412 // A FakeWebSocketStream whose ReadFrames() function returns data. 356 // A FakeWebSocketStream whose ReadFrames() function returns data.
413 class ReadableFakeWebSocketStream : public FakeWebSocketStream { 357 class ReadableFakeWebSocketStream : public FakeWebSocketStream {
414 public: 358 public:
415 enum IsSync { 359 enum IsSync {
416 SYNC, 360 SYNC,
417 ASYNC 361 ASYNC
418 }; 362 };
419 363
420 // After constructing the object, call PrepareReadFrames() once for each 364 // After constructing the object, call PrepareReadFrames() once for each
421 // time you wish it to return from the test. 365 // time you wish it to return from the test.
422 ReadableFakeWebSocketStream() : index_(0), read_frames_pending_(false) {} 366 ReadableFakeWebSocketStream() : index_(0), read_frames_pending_(false) {}
423 367
424 // Check that all the prepared responses have been consumed. 368 // Check that all the prepared responses have been consumed.
425 virtual ~ReadableFakeWebSocketStream() { 369 virtual ~ReadableFakeWebSocketStream() {
426 CHECK(index_ >= responses_.size()); 370 CHECK(index_ >= responses_.size());
427 CHECK(!read_frames_pending_); 371 CHECK(!read_frames_pending_);
428 } 372 }
429 373
430 // Prepares a fake responses. Fake responses will be returned from 374 // Prepares a fake response. Fake responses will be returned from ReadFrames()
431 // ReadFrames() in the same order they were prepared with PrepareReadFrames() 375 // in the same order they were prepared with PrepareReadFrames() and
432 // and PrepareReadFramesError(). If |async| is ASYNC, then ReadFrames() will 376 // PrepareReadFramesError(). If |async| is ASYNC, then ReadFrames() will
433 // return ERR_IO_PENDING and the callback will be scheduled to run on the 377 // return ERR_IO_PENDING and the callback will be scheduled to run on the
434 // message loop. This requires the test case to run the message loop. If 378 // message loop. This requires the test case to run the message loop. If
435 // |async| is SYNC, the response will be returned synchronously. |error| is 379 // |async| is SYNC, the response will be returned synchronously. |error| is
436 // returned directly from ReadFrames() in the synchronous case, or passed to 380 // returned directly from ReadFrames() in the synchronous case, or passed to
437 // the callback in the asynchronous case. |chunks| will be converted to a 381 // the callback in the asynchronous case. |frames| will be converted to a
438 // ScopedVector<WebSocketFrameChunks> and copied to the pointer that was 382 // ScopedVector<WebSocketFrame> and copied to the pointer that was passed to
439 // passed to ReadFrames(). 383 // ReadFrames().
440 template <size_t N> 384 template <size_t N>
441 void PrepareReadFrames(IsSync async, 385 void PrepareReadFrames(IsSync async,
442 int error, 386 int error,
443 const InitFrameChunk (&chunks)[N]) { 387 const InitFrame (&frames)[N]) {
444 responses_.push_back( 388 responses_.push_back(new Response(async, error, CreateFrameVector(frames)));
445 new Response(async, error, CreateFrameChunkVector(chunks)));
446 } 389 }
447 390
448 // An alternate version of PrepareReadFrames for when we need to construct 391 // An alternate version of PrepareReadFrames for when we need to construct
449 // the frames manually. 392 // the frames manually.
450 void PrepareRawReadFrames(IsSync async, 393 void PrepareRawReadFrames(IsSync async,
451 int error, 394 int error,
452 ScopedVector<WebSocketFrameChunk> chunks) { 395 ScopedVector<WebSocketFrame> frames) {
453 responses_.push_back(new Response(async, error, chunks.Pass())); 396 responses_.push_back(new Response(async, error, frames.Pass()));
454 } 397 }
455 398
456 // Prepares a fake error response (ie. there is no data). 399 // Prepares a fake error response (ie. there is no data).
457 void PrepareReadFramesError(IsSync async, int error) { 400 void PrepareReadFramesError(IsSync async, int error) {
458 responses_.push_back( 401 responses_.push_back(
459 new Response(async, error, ScopedVector<WebSocketFrameChunk>())); 402 new Response(async, error, ScopedVector<WebSocketFrame>()));
460 } 403 }
461 404
462 virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 405 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
463 const CompletionCallback& callback) OVERRIDE { 406 const CompletionCallback& callback) OVERRIDE {
464 CHECK(!read_frames_pending_); 407 CHECK(!read_frames_pending_);
465 if (index_ >= responses_.size()) 408 if (index_ >= responses_.size())
466 return ERR_IO_PENDING; 409 return ERR_IO_PENDING;
467 if (responses_[index_]->async == ASYNC) { 410 if (responses_[index_]->async == ASYNC) {
468 read_frames_pending_ = true; 411 read_frames_pending_ = true;
469 base::MessageLoop::current()->PostTask( 412 base::MessageLoop::current()->PostTask(
470 FROM_HERE, 413 FROM_HERE,
471 base::Bind(&ReadableFakeWebSocketStream::DoCallback, 414 base::Bind(&ReadableFakeWebSocketStream::DoCallback,
472 base::Unretained(this), 415 base::Unretained(this),
473 frame_chunks, 416 frames,
474 callback)); 417 callback));
475 return ERR_IO_PENDING; 418 return ERR_IO_PENDING;
476 } else { 419 } else {
477 frame_chunks->swap(responses_[index_]->chunks); 420 frames->swap(responses_[index_]->frames);
478 return responses_[index_++]->error; 421 return responses_[index_++]->error;
479 } 422 }
480 } 423 }
481 424
482 private: 425 private:
483 void DoCallback(ScopedVector<WebSocketFrameChunk>* frame_chunks, 426 void DoCallback(ScopedVector<WebSocketFrame>* frames,
484 const CompletionCallback& callback) { 427 const CompletionCallback& callback) {
485 read_frames_pending_ = false; 428 read_frames_pending_ = false;
486 frame_chunks->swap(responses_[index_]->chunks); 429 frames->swap(responses_[index_]->frames);
487 callback.Run(responses_[index_++]->error); 430 callback.Run(responses_[index_++]->error);
488 return; 431 return;
489 } 432 }
490 433
491 struct Response { 434 struct Response {
492 Response(IsSync async, int error, ScopedVector<WebSocketFrameChunk> chunks) 435 Response(IsSync async, int error, ScopedVector<WebSocketFrame> frames)
493 : async(async), error(error), chunks(chunks.Pass()) {} 436 : async(async), error(error), frames(frames.Pass()) {}
494 437
495 IsSync async; 438 IsSync async;
496 int error; 439 int error;
497 ScopedVector<WebSocketFrameChunk> chunks; 440 ScopedVector<WebSocketFrame> frames;
498 441
499 private: 442 private:
500 // Bad things will happen if we attempt to copy or assign "chunks". 443 // Bad things will happen if we attempt to copy or assign |frames|.
501 DISALLOW_COPY_AND_ASSIGN(Response); 444 DISALLOW_COPY_AND_ASSIGN(Response);
502 }; 445 };
503 ScopedVector<Response> responses_; 446 ScopedVector<Response> responses_;
504 447
505 // The index into the responses_ array of the next response to be returned. 448 // The index into the responses_ array of the next response to be returned.
506 size_t index_; 449 size_t index_;
507 450
508 // True when an async response from ReadFrames() is pending. This only applies 451 // True when an async response from ReadFrames() is pending. This only applies
509 // to "real" async responses. Once all the prepared responses have been 452 // to "real" async responses. Once all the prepared responses have been
510 // returned, ReadFrames() returns ERR_IO_PENDING but read_frames_pending_ is 453 // returned, ReadFrames() returns ERR_IO_PENDING but read_frames_pending_ is
511 // not set to true. 454 // not set to true.
512 bool read_frames_pending_; 455 bool read_frames_pending_;
513 }; 456 };
514 457
515 // A FakeWebSocketStream where writes always complete successfully and 458 // A FakeWebSocketStream where writes always complete successfully and
516 // synchronously. 459 // synchronously.
517 class WriteableFakeWebSocketStream : public FakeWebSocketStream { 460 class WriteableFakeWebSocketStream : public FakeWebSocketStream {
518 public: 461 public:
519 virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 462 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
520 const CompletionCallback& callback) OVERRIDE { 463 const CompletionCallback& callback) OVERRIDE {
521 return OK; 464 return OK;
522 } 465 }
523 }; 466 };
524 467
525 // A FakeWebSocketStream where writes always fail. 468 // A FakeWebSocketStream where writes always fail.
526 class UnWriteableFakeWebSocketStream : public FakeWebSocketStream { 469 class UnWriteableFakeWebSocketStream : public FakeWebSocketStream {
527 public: 470 public:
528 virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 471 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
529 const CompletionCallback& callback) OVERRIDE { 472 const CompletionCallback& callback) OVERRIDE {
530 return ERR_CONNECTION_RESET; 473 return ERR_CONNECTION_RESET;
531 } 474 }
532 }; 475 };
533 476
534 // A FakeWebSocketStream which echoes any frames written back. Clears the 477 // A FakeWebSocketStream which echoes any frames written back. Clears the
535 // "masked" header bit, but makes no other checks for validity. Tests using this 478 // "masked" header bit, but makes no other checks for validity. Tests using this
536 // must run the MessageLoop to receive the callback(s). If a message with opcode 479 // must run the MessageLoop to receive the callback(s). If a message with opcode
537 // Close is echoed, then an ERR_CONNECTION_CLOSED is returned in the next 480 // Close is echoed, then an ERR_CONNECTION_CLOSED is returned in the next
538 // callback. The test must do something to cause WriteFrames() to be called, 481 // callback. The test must do something to cause WriteFrames() to be called,
539 // otherwise the ReadFrames() callback will never be called. 482 // otherwise the ReadFrames() callback will never be called.
540 class EchoeyFakeWebSocketStream : public FakeWebSocketStream { 483 class EchoeyFakeWebSocketStream : public FakeWebSocketStream {
541 public: 484 public:
542 EchoeyFakeWebSocketStream() : read_frame_chunks_(NULL), done_(false) {} 485 EchoeyFakeWebSocketStream() : read_frames_(NULL), done_(false) {}
543 486
544 virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 487 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
545 const CompletionCallback& callback) OVERRIDE { 488 const CompletionCallback& callback) OVERRIDE {
546 // Users of WebSocketStream will not expect the ReadFrames() callback to be 489 // Users of WebSocketStream will not expect the ReadFrames() callback to be
547 // called from within WriteFrames(), so post it to the message loop instead. 490 // called from within WriteFrames(), so post it to the message loop instead.
548 stored_frame_chunks_.insert( 491 stored_frames_.insert(stored_frames_.end(), frames->begin(), frames->end());
549 stored_frame_chunks_.end(), frame_chunks->begin(), frame_chunks->end()); 492 frames->weak_clear();
550 frame_chunks->weak_clear();
551 PostCallback(); 493 PostCallback();
552 return OK; 494 return OK;
553 } 495 }
554 496
555 virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 497 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
556 const CompletionCallback& callback) OVERRIDE { 498 const CompletionCallback& callback) OVERRIDE {
557 read_callback_ = callback; 499 read_callback_ = callback;
558 read_frame_chunks_ = frame_chunks; 500 read_frames_ = frames;
559 if (done_) 501 if (done_)
560 PostCallback(); 502 PostCallback();
561 return ERR_IO_PENDING; 503 return ERR_IO_PENDING;
562 } 504 }
563 505
564 private: 506 private:
565 void PostCallback() { 507 void PostCallback() {
566 base::MessageLoop::current()->PostTask( 508 base::MessageLoop::current()->PostTask(
567 FROM_HERE, 509 FROM_HERE,
568 base::Bind(&EchoeyFakeWebSocketStream::DoCallback, 510 base::Bind(&EchoeyFakeWebSocketStream::DoCallback,
569 base::Unretained(this))); 511 base::Unretained(this)));
570 } 512 }
571 513
572 void DoCallback() { 514 void DoCallback() {
573 if (done_) { 515 if (done_) {
574 read_callback_.Run(ERR_CONNECTION_CLOSED); 516 read_callback_.Run(ERR_CONNECTION_CLOSED);
575 } else if (!stored_frame_chunks_.empty()) { 517 } else if (!stored_frames_.empty()) {
576 done_ = MoveFrameChunks(read_frame_chunks_); 518 done_ = MoveFrames(read_frames_);
577 read_frame_chunks_ = NULL; 519 read_frames_ = NULL;
578 read_callback_.Run(OK); 520 read_callback_.Run(OK);
579 } 521 }
580 } 522 }
581 523
582 // Copy the chunks stored in stored_frame_chunks_ to |out|, while clearing the 524 // Copy the frames stored in stored_frames_ to |out|, while clearing the
583 // "masked" header bit. Returns true if a Close Frame was seen, false 525 // "masked" header bit. Returns true if a Close Frame was seen, false
584 // otherwise. 526 // otherwise.
585 bool MoveFrameChunks(ScopedVector<WebSocketFrameChunk>* out) { 527 bool MoveFrames(ScopedVector<WebSocketFrame>* out) {
586 bool seen_close = false; 528 bool seen_close = false;
587 *out = stored_frame_chunks_.Pass(); 529 *out = stored_frames_.Pass();
588 for (ScopedVector<WebSocketFrameChunk>::iterator it = out->begin(); 530 for (ScopedVector<WebSocketFrame>::iterator it = out->begin();
589 it != out->end(); 531 it != out->end();
590 ++it) { 532 ++it) {
591 WebSocketFrameHeader* header = (*it)->header.get(); 533 WebSocketFrameHeader& header = (*it)->header;
592 if (header) { 534 header.masked = false;
593 header->masked = false; 535 if (header.opcode == WebSocketFrameHeader::kOpCodeClose)
594 if (header->opcode == WebSocketFrameHeader::kOpCodeClose) 536 seen_close = true;
595 seen_close = true;
596 }
597 } 537 }
598 return seen_close; 538 return seen_close;
599 } 539 }
600 540
601 ScopedVector<WebSocketFrameChunk> stored_frame_chunks_; 541 ScopedVector<WebSocketFrame> stored_frames_;
602 CompletionCallback read_callback_; 542 CompletionCallback read_callback_;
603 // Owned by the caller of ReadFrames(). 543 // Owned by the caller of ReadFrames().
604 ScopedVector<WebSocketFrameChunk>* read_frame_chunks_; 544 ScopedVector<WebSocketFrame>* read_frames_;
605 // True if we should close the connection. 545 // True if we should close the connection.
606 bool done_; 546 bool done_;
607 }; 547 };
608 548
609 // A FakeWebSocketStream where writes trigger a connection reset. 549 // A FakeWebSocketStream where writes trigger a connection reset.
610 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous 550 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous
611 // and triggers ReadFrames to return a reset as well. Tests using this need to 551 // and triggers ReadFrames to return a reset as well. Tests using this need to
612 // run the message loop. 552 // run the message loop.
613 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { 553 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream {
614 public: 554 public:
615 virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 555 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames,
616 const CompletionCallback& callback) OVERRIDE { 556 const CompletionCallback& callback) OVERRIDE {
617 base::MessageLoop::current()->PostTask( 557 base::MessageLoop::current()->PostTask(
618 FROM_HERE, base::Bind(callback, ERR_CONNECTION_RESET)); 558 FROM_HERE, base::Bind(callback, ERR_CONNECTION_RESET));
619 base::MessageLoop::current()->PostTask( 559 base::MessageLoop::current()->PostTask(
620 FROM_HERE, base::Bind(read_callback_, ERR_CONNECTION_RESET)); 560 FROM_HERE, base::Bind(read_callback_, ERR_CONNECTION_RESET));
621 return ERR_IO_PENDING; 561 return ERR_IO_PENDING;
622 } 562 }
623 563
624 virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, 564 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames,
625 const CompletionCallback& callback) OVERRIDE { 565 const CompletionCallback& callback) OVERRIDE {
626 read_callback_ = callback; 566 read_callback_ = callback;
627 return ERR_IO_PENDING; 567 return ERR_IO_PENDING;
628 } 568 }
629 569
630 private: 570 private:
631 CompletionCallback read_callback_; 571 CompletionCallback read_callback_;
632 }; 572 };
633 573
634 // This mock is for verifying that WebSocket protocol semantics are obeyed (to 574 // This mock is for verifying that WebSocket protocol semantics are obeyed (to
635 // the extent that they are implemented in WebSocketCommon). 575 // the extent that they are implemented in WebSocketCommon).
636 class MockWebSocketStream : public WebSocketStream { 576 class MockWebSocketStream : public WebSocketStream {
637 public: 577 public:
638 MOCK_METHOD2(ReadFrames, 578 MOCK_METHOD2(ReadFrames,
639 int(ScopedVector<WebSocketFrameChunk>* frame_chunks, 579 int(ScopedVector<WebSocketFrame>* frames,
640 const CompletionCallback& callback)); 580 const CompletionCallback& callback));
641 MOCK_METHOD2(WriteFrames, 581 MOCK_METHOD2(WriteFrames,
642 int(ScopedVector<WebSocketFrameChunk>* frame_chunks, 582 int(ScopedVector<WebSocketFrame>* frames,
643 const CompletionCallback& callback)); 583 const CompletionCallback& callback));
644 MOCK_METHOD0(Close, void()); 584 MOCK_METHOD0(Close, void());
645 MOCK_CONST_METHOD0(GetSubProtocol, std::string()); 585 MOCK_CONST_METHOD0(GetSubProtocol, std::string());
646 MOCK_CONST_METHOD0(GetExtensions, std::string()); 586 MOCK_CONST_METHOD0(GetExtensions, std::string());
647 MOCK_METHOD0(AsWebSocketStream, WebSocketStream*()); 587 MOCK_METHOD0(AsWebSocketStream, WebSocketStream*());
648 MOCK_METHOD4(SendHandshakeRequest, 588 MOCK_METHOD4(SendHandshakeRequest,
649 int(const GURL& url, 589 int(const GURL& url,
650 const HttpRequestHeaders& headers, 590 const HttpRequestHeaders& headers,
651 HttpResponseInfo* response_info, 591 HttpResponseInfo* response_info,
652 const CompletionCallback& callback)); 592 const CompletionCallback& callback));
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 connect_data_.factory.url_request_context); 779 connect_data_.factory.url_request_context);
840 } 780 }
841 781
842 // The documentation for WebSocketEventInterface::OnAddChannelResponse() says 782 // The documentation for WebSocketEventInterface::OnAddChannelResponse() says
843 // that if the first argument is true, ie. the connection failed, then we can 783 // that if the first argument is true, ie. the connection failed, then we can
844 // safely synchronously delete the WebSocketChannel. This test will only 784 // safely synchronously delete the WebSocketChannel. This test will only
845 // reliably find problems if run with a memory debugger such as 785 // reliably find problems if run with a memory debugger such as
846 // AddressSanitizer. 786 // AddressSanitizer.
847 TEST_F(WebSocketChannelDeletingTest, DeletingFromOnAddChannelResponseWorks) { 787 TEST_F(WebSocketChannelDeletingTest, DeletingFromOnAddChannelResponseWorks) {
848 CreateChannelAndConnect(); 788 CreateChannelAndConnect();
849 connect_data_.factory.connect_delegate 789 connect_data_.factory.connect_delegate->OnFailure(
850 ->OnFailure(kWebSocketErrorNoStatusReceived); 790 kWebSocketErrorNoStatusReceived);
851 EXPECT_EQ(NULL, channel_.get()); 791 EXPECT_EQ(NULL, channel_.get());
852 } 792 }
853 793
854 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { 794 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) {
855 // false means success. 795 // false means success.
856 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "")); 796 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, ""));
857 // OnFlowControl is always called immediately after connect to provide initial 797 // OnFlowControl is always called immediately after connect to provide initial
858 // quota to the renderer. 798 // quota to the renderer.
859 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 799 EXPECT_CALL(*event_interface_, OnFlowControl(_));
860 800
861 CreateChannelAndConnect(); 801 CreateChannelAndConnect();
862 802
863 connect_data_.factory.connect_delegate->OnSuccess(stream_.Pass()); 803 connect_data_.factory.connect_delegate->OnSuccess(stream_.Pass());
864 } 804 }
865 805
866 TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) { 806 TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) {
867 // true means failure. 807 // true means failure.
868 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "")); 808 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, ""));
869 809
870 CreateChannelAndConnect(); 810 CreateChannelAndConnect();
871 811
872 connect_data_.factory.connect_delegate 812 connect_data_.factory.connect_delegate->OnFailure(
873 ->OnFailure(kWebSocketErrorNoStatusReceived); 813 kWebSocketErrorNoStatusReceived);
874 } 814 }
875 815
876 TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { 816 TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) {
877 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "Bob")); 817 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "Bob"));
878 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 818 EXPECT_CALL(*event_interface_, OnFlowControl(_));
879 819
880 CreateChannelAndConnect(); 820 CreateChannelAndConnect();
881 821
882 connect_data_.factory.connect_delegate->OnSuccess( 822 connect_data_.factory.connect_delegate->OnSuccess(
883 scoped_ptr<WebSocketStream>(new FakeWebSocketStream("Bob", ""))); 823 scoped_ptr<WebSocketStream>(new FakeWebSocketStream("Bob", "")));
884 } 824 }
885 825
886 // The first frames from the server can arrive together with the handshake, in 826 // The first frames from the server can arrive together with the handshake, in
887 // which case they will be available as soon as ReadFrames() is called the first 827 // which case they will be available as soon as ReadFrames() is called the first
888 // time. 828 // time.
889 TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) { 829 TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) {
890 scoped_ptr<ReadableFakeWebSocketStream> stream( 830 scoped_ptr<ReadableFakeWebSocketStream> stream(
891 new ReadableFakeWebSocketStream); 831 new ReadableFakeWebSocketStream);
892 static const InitFrameChunk chunks[] = { 832 static const InitFrame frames[] = {
893 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, 833 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
894 FINAL_CHUNK, "HELLO"}}; 834 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
895 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks);
896 set_stream(stream.Pass()); 835 set_stream(stream.Pass());
897 { 836 {
898 InSequence s; 837 InSequence s;
899 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 838 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
900 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 839 EXPECT_CALL(*event_interface_, OnFlowControl(_));
901 EXPECT_CALL( 840 EXPECT_CALL(
902 *event_interface_, 841 *event_interface_,
903 OnDataFrame( 842 OnDataFrame(
904 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 843 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO")));
905 } 844 }
906 845
907 CreateChannelAndConnectSuccessfully(); 846 CreateChannelAndConnectSuccessfully();
908 } 847 }
909 848
910 // A remote server could accept the handshake, but then immediately send a 849 // A remote server could accept the handshake, but then immediately send a
911 // Close frame. 850 // Close frame.
912 TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) { 851 TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) {
913 scoped_ptr<ReadableFakeWebSocketStream> stream( 852 scoped_ptr<ReadableFakeWebSocketStream> stream(
914 new ReadableFakeWebSocketStream); 853 new ReadableFakeWebSocketStream);
915 static const InitFrameChunk chunks[] = { 854 static const InitFrame frames[] = {
916 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 23}, 855 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
917 FINAL_CHUNK, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}}; 856 NOT_MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}};
918 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks); 857 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
919 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 858 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
920 ERR_CONNECTION_CLOSED); 859 ERR_CONNECTION_CLOSED);
921 set_stream(stream.Pass()); 860 set_stream(stream.Pass());
922 { 861 {
923 InSequence s; 862 InSequence s;
924 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 863 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
925 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 864 EXPECT_CALL(*event_interface_, OnFlowControl(_));
926 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 865 EXPECT_CALL(*event_interface_, OnClosingHandshake());
927 EXPECT_CALL(*event_interface_, 866 EXPECT_CALL(*event_interface_,
928 OnDropChannel(kWebSocketErrorInternalServerError, 867 OnDropChannel(kWebSocketErrorInternalServerError,
(...skipping 18 matching lines...) Expand all
947 EXPECT_CALL(*event_interface_, 886 EXPECT_CALL(*event_interface_,
948 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); 887 OnDropChannel(kWebSocketErrorAbnormalClosure, _));
949 } 888 }
950 889
951 CreateChannelAndConnectSuccessfully(); 890 CreateChannelAndConnectSuccessfully();
952 } 891 }
953 892
954 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { 893 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) {
955 scoped_ptr<ReadableFakeWebSocketStream> stream( 894 scoped_ptr<ReadableFakeWebSocketStream> stream(
956 new ReadableFakeWebSocketStream); 895 new ReadableFakeWebSocketStream);
957 static const InitFrameChunk chunks[] = { 896 static const InitFrame frames[] = {
958 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, 897 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
959 FINAL_CHUNK, "HELLO"}};
960 // We use this checkpoint object to verify that the callback isn't called 898 // We use this checkpoint object to verify that the callback isn't called
961 // until we expect it to be. 899 // until we expect it to be.
962 MockFunction<void(int)> checkpoint; 900 MockFunction<void(int)> checkpoint;
963 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); 901 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
964 set_stream(stream.Pass()); 902 set_stream(stream.Pass());
965 { 903 {
966 InSequence s; 904 InSequence s;
967 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 905 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
968 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 906 EXPECT_CALL(*event_interface_, OnFlowControl(_));
969 EXPECT_CALL(checkpoint, Call(1)); 907 EXPECT_CALL(checkpoint, Call(1));
970 EXPECT_CALL( 908 EXPECT_CALL(
971 *event_interface_, 909 *event_interface_,
972 OnDataFrame( 910 OnDataFrame(
973 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 911 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO")));
974 EXPECT_CALL(checkpoint, Call(2)); 912 EXPECT_CALL(checkpoint, Call(2));
975 } 913 }
976 914
977 CreateChannelAndConnectSuccessfully(); 915 CreateChannelAndConnectSuccessfully();
978 checkpoint.Call(1); 916 checkpoint.Call(1);
979 base::MessageLoop::current()->RunUntilIdle(); 917 base::MessageLoop::current()->RunUntilIdle();
980 checkpoint.Call(2); 918 checkpoint.Call(2);
981 } 919 }
982 920
983 // Extra data can arrive while a read is being processed, resulting in the next 921 // Extra data can arrive while a read is being processed, resulting in the next
984 // read completing synchronously. 922 // read completing synchronously.
985 TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) { 923 TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) {
986 scoped_ptr<ReadableFakeWebSocketStream> stream( 924 scoped_ptr<ReadableFakeWebSocketStream> stream(
987 new ReadableFakeWebSocketStream); 925 new ReadableFakeWebSocketStream);
988 static const InitFrameChunk chunks1[] = { 926 static const InitFrame frames1[] = {
989 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, 927 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
990 FINAL_CHUNK, "HELLO"}}; 928 static const InitFrame frames2[] = {
991 static const InitFrameChunk chunks2[] = { 929 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "WORLD"}};
992 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, 930 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1);
993 FINAL_CHUNK, "WORLD"}}; 931 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames2);
994 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1);
995 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks2);
996 set_stream(stream.Pass()); 932 set_stream(stream.Pass());
997 { 933 {
998 InSequence s; 934 InSequence s;
999 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 935 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1000 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 936 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1001 EXPECT_CALL( 937 EXPECT_CALL(
1002 *event_interface_, 938 *event_interface_,
1003 OnDataFrame( 939 OnDataFrame(
1004 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 940 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO")));
1005 EXPECT_CALL( 941 EXPECT_CALL(
1006 *event_interface_, 942 *event_interface_,
1007 OnDataFrame( 943 OnDataFrame(
1008 true, WebSocketFrameHeader::kOpCodeText, AsVector("WORLD"))); 944 true, WebSocketFrameHeader::kOpCodeText, AsVector("WORLD")));
1009 } 945 }
1010 946
1011 CreateChannelAndConnectSuccessfully(); 947 CreateChannelAndConnectSuccessfully();
1012 base::MessageLoop::current()->RunUntilIdle(); 948 base::MessageLoop::current()->RunUntilIdle();
1013 } 949 }
1014 950
1015 // Data frames that arrive in fragments are turned into individual frames 951 // Data frames are delivered the same regardless of how many reads they arrive
1016 TEST_F(WebSocketChannelEventInterfaceTest, FragmentedFrames) { 952 // as.
953 TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) {
1017 scoped_ptr<ReadableFakeWebSocketStream> stream( 954 scoped_ptr<ReadableFakeWebSocketStream> stream(
1018 new ReadableFakeWebSocketStream); 955 new ReadableFakeWebSocketStream);
1019 // Here we have one message split into 3 frames which arrive in 3 chunks. The 956 // Here we have one message which arrived in five frames split across three
1020 // first frame is entirely in the first chunk, the second frame is split 957 // reads. It may have been reframed on arrival, but this class doesn't care
1021 // across all the chunks, and the final frame is entirely in the final 958 // about that.
1022 // chunk. The frame fragments are converted to separate frames so that they 959 static const InitFrame frames1[] = {
1023 // can be delivered immediatedly. So the EventInterface should see a Text 960 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "THREE"},
1024 // message with 5 frames. 961 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1025 static const InitFrameChunk chunks1[] = { 962 NOT_MASKED, " "}};
1026 {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, 963 static const InitFrame frames2[] = {
1027 FINAL_CHUNK, "THREE"}, 964 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1028 {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 965 NOT_MASKED, "SMALL"}};
1029 7}, 966 static const InitFrame frames3[] = {
1030 NOT_FINAL_CHUNK, " "}}; 967 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1031 static const InitFrameChunk chunks2[] = { 968 NOT_MASKED, " "},
1032 {{NO_HEADER}, NOT_FINAL_CHUNK, "SMALL"}}; 969 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1033 static const InitFrameChunk chunks3[] = { 970 NOT_MASKED, "FRAMES"}};
1034 {{NO_HEADER}, FINAL_CHUNK, " "}, 971 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1);
1035 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 6}, 972 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2);
1036 FINAL_CHUNK, "FRAMES"}}; 973 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3);
1037 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1);
1038 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2);
1039 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3);
1040 set_stream(stream.Pass()); 974 set_stream(stream.Pass());
1041 { 975 {
1042 InSequence s; 976 InSequence s;
1043 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 977 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1044 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 978 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1045 EXPECT_CALL( 979 EXPECT_CALL(
1046 *event_interface_, 980 *event_interface_,
1047 OnDataFrame( 981 OnDataFrame(
1048 false, WebSocketFrameHeader::kOpCodeText, AsVector("THREE"))); 982 false, WebSocketFrameHeader::kOpCodeText, AsVector("THREE")));
1049 EXPECT_CALL( 983 EXPECT_CALL(
(...skipping 11 matching lines...) Expand all
1061 EXPECT_CALL(*event_interface_, 995 EXPECT_CALL(*event_interface_,
1062 OnDataFrame(true, 996 OnDataFrame(true,
1063 WebSocketFrameHeader::kOpCodeContinuation, 997 WebSocketFrameHeader::kOpCodeContinuation,
1064 AsVector("FRAMES"))); 998 AsVector("FRAMES")));
1065 } 999 }
1066 1000
1067 CreateChannelAndConnectSuccessfully(); 1001 CreateChannelAndConnectSuccessfully();
1068 base::MessageLoop::current()->RunUntilIdle(); 1002 base::MessageLoop::current()->RunUntilIdle();
1069 } 1003 }
1070 1004
1071 // In the case when a single-frame message because fragmented, it must be
1072 // correctly transformed to multiple frames.
1073 TEST_F(WebSocketChannelEventInterfaceTest, MessageFragmentation) {
1074 scoped_ptr<ReadableFakeWebSocketStream> stream(
1075 new ReadableFakeWebSocketStream);
1076 // A single-frame Text message arrives in three chunks. This should be
1077 // delivered as three frames.
1078 static const InitFrameChunk chunks1[] = {
1079 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 12},
1080 NOT_FINAL_CHUNK, "TIME"}};
1081 static const InitFrameChunk chunks2[] = {
1082 {{NO_HEADER}, NOT_FINAL_CHUNK, " FOR "}};
1083 static const InitFrameChunk chunks3[] = {{{NO_HEADER}, FINAL_CHUNK, "TEA"}};
1084 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1);
1085 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2);
1086 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3);
1087 set_stream(stream.Pass());
1088 {
1089 InSequence s;
1090 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1091 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1092 EXPECT_CALL(
1093 *event_interface_,
1094 OnDataFrame(
1095 false, WebSocketFrameHeader::kOpCodeText, AsVector("TIME")));
1096 EXPECT_CALL(*event_interface_,
1097 OnDataFrame(false,
1098 WebSocketFrameHeader::kOpCodeContinuation,
1099 AsVector(" FOR ")));
1100 EXPECT_CALL(
1101 *event_interface_,
1102 OnDataFrame(
1103 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("TEA")));
1104 }
1105
1106 CreateChannelAndConnectSuccessfully();
1107 base::MessageLoop::current()->RunUntilIdle();
1108 }
1109
1110 // If a control message is fragmented, it must be re-assembled before being
1111 // delivered. A control message can only be fragmented at the network level; it
1112 // is not permitted to be split into multiple frames.
1113 TEST_F(WebSocketChannelEventInterfaceTest, FragmentedControlMessage) {
1114 scoped_ptr<ReadableFakeWebSocketStream> stream(
1115 new ReadableFakeWebSocketStream);
1116 static const InitFrameChunk chunks1[] = {
1117 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7},
1118 NOT_FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "")}};
1119 static const InitFrameChunk chunks2[] = {
1120 {{NO_HEADER}, NOT_FINAL_CHUNK, "Clo"}};
1121 static const InitFrameChunk chunks3[] = {{{NO_HEADER}, FINAL_CHUNK, "se"}};
1122 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1);
1123 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2);
1124 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3);
1125 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
1126 ERR_CONNECTION_CLOSED);
1127 set_stream(stream.Pass());
1128 {
1129 InSequence s;
1130 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1131 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1132 EXPECT_CALL(*event_interface_, OnClosingHandshake());
1133 EXPECT_CALL(*event_interface_,
1134 OnDropChannel(kWebSocketNormalClosure, "Close"));
1135 }
1136
1137 CreateChannelAndConnectSuccessfully();
1138 base::MessageLoop::current()->RunUntilIdle();
1139 }
1140
1141 // The payload of a control frame is not permitted to exceed 125 bytes. RFC6455
1142 // 5.5 "All control frames MUST have a payload length of 125 bytes or less"
1143 TEST_F(WebSocketChannelEventInterfaceTest, OversizeControlMessageIsRejected) {
1144 scoped_ptr<ReadableFakeWebSocketStream> stream(
1145 new ReadableFakeWebSocketStream);
1146 static const size_t kPayloadLen = 126;
1147 char payload[kPayloadLen + 1]; // allow space for trailing NUL
1148 std::fill(payload, payload + kPayloadLen, 'A');
1149 payload[kPayloadLen] = '\0';
1150 // Not static because "payload" is constructed at runtime.
1151 const InitFrameChunk chunks[] = {
1152 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED,
1153 kPayloadLen},
1154 FINAL_CHUNK, payload}};
1155 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks);
1156 set_stream(stream.Pass());
1157
1158 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1159 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1160 EXPECT_CALL(*event_interface_,
1161 OnDropChannel(kWebSocketErrorProtocolError, _));
1162
1163 CreateChannelAndConnectSuccessfully();
1164 }
1165
1166 // A control frame is not permitted to be split into multiple frames. RFC6455 1005 // A control frame is not permitted to be split into multiple frames. RFC6455
1167 // 5.5 "All control frames ... MUST NOT be fragmented." 1006 // 5.5 "All control frames ... MUST NOT be fragmented."
1168 TEST_F(WebSocketChannelEventInterfaceTest, MultiFrameControlMessageIsRejected) { 1007 TEST_F(WebSocketChannelEventInterfaceTest, MultiFrameControlMessageIsRejected) {
1169 scoped_ptr<ReadableFakeWebSocketStream> stream( 1008 scoped_ptr<ReadableFakeWebSocketStream> stream(
1170 new ReadableFakeWebSocketStream); 1009 new ReadableFakeWebSocketStream);
1171 static const InitFrameChunk chunks[] = { 1010 static const InitFrame frames[] = {
1172 {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 2}, 1011 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, "Pi"},
1173 FINAL_CHUNK, "Pi"}, 1012 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1174 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 2}, 1013 NOT_MASKED, "ng"}};
1175 FINAL_CHUNK, "ng"}}; 1014 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
1176 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks);
1177 set_stream(stream.Pass()); 1015 set_stream(stream.Pass());
1178 { 1016 {
1179 InSequence s; 1017 InSequence s;
1180 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1018 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1181 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1019 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1182 EXPECT_CALL(*event_interface_, 1020 EXPECT_CALL(*event_interface_,
1183 OnDropChannel(kWebSocketErrorProtocolError, _)); 1021 OnDropChannel(kWebSocketErrorProtocolError, _));
1184 } 1022 }
1185 1023
1186 CreateChannelAndConnectSuccessfully(); 1024 CreateChannelAndConnectSuccessfully();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1056 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1219 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1057 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1220 EXPECT_CALL(*event_interface_, 1058 EXPECT_CALL(*event_interface_,
1221 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); 1059 OnDropChannel(kWebSocketErrorAbnormalClosure, _));
1222 } 1060 }
1223 1061
1224 CreateChannelAndConnectSuccessfully(); 1062 CreateChannelAndConnectSuccessfully();
1225 base::MessageLoop::current()->RunUntilIdle(); 1063 base::MessageLoop::current()->RunUntilIdle();
1226 } 1064 }
1227 1065
1228 // Connection closed in the middle of a Close message (server bug, etc.)
1229 TEST_F(WebSocketChannelEventInterfaceTest, ConnectionClosedInMessage) {
1230 scoped_ptr<ReadableFakeWebSocketStream> stream(
1231 new ReadableFakeWebSocketStream);
1232 static const InitFrameChunk chunks[] = {
1233 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7},
1234 NOT_FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "")}};
1235
1236 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks);
1237 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
1238 ERR_CONNECTION_CLOSED);
1239 set_stream(stream.Pass());
1240 {
1241 InSequence s;
1242 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1243 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1244 EXPECT_CALL(*event_interface_,
1245 OnDropChannel(kWebSocketErrorAbnormalClosure, _));
1246 }
1247
1248 CreateChannelAndConnectSuccessfully();
1249 base::MessageLoop::current()->RunUntilIdle();
1250 }
1251
1252 // RFC6455 5.1 "A client MUST close a connection if it detects a masked frame." 1066 // RFC6455 5.1 "A client MUST close a connection if it detects a masked frame."
1253 TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) { 1067 TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) {
1254 scoped_ptr<ReadableFakeWebSocketStream> stream( 1068 scoped_ptr<ReadableFakeWebSocketStream> stream(
1255 new ReadableFakeWebSocketStream); 1069 new ReadableFakeWebSocketStream);
1256 static const InitFrameChunk chunks[] = { 1070 static const InitFrame frames[] = {
1257 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 5}, FINAL_CHUNK, 1071 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}};
1258 "HELLO"}};
1259 1072
1260 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); 1073 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
1261 set_stream(stream.Pass()); 1074 set_stream(stream.Pass());
1262 { 1075 {
1263 InSequence s; 1076 InSequence s;
1264 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1077 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1265 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1078 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1266 EXPECT_CALL(*event_interface_, 1079 EXPECT_CALL(*event_interface_,
1267 OnDropChannel(kWebSocketErrorProtocolError, _)); 1080 OnDropChannel(kWebSocketErrorProtocolError, _));
1268 } 1081 }
1269 1082
1270 CreateChannelAndConnectSuccessfully(); 1083 CreateChannelAndConnectSuccessfully();
1271 base::MessageLoop::current()->RunUntilIdle(); 1084 base::MessageLoop::current()->RunUntilIdle();
1272 } 1085 }
1273 1086
1274 // RFC6455 5.2 "If an unknown opcode is received, the receiving endpoint MUST 1087 // RFC6455 5.2 "If an unknown opcode is received, the receiving endpoint MUST
1275 // _Fail the WebSocket Connection_." 1088 // _Fail the WebSocket Connection_."
1276 TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) { 1089 TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) {
1277 scoped_ptr<ReadableFakeWebSocketStream> stream( 1090 scoped_ptr<ReadableFakeWebSocketStream> stream(
1278 new ReadableFakeWebSocketStream); 1091 new ReadableFakeWebSocketStream);
1279 static const InitFrameChunk chunks[] = { 1092 static const InitFrame frames[] = {{FINAL_FRAME, 4, NOT_MASKED, "HELLO"}};
1280 {{FINAL_FRAME, 4, NOT_MASKED, 5}, FINAL_CHUNK, "HELLO"}};
1281 1093
1282 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); 1094 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
1283 set_stream(stream.Pass()); 1095 set_stream(stream.Pass());
1284 { 1096 {
1285 InSequence s; 1097 InSequence s;
1286 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1098 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1287 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1099 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1288 EXPECT_CALL(*event_interface_, 1100 EXPECT_CALL(*event_interface_,
1289 OnDropChannel(kWebSocketErrorProtocolError, _)); 1101 OnDropChannel(kWebSocketErrorProtocolError, _));
1290 } 1102 }
1291 1103
1292 CreateChannelAndConnectSuccessfully(); 1104 CreateChannelAndConnectSuccessfully();
1293 base::MessageLoop::current()->RunUntilIdle(); 1105 base::MessageLoop::current()->RunUntilIdle();
1294 } 1106 }
1295 1107
1296 // RFC6455 5.4 "Control frames ... MAY be injected in the middle of a 1108 // RFC6455 5.4 "Control frames ... MAY be injected in the middle of a
1297 // fragmented message." 1109 // fragmented message."
1298 TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) { 1110 TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) {
1299 scoped_ptr<ReadableFakeWebSocketStream> stream( 1111 scoped_ptr<ReadableFakeWebSocketStream> stream(
1300 new ReadableFakeWebSocketStream); 1112 new ReadableFakeWebSocketStream);
1301 // We have one message of type Text split into two frames. In the middle is a 1113 // We have one message of type Text split into two frames. In the middle is a
1302 // control message of type Pong. 1114 // control message of type Pong.
1303 static const InitFrameChunk chunks1[] = { 1115 static const InitFrame frames1[] = {
1304 {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 6}, 1116 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText,
1305 FINAL_CHUNK, "SPLIT "}}; 1117 NOT_MASKED, "SPLIT "}};
1306 static const InitFrameChunk chunks2[] = { 1118 static const InitFrame frames2[] = {
1307 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, 0}, 1119 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}};
1308 FINAL_CHUNK, ""}}; 1120 static const InitFrame frames3[] = {
1309 static const InitFrameChunk chunks3[] = { 1121 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1310 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 7}, 1122 NOT_MASKED, "MESSAGE"}};
1311 FINAL_CHUNK, "MESSAGE"}}; 1123 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1);
1312 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1); 1124 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2);
1313 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2); 1125 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3);
1314 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3);
1315 set_stream(stream.Pass()); 1126 set_stream(stream.Pass());
1316 { 1127 {
1317 InSequence s; 1128 InSequence s;
1318 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1129 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1319 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1130 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1320 EXPECT_CALL( 1131 EXPECT_CALL(
1321 *event_interface_, 1132 *event_interface_,
1322 OnDataFrame( 1133 OnDataFrame(
1323 false, WebSocketFrameHeader::kOpCodeText, AsVector("SPLIT "))); 1134 false, WebSocketFrameHeader::kOpCodeText, AsVector("SPLIT ")));
1324 EXPECT_CALL(*event_interface_, 1135 EXPECT_CALL(*event_interface_,
1325 OnDataFrame(true, 1136 OnDataFrame(true,
1326 WebSocketFrameHeader::kOpCodeContinuation, 1137 WebSocketFrameHeader::kOpCodeContinuation,
1327 AsVector("MESSAGE"))); 1138 AsVector("MESSAGE")));
1328 } 1139 }
1329 1140
1330 CreateChannelAndConnectSuccessfully(); 1141 CreateChannelAndConnectSuccessfully();
1331 base::MessageLoop::current()->RunUntilIdle(); 1142 base::MessageLoop::current()->RunUntilIdle();
1332 } 1143 }
1333 1144
1334 // If a chunk has an invalid header, then the connection is closed and 1145 // If a frame has an invalid header, then the connection is closed and
1335 // subsequent chunks must not trigger events. 1146 // subsequent frames must not trigger events.
1336 TEST_F(WebSocketChannelEventInterfaceTest, HeaderlessChunkAfterInvalidChunk) { 1147 TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) {
1337 scoped_ptr<ReadableFakeWebSocketStream> stream( 1148 scoped_ptr<ReadableFakeWebSocketStream> stream(
1338 new ReadableFakeWebSocketStream); 1149 new ReadableFakeWebSocketStream);
1339 static const InitFrameChunk chunks[] = { 1150 static const InitFrame frames[] = {
1340 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 11}, 1151 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"},
1341 NOT_FINAL_CHUNK, "HELLO"}, 1152 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, " WORLD"}};
1342 {{NO_HEADER}, FINAL_CHUNK, " WORLD"}};
1343 1153
1344 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); 1154 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
1345 set_stream(stream.Pass()); 1155 set_stream(stream.Pass());
1346 { 1156 {
1347 InSequence s; 1157 InSequence s;
1348 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1158 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1349 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1159 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1350 EXPECT_CALL(*event_interface_, 1160 EXPECT_CALL(*event_interface_,
1351 OnDropChannel(kWebSocketErrorProtocolError, _)); 1161 OnDropChannel(kWebSocketErrorProtocolError, _));
1352 } 1162 }
1353 1163
1354 CreateChannelAndConnectSuccessfully(); 1164 CreateChannelAndConnectSuccessfully();
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 1304
1495 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("yt?")); 1305 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("yt?"));
1496 base::MessageLoop::current()->RunUntilIdle(); 1306 base::MessageLoop::current()->RunUntilIdle();
1497 } 1307 }
1498 1308
1499 // When the remote server sends a Close frame with an empty payload, 1309 // When the remote server sends a Close frame with an empty payload,
1500 // WebSocketChannel should report code 1005, kWebSocketErrorNoStatusReceived. 1310 // WebSocketChannel should report code 1005, kWebSocketErrorNoStatusReceived.
1501 TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) { 1311 TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) {
1502 scoped_ptr<ReadableFakeWebSocketStream> stream( 1312 scoped_ptr<ReadableFakeWebSocketStream> stream(
1503 new ReadableFakeWebSocketStream); 1313 new ReadableFakeWebSocketStream);
1504 static const InitFrameChunk chunks[] = { 1314 static const InitFrame frames[] = {
1505 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 0}, 1315 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}};
1506 FINAL_CHUNK, ""}}; 1316 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
1507 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks);
1508 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1317 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
1509 ERR_CONNECTION_CLOSED); 1318 ERR_CONNECTION_CLOSED);
1510 set_stream(stream.Pass()); 1319 set_stream(stream.Pass());
1511 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1320 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1512 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1321 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1513 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1322 EXPECT_CALL(*event_interface_, OnClosingHandshake());
1514 EXPECT_CALL(*event_interface_, 1323 EXPECT_CALL(*event_interface_,
1515 OnDropChannel(kWebSocketErrorNoStatusReceived, _)); 1324 OnDropChannel(kWebSocketErrorNoStatusReceived, _));
1516 1325
1517 CreateChannelAndConnectSuccessfully(); 1326 CreateChannelAndConnectSuccessfully();
1518 } 1327 }
1519 1328
1329 // If ReadFrames() returns ERR_WS_PROTOCOL_ERROR, then
1330 // kWebSocketErrorProtocolError must be sent to the renderer.
1331 TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) {
1332 scoped_ptr<ReadableFakeWebSocketStream> stream(
1333 new ReadableFakeWebSocketStream);
1334 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
1335 ERR_WS_PROTOCOL_ERROR);
1336 set_stream(stream.Pass());
1337 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1338 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1339
1340 EXPECT_CALL(*event_interface_,
1341 OnDropChannel(kWebSocketErrorProtocolError, _));
1342
1343 CreateChannelAndConnectSuccessfully();
1344 }
1345
1346 // Async version of above test.
1347 TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) {
1348 scoped_ptr<ReadableFakeWebSocketStream> stream(
1349 new ReadableFakeWebSocketStream);
1350 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
1351 ERR_WS_PROTOCOL_ERROR);
1352 set_stream(stream.Pass());
1353 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1354 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1355
1356 EXPECT_CALL(*event_interface_,
1357 OnDropChannel(kWebSocketErrorProtocolError, _));
1358
1359 CreateChannelAndConnectSuccessfully();
1360 base::MessageLoop::current()->RunUntilIdle();
1361 }
1362
1520 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". 1363 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server".
1521 // WebSocketChannel actually only sets the mask bit in the header, it doesn't 1364 // WebSocketChannel actually only sets the mask bit in the header, it doesn't
1522 // perform masking itself (not all transports actually use masking). 1365 // perform masking itself (not all transports actually use masking).
1523 TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { 1366 TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) {
1524 static const InitFrameChunk expected[] = { 1367 static const InitFrame expected[] = {
1525 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 13}, 1368 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText,
1526 FINAL_CHUNK, "NEEDS MASKING"}}; 1369 MASKED, "NEEDS MASKING"}};
1527 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1370 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1528 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1371 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
1529 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1372 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1530 .WillOnce(Return(OK)); 1373 .WillOnce(Return(OK));
1531 1374
1532 CreateChannelAndConnectSuccessfully(); 1375 CreateChannelAndConnectSuccessfully();
1533 channel_->SendFrame( 1376 channel_->SendFrame(
1534 true, WebSocketFrameHeader::kOpCodeText, AsVector("NEEDS MASKING")); 1377 true, WebSocketFrameHeader::kOpCodeText, AsVector("NEEDS MASKING"));
1535 } 1378 }
1536 1379
1537 // RFC6455 5.5.1 "The application MUST NOT send any more data frames after 1380 // RFC6455 5.5.1 "The application MUST NOT send any more data frames after
1538 // sending a Close frame." 1381 // sending a Close frame."
1539 TEST_F(WebSocketChannelStreamTest, NothingIsSentAfterClose) { 1382 TEST_F(WebSocketChannelStreamTest, NothingIsSentAfterClose) {
1540 static const InitFrameChunk expected[] = { 1383 static const InitFrame expected[] = {
1541 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 9}, 1384 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1542 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 1385 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
1543 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1386 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1544 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1387 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
1545 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1388 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1546 .WillOnce(Return(OK)); 1389 .WillOnce(Return(OK));
1547 1390
1548 CreateChannelAndConnectSuccessfully(); 1391 CreateChannelAndConnectSuccessfully();
1549 channel_->StartClosingHandshake(1000, "Success"); 1392 channel_->StartClosingHandshake(1000, "Success");
1550 channel_->SendFrame( 1393 channel_->SendFrame(
1551 true, WebSocketFrameHeader::kOpCodeText, AsVector("SHOULD BE IGNORED")); 1394 true, WebSocketFrameHeader::kOpCodeText, AsVector("SHOULD BE IGNORED"));
1552 } 1395 }
1553 1396
1554 // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously 1397 // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously
1555 // send a Close frame, the endpoint MUST send a Close frame in response." 1398 // send a Close frame, the endpoint MUST send a Close frame in response."
1556 TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { 1399 TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) {
1557 static const InitFrameChunk chunks[] = { 1400 static const InitFrame frames[] = {
1558 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7}, 1401 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1559 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1402 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}};
1560 static const InitFrameChunk expected[] = { 1403 static const InitFrame expected[] = {
1561 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 7}, 1404 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1562 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1405 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}};
1563 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1406 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1564 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1407 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1565 .WillOnce(ReturnChunks(&chunks)) 1408 .WillOnce(ReturnFrames(&frames))
1566 .WillRepeatedly(Return(ERR_IO_PENDING)); 1409 .WillRepeatedly(Return(ERR_IO_PENDING));
1567 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1410 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1568 .WillOnce(Return(OK)); 1411 .WillOnce(Return(OK));
1569 1412
1570 CreateChannelAndConnectSuccessfully(); 1413 CreateChannelAndConnectSuccessfully();
1571 } 1414 }
1572 1415
1573 // The converse of the above case; after sending a Close frame, we should not 1416 // The converse of the above case; after sending a Close frame, we should not
1574 // send another one. 1417 // send another one.
1575 TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { 1418 TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) {
1576 static const InitFrameChunk expected[] = { 1419 static const InitFrame expected[] = {
1577 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 7}, 1420 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1578 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1421 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}};
1579 static const InitFrameChunk chunks[] = { 1422 static const InitFrame frames_init[] = {
1580 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7}, 1423 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1581 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1424 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}};
1582 1425
1583 // We store the parameters that were passed to ReadFrames() so that we can 1426 // We store the parameters that were passed to ReadFrames() so that we can
1584 // call them explicitly later. 1427 // call them explicitly later.
1585 CompletionCallback read_callback; 1428 CompletionCallback read_callback;
1586 ScopedVector<WebSocketFrameChunk>* frame_chunks = NULL; 1429 ScopedVector<WebSocketFrame>* frames = NULL;
1587 1430
1588 // Use a checkpoint to make the ordering of events clearer. 1431 // Use a checkpoint to make the ordering of events clearer.
1589 MockFunction<void(int)> checkpoint; 1432 MockFunction<void(int)> checkpoint;
1590 { 1433 {
1591 InSequence s; 1434 InSequence s;
1592 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1435 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1593 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1436 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1594 .WillOnce(DoAll(SaveArg<0>(&frame_chunks), 1437 .WillOnce(DoAll(SaveArg<0>(&frames),
1595 SaveArg<1>(&read_callback), 1438 SaveArg<1>(&read_callback),
1596 Return(ERR_IO_PENDING))); 1439 Return(ERR_IO_PENDING)));
1597 EXPECT_CALL(checkpoint, Call(1)); 1440 EXPECT_CALL(checkpoint, Call(1));
1598 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1441 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1599 .WillOnce(Return(OK)); 1442 .WillOnce(Return(OK));
1600 EXPECT_CALL(checkpoint, Call(2)); 1443 EXPECT_CALL(checkpoint, Call(2));
1601 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1444 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1602 .WillOnce(Return(ERR_IO_PENDING)); 1445 .WillOnce(Return(ERR_IO_PENDING));
1603 EXPECT_CALL(checkpoint, Call(3)); 1446 EXPECT_CALL(checkpoint, Call(3));
1604 // WriteFrames() must not be called again. GoogleMock will ensure that the 1447 // WriteFrames() must not be called again. GoogleMock will ensure that the
1605 // test fails if it is. 1448 // test fails if it is.
1606 } 1449 }
1607 1450
1608 CreateChannelAndConnectSuccessfully(); 1451 CreateChannelAndConnectSuccessfully();
1609 checkpoint.Call(1); 1452 checkpoint.Call(1);
1610 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close"); 1453 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close");
1611 checkpoint.Call(2); 1454 checkpoint.Call(2);
1612 1455
1613 *frame_chunks = CreateFrameChunkVector(chunks); 1456 *frames = CreateFrameVector(frames_init);
1614 read_callback.Run(OK); 1457 read_callback.Run(OK);
1615 checkpoint.Call(3); 1458 checkpoint.Call(3);
1616 } 1459 }
1617 1460
1618 // We generate code 1005, kWebSocketErrorNoStatusReceived, when there is no 1461 // We generate code 1005, kWebSocketErrorNoStatusReceived, when there is no
1619 // status in the Close message from the other side. Code 1005 is not allowed to 1462 // status in the Close message from the other side. Code 1005 is not allowed to
1620 // appear on the wire, so we should not echo it back. See test 1463 // appear on the wire, so we should not echo it back. See test
1621 // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is 1464 // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is
1622 // correctly generated internally. 1465 // correctly generated internally.
1623 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { 1466 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) {
1624 static const InitFrameChunk chunks[] = { 1467 static const InitFrame frames[] = {
1625 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 0}, 1468 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}};
1626 FINAL_CHUNK, ""}}; 1469 static const InitFrame expected[] = {
1627 static const InitFrameChunk expected[] = { 1470 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, ""}};
1628 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 0},
1629 FINAL_CHUNK, ""}};
1630 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1471 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1631 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1472 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1632 .WillOnce(ReturnChunks(&chunks)) 1473 .WillOnce(ReturnFrames(&frames))
1633 .WillRepeatedly(Return(ERR_IO_PENDING)); 1474 .WillRepeatedly(Return(ERR_IO_PENDING));
1634 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1475 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1635 .WillOnce(Return(OK)); 1476 .WillOnce(Return(OK));
1636 1477
1637 CreateChannelAndConnectSuccessfully(); 1478 CreateChannelAndConnectSuccessfully();
1638 } 1479 }
1639 1480
1640 // RFC6455 5.5.2 "Upon receipt of a Ping frame, an endpoint MUST send a Pong 1481 // RFC6455 5.5.2 "Upon receipt of a Ping frame, an endpoint MUST send a Pong
1641 // frame in response" 1482 // frame in response"
1642 // 5.5.3 "A Pong frame sent in response to a Ping frame must have identical 1483 // 5.5.3 "A Pong frame sent in response to a Ping frame must have identical
1643 // "Application data" as found in the message body of the Ping frame being 1484 // "Application data" as found in the message body of the Ping frame being
1644 // replied to." 1485 // replied to."
1645 TEST_F(WebSocketChannelStreamTest, PingRepliedWithPong) { 1486 TEST_F(WebSocketChannelStreamTest, PingRepliedWithPong) {
1646 static const InitFrameChunk chunks[] = { 1487 static const InitFrame frames[] = {
1647 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 16}, 1488 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing,
1648 FINAL_CHUNK, "Application data"}}; 1489 NOT_MASKED, "Application data"}};
1649 static const InitFrameChunk expected[] = { 1490 static const InitFrame expected[] = {
1650 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, MASKED, 16}, 1491 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong,
1651 FINAL_CHUNK, "Application data"}}; 1492 MASKED, "Application data"}};
1652 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1493 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1653 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1494 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1654 .WillOnce(ReturnChunks(&chunks)) 1495 .WillOnce(ReturnFrames(&frames))
1655 .WillRepeatedly(Return(ERR_IO_PENDING)); 1496 .WillRepeatedly(Return(ERR_IO_PENDING));
1656 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1497 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1657 .WillOnce(Return(OK)); 1498 .WillOnce(Return(OK));
1658 1499
1659 CreateChannelAndConnectSuccessfully(); 1500 CreateChannelAndConnectSuccessfully();
1660 } 1501 }
1661 1502
1662 TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) { 1503 TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) {
1663 static const InitFrameChunk chunks[] = { 1504 static const InitFrame frames[] = {
1664 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 16}, 1505 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing,
1665 FINAL_CHUNK, "Application data"}}; 1506 NOT_MASKED, "Application data"}};
1666 static const InitFrameChunk expected1[] = { 1507 static const InitFrame expected1[] = {
1667 {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 6}, 1508 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}};
1668 FINAL_CHUNK, "Hello "}}; 1509 static const InitFrame expected2[] = {
1669 static const InitFrameChunk expected2[] = { 1510 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong,
1670 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, MASKED, 16}, 1511 MASKED, "Application data"}};
1671 FINAL_CHUNK, "Application data"}}; 1512 static const InitFrame expected3[] = {
1672 static const InitFrameChunk expected3[] = { 1513 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
1673 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, MASKED, 5}, 1514 MASKED, "World"}};
1674 FINAL_CHUNK, "World"}}; 1515 ScopedVector<WebSocketFrame>* read_frames;
1675 ScopedVector<WebSocketFrameChunk>* read_chunks;
1676 CompletionCallback read_callback; 1516 CompletionCallback read_callback;
1677 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1517 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1678 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1518 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1679 .WillOnce(DoAll(SaveArg<0>(&read_chunks), 1519 .WillOnce(DoAll(SaveArg<0>(&read_frames),
1680 SaveArg<1>(&read_callback), 1520 SaveArg<1>(&read_callback),
1681 Return(ERR_IO_PENDING))) 1521 Return(ERR_IO_PENDING)))
1682 .WillRepeatedly(Return(ERR_IO_PENDING)); 1522 .WillRepeatedly(Return(ERR_IO_PENDING));
1683 { 1523 {
1684 InSequence s; 1524 InSequence s;
1685 1525
1686 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected1), _)) 1526 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _))
1687 .WillOnce(Return(OK)); 1527 .WillOnce(Return(OK));
1688 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected2), _)) 1528 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _))
1689 .WillOnce(Return(OK)); 1529 .WillOnce(Return(OK));
1690 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected3), _)) 1530 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected3), _))
1691 .WillOnce(Return(OK)); 1531 .WillOnce(Return(OK));
1692 } 1532 }
1693 1533
1694 CreateChannelAndConnectSuccessfully(); 1534 CreateChannelAndConnectSuccessfully();
1695 channel_->SendFrame( 1535 channel_->SendFrame(
1696 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); 1536 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello "));
1697 *read_chunks = CreateFrameChunkVector(chunks); 1537 *read_frames = CreateFrameVector(frames);
1698 read_callback.Run(OK); 1538 read_callback.Run(OK);
1699 channel_->SendFrame( 1539 channel_->SendFrame(
1700 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("World")); 1540 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("World"));
1701 } 1541 }
1702 1542
1703 // WriteFrames() may not be called until the previous write has completed. 1543 // WriteFrames() may not be called until the previous write has completed.
1704 // WebSocketChannel must buffer writes that happen in the meantime. 1544 // WebSocketChannel must buffer writes that happen in the meantime.
1705 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { 1545 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) {
1706 static const InitFrameChunk expected1[] = { 1546 static const InitFrame expected1[] = {
1707 {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 6}, 1547 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}};
1708 FINAL_CHUNK, "Hello "}}; 1548 static const InitFrame expected2[] = {
1709 static const InitFrameChunk expected2[] = { 1549 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}};
1710 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 5}, FINAL_CHUNK,
1711 "World"}};
1712 CompletionCallback write_callback; 1550 CompletionCallback write_callback;
1713 MockFunction<void(int)> checkpoint; 1551 MockFunction<void(int)> checkpoint;
1714 1552
1715 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1553 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1716 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1554 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
1717 { 1555 {
1718 InSequence s; 1556 InSequence s;
1719 EXPECT_CALL(checkpoint, Call(1)); 1557 EXPECT_CALL(checkpoint, Call(1));
1720 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected1), _)) 1558 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _))
1721 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); 1559 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING)));
1722 EXPECT_CALL(checkpoint, Call(2)); 1560 EXPECT_CALL(checkpoint, Call(2));
1723 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected2), _)) 1561 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _))
1724 .WillOnce(Return(ERR_IO_PENDING)); 1562 .WillOnce(Return(ERR_IO_PENDING));
1725 EXPECT_CALL(checkpoint, Call(3)); 1563 EXPECT_CALL(checkpoint, Call(3));
1726 } 1564 }
1727 1565
1728 CreateChannelAndConnectSuccessfully(); 1566 CreateChannelAndConnectSuccessfully();
1729 checkpoint.Call(1); 1567 checkpoint.Call(1);
1730 channel_->SendFrame( 1568 channel_->SendFrame(
1731 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); 1569 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello "));
1732 channel_->SendFrame( 1570 channel_->SendFrame(
1733 true, WebSocketFrameHeader::kOpCodeText, AsVector("World")); 1571 true, WebSocketFrameHeader::kOpCodeText, AsVector("World"));
1734 checkpoint.Call(2); 1572 checkpoint.Call(2);
1735 write_callback.Run(OK); 1573 write_callback.Run(OK);
1736 checkpoint.Call(3); 1574 checkpoint.Call(3);
1737 } 1575 }
1738 1576
1739 // WebSocketChannel must buffer frames while it is waiting for a write to 1577 // WebSocketChannel must buffer frames while it is waiting for a write to
1740 // complete, and then send them in a single batch. The batching behaviour is 1578 // complete, and then send them in a single batch. The batching behaviour is
1741 // important to get good throughput in the "many small messages" case. 1579 // important to get good throughput in the "many small messages" case.
1742 TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) { 1580 TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) {
1743 static const char input_letters[] = "Hello"; 1581 static const char input_letters[] = "Hello";
1744 static const InitFrameChunk expected1[] = { 1582 static const InitFrame expected1[] = {
1745 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, 1583 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "H"}};
1746 "H"}}; 1584 static const InitFrame expected2[] = {
1747 static const InitFrameChunk expected2[] = { 1585 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "e"},
1748 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, 1586 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"},
1749 "e"}, 1587 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"},
1750 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, 1588 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "o"}};
1751 "l"},
1752 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK,
1753 "l"},
1754 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK,
1755 "o"}};
1756 CompletionCallback write_callback; 1589 CompletionCallback write_callback;
1757 1590
1758 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1591 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1759 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1592 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
1760 { 1593 {
1761 InSequence s; 1594 InSequence s;
1762 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected1), _)) 1595 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _))
1763 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); 1596 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING)));
1764 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected2), _)) 1597 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _))
1765 .WillOnce(Return(ERR_IO_PENDING)); 1598 .WillOnce(Return(ERR_IO_PENDING));
1766 } 1599 }
1767 1600
1768 CreateChannelAndConnectSuccessfully(); 1601 CreateChannelAndConnectSuccessfully();
1769 for (size_t i = 0; i < strlen(input_letters); ++i) { 1602 for (size_t i = 0; i < strlen(input_letters); ++i) {
1770 channel_->SendFrame(true, 1603 channel_->SendFrame(true,
1771 WebSocketFrameHeader::kOpCodeText, 1604 WebSocketFrameHeader::kOpCodeText,
1772 std::vector<char>(1, input_letters[i])); 1605 std::vector<char>(1, input_letters[i]));
1773 } 1606 }
1774 write_callback.Run(OK); 1607 write_callback.Run(OK);
1775 } 1608 }
1776 1609
1777 // When the renderer sends more on a channel than it has quota for, then we send 1610 // When the renderer sends more on a channel than it has quota for, then we send
1778 // a kWebSocketMuxErrorSendQuotaViolation status code (from the draft websocket 1611 // a kWebSocketMuxErrorSendQuotaViolation status code (from the draft websocket
1779 // mux specification) back to the renderer. This should not be sent to the 1612 // mux specification) back to the renderer. This should not be sent to the
1780 // remote server, which may not even implement the mux specification, and could 1613 // remote server, which may not even implement the mux specification, and could
1781 // even be using a different extension which uses that code to mean something 1614 // even be using a different extension which uses that code to mean something
1782 // else. 1615 // else.
1783 TEST_F(WebSocketChannelStreamTest, MuxErrorIsNotSentToStream) { 1616 TEST_F(WebSocketChannelStreamTest, MuxErrorIsNotSentToStream) {
1784 static const InitFrameChunk expected[] = { 1617 static const InitFrame expected[] = {
1785 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 16}, 1618 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1786 FINAL_CHUNK, CLOSE_DATA(GOING_AWAY, "Internal Error")}}; 1619 MASKED, CLOSE_DATA(GOING_AWAY, "Internal Error")}};
1787 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1620 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1788 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1621 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
1789 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1622 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1790 .WillOnce(Return(OK)); 1623 .WillOnce(Return(OK));
1791 EXPECT_CALL(*mock_stream_, Close()); 1624 EXPECT_CALL(*mock_stream_, Close());
1792 1625
1793 CreateChannelAndConnectSuccessfully(); 1626 CreateChannelAndConnectSuccessfully();
1794 channel_->SendFrame(true, 1627 channel_->SendFrame(true,
1795 WebSocketFrameHeader::kOpCodeText, 1628 WebSocketFrameHeader::kOpCodeText,
1796 std::vector<char>(kDefaultInitialQuota + 1, 'C')); 1629 std::vector<char>(kDefaultInitialQuota + 1, 'C'));
1797 } 1630 }
1798 1631
1799 // For convenience, most of these tests use Text frames. However, the WebSocket 1632 // For convenience, most of these tests use Text frames. However, the WebSocket
1800 // protocol also has Binary frames and those need to be 8-bit clean. For the 1633 // protocol also has Binary frames and those need to be 8-bit clean. For the
1801 // sake of completeness, this test verifies that they are. 1634 // sake of completeness, this test verifies that they are.
1802 TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) { 1635 TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) {
1803 ScopedVector<WebSocketFrameChunk>* frame_chunks = NULL; 1636 ScopedVector<WebSocketFrame>* frames = NULL;
1804 1637
1805 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1638 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1806 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1639 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING));
1807 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) 1640 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1808 .WillOnce(DoAll(SaveArg<0>(&frame_chunks), Return(ERR_IO_PENDING))); 1641 .WillOnce(DoAll(SaveArg<0>(&frames), Return(ERR_IO_PENDING)));
1809 1642
1810 CreateChannelAndConnectSuccessfully(); 1643 CreateChannelAndConnectSuccessfully();
1811 channel_->SendFrame( 1644 channel_->SendFrame(
1812 true, 1645 true,
1813 WebSocketFrameHeader::kOpCodeBinary, 1646 WebSocketFrameHeader::kOpCodeBinary,
1814 std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize)); 1647 std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize));
1815 ASSERT_TRUE(frame_chunks != NULL); 1648 ASSERT_TRUE(frames != NULL);
1816 ASSERT_EQ(1U, frame_chunks->size()); 1649 ASSERT_EQ(1U, frames->size());
1817 const WebSocketFrameChunk* out_chunk = (*frame_chunks)[0]; 1650 const WebSocketFrame* out_frame = (*frames)[0];
1818 ASSERT_TRUE(out_chunk->header); 1651 EXPECT_EQ(kBinaryBlobSize, out_frame->header.payload_length);
1819 EXPECT_EQ(kBinaryBlobSize, out_chunk->header->payload_length); 1652 ASSERT_TRUE(out_frame->data);
1820 ASSERT_TRUE(out_chunk->data); 1653 EXPECT_EQ(0, memcmp(kBinaryBlob, out_frame->data->data(), kBinaryBlobSize));
1821 EXPECT_EQ(kBinaryBlobSize, static_cast<size_t>(out_chunk->data->size()));
1822 EXPECT_EQ(0, memcmp(kBinaryBlob, out_chunk->data->data(), kBinaryBlobSize));
1823 } 1654 }
1824 1655
1825 // Test the read path for 8-bit cleanliness as well. 1656 // Test the read path for 8-bit cleanliness as well.
1826 TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) { 1657 TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) {
1827 scoped_ptr<WebSocketFrameHeader> frame_header( 1658 scoped_ptr<WebSocketFrame> frame(
1828 new WebSocketFrameHeader(WebSocketFrameHeader::kOpCodeBinary)); 1659 new WebSocketFrame(WebSocketFrameHeader::kOpCodeBinary));
1829 frame_header->final = true; 1660 WebSocketFrameHeader& frame_header = frame->header;
1830 frame_header->payload_length = kBinaryBlobSize; 1661 frame_header.final = true;
1831 scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk); 1662 frame_header.payload_length = kBinaryBlobSize;
1832 frame_chunk->header = frame_header.Pass(); 1663 frame->data = new IOBuffer(kBinaryBlobSize);
1833 frame_chunk->final_chunk = true; 1664 memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize);
1834 frame_chunk->data = new IOBufferWithSize(kBinaryBlobSize); 1665 ScopedVector<WebSocketFrame> frames;
1835 memcpy(frame_chunk->data->data(), kBinaryBlob, kBinaryBlobSize); 1666 frames.push_back(frame.release());
1836 ScopedVector<WebSocketFrameChunk> chunks;
1837 chunks.push_back(frame_chunk.release());
1838 scoped_ptr<ReadableFakeWebSocketStream> stream( 1667 scoped_ptr<ReadableFakeWebSocketStream> stream(
1839 new ReadableFakeWebSocketStream); 1668 new ReadableFakeWebSocketStream);
1840 stream->PrepareRawReadFrames( 1669 stream->PrepareRawReadFrames(
1841 ReadableFakeWebSocketStream::SYNC, OK, chunks.Pass()); 1670 ReadableFakeWebSocketStream::SYNC, OK, frames.Pass());
1842 set_stream(stream.Pass()); 1671 set_stream(stream.Pass());
1843 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1672 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _));
1844 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1673 EXPECT_CALL(*event_interface_, OnFlowControl(_));
1845 EXPECT_CALL(*event_interface_, 1674 EXPECT_CALL(*event_interface_,
1846 OnDataFrame(true, 1675 OnDataFrame(true,
1847 WebSocketFrameHeader::kOpCodeBinary, 1676 WebSocketFrameHeader::kOpCodeBinary,
1848 std::vector<char>(kBinaryBlob, 1677 std::vector<char>(kBinaryBlob,
1849 kBinaryBlob + kBinaryBlobSize))); 1678 kBinaryBlob + kBinaryBlobSize)));
1850 1679
1851 CreateChannelAndConnectSuccessfully(); 1680 CreateChannelAndConnectSuccessfully();
1852 } 1681 }
1853 1682
1854 // If we receive another frame after Close, it is not valid. It is not 1683 // If we receive another frame after Close, it is not valid. It is not
1855 // completely clear what behaviour is required from the standard in this case, 1684 // completely clear what behaviour is required from the standard in this case,
1856 // but the current implementation fails the connection. Since a Close has 1685 // but the current implementation fails the connection. Since a Close has
1857 // already been sent, this just means closing the connection. 1686 // already been sent, this just means closing the connection.
1858 TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { 1687 TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) {
1859 static const InitFrameChunk chunks[] = { 1688 static const InitFrame frames[] = {
1860 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 4}, 1689 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1861 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, 1690 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")},
1862 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 9}, 1691 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing,
1863 FINAL_CHUNK, "Ping body"}}; 1692 NOT_MASKED, "Ping body"}};
1864 static const InitFrameChunk expected[] = { 1693 static const InitFrame expected[] = {
1865 {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 4}, 1694 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1866 FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 1695 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}};
1867 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1696 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1868 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1697 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1869 .WillOnce(ReturnChunks(&chunks)) 1698 .WillOnce(ReturnFrames(&frames))
1870 .WillRepeatedly(Return(ERR_IO_PENDING)); 1699 .WillRepeatedly(Return(ERR_IO_PENDING));
1871 { 1700 {
1872 // We only need to verify the relative order of WriteFrames() and 1701 // We only need to verify the relative order of WriteFrames() and
1873 // Close(). The current implementation calls WriteFrames() for the Close 1702 // Close(). The current implementation calls WriteFrames() for the Close
1874 // frame before calling ReadFrames() again, but that is an implementation 1703 // frame before calling ReadFrames() again, but that is an implementation
1875 // detail and better not to consider required behaviour. 1704 // detail and better not to consider required behaviour.
1876 InSequence s; 1705 InSequence s;
1877 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) 1706 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1878 .WillOnce(Return(OK)); 1707 .WillOnce(Return(OK));
1879 EXPECT_CALL(*mock_stream_, Close()).Times(1); 1708 EXPECT_CALL(*mock_stream_, Close()).Times(1);
1880 } 1709 }
1881 1710
1882 CreateChannelAndConnectSuccessfully(); 1711 CreateChannelAndConnectSuccessfully();
1883 } 1712 }
1884 1713
1714 // A protocol error from the remote server should result in a close frame with
1715 // status 1002, followed by the connection closing.
1716 TEST_F(WebSocketChannelStreamTest, ProtocolError) {
1717 static const InitFrame expected[] = {
1718 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
1719 MASKED, CLOSE_DATA(PROTOCOL_ERROR, "WebSocket Protocol Error")}};
1720 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber());
1721 EXPECT_CALL(*mock_stream_, ReadFrames(_, _))
1722 .WillOnce(Return(ERR_WS_PROTOCOL_ERROR));
1723 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _))
1724 .WillOnce(Return(OK));
1725 EXPECT_CALL(*mock_stream_, Close());
1726
1727 CreateChannelAndConnectSuccessfully();
1728 }
1729
1885 } // namespace 1730 } // namespace
1886 } // namespace net 1731 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_channel.cc ('k') | net/websockets/websocket_frame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698