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

Powered by Google App Engine
This is Rietveld 408576698