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

Side by Side Diff: Source/modules/websockets/MainThreadWebSocketChannel.cpp

Issue 14657008: Make websocket error messages look better at the devtools console. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 7 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 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 , m_hasContinuousFrame(false) 87 , m_hasContinuousFrame(false)
88 , m_closeEventCode(CloseEventCodeAbnormalClosure) 88 , m_closeEventCode(CloseEventCodeAbnormalClosure)
89 , m_outgoingFrameQueueStatus(OutgoingFrameQueueOpen) 89 , m_outgoingFrameQueueStatus(OutgoingFrameQueueOpen)
90 , m_blobLoaderStatus(BlobLoaderNotStarted) 90 , m_blobLoaderStatus(BlobLoaderNotStarted)
91 , m_callFrameAtConnection("", "", 0) 91 , m_callFrameAtConnection("", "", 0)
92 { 92 {
93 if (Page* page = m_document->page()) 93 if (Page* page = m_document->page())
94 m_identifier = createUniqueIdentifier(); 94 m_identifier = createUniqueIdentifier();
95 } 95 }
96 96
97 MainThreadWebSocketChannel::MainThreadWebSocketChannel(Document* document, WebSo cketChannelClient* client, const ScriptCallFrame& callFrame)
tkent 2013/05/06 22:56:40 Can you merge this constructor to another construc
yhirano 2013/05/07 01:08:08 Done.
98 : m_document(document)
99 , m_client(client)
100 , m_resumeTimer(this, &MainThreadWebSocketChannel::resumeTimerFired)
101 , m_suspended(false)
102 , m_closing(false)
103 , m_didFailOfClientAlreadyRun(false)
104 , m_receivedClosingHandshake(false)
105 , m_closingTimer(this, &MainThreadWebSocketChannel::closingTimerFired)
106 , m_closed(false)
107 , m_shouldDiscardReceivedData(false)
108 , m_unhandledBufferedAmount(0)
109 , m_identifier(0)
110 , m_hasContinuousFrame(false)
111 , m_closeEventCode(CloseEventCodeAbnormalClosure)
112 , m_outgoingFrameQueueStatus(OutgoingFrameQueueOpen)
113 , m_blobLoaderStatus(BlobLoaderNotStarted)
114 , m_callFrameAtConnection(callFrame)
115 {
116 if (Page* page = m_document->page())
117 m_identifier = createUniqueIdentifier();
118 }
119
97 MainThreadWebSocketChannel::~MainThreadWebSocketChannel() 120 MainThreadWebSocketChannel::~MainThreadWebSocketChannel()
98 { 121 {
99 } 122 }
100 123
101 void MainThreadWebSocketChannel::connect(const KURL& url, const String& protocol ) 124 void MainThreadWebSocketChannel::connect(const KURL& url, const String& protocol )
102 { 125 {
103 LOG(Network, "MainThreadWebSocketChannel %p connect()", this); 126 LOG(Network, "MainThreadWebSocketChannel %p connect()", this);
104 ASSERT(!m_handle); 127 ASSERT(!m_handle);
105 ASSERT(!m_suspended); 128 ASSERT(!m_suspended);
106 m_handshake = adoptPtr(new WebSocketHandshake(url, protocol, m_document)); 129 m_handshake = adoptPtr(new WebSocketHandshake(url, protocol, m_document));
107 m_handshake->reset(); 130 m_handshake->reset();
108 m_handshake->addExtensionProcessor(m_deflateFramer.createExtensionProcessor( )); 131 m_handshake->addExtensionProcessor(m_deflateFramer.createExtensionProcessor( ));
109 if (m_identifier) 132 if (m_identifier)
110 InspectorInstrumentation::didCreateWebSocket(m_document, m_identifier, u rl, m_document->url(), protocol); 133 InspectorInstrumentation::didCreateWebSocket(m_document, m_identifier, u rl, m_document->url(), protocol);
111 ref(); 134 ref();
112 m_handle = SocketStreamHandle::create(m_handshake->url(), this); 135 m_handle = SocketStreamHandle::create(m_handshake->url(), this);
113 RefPtr<ScriptCallStack> callstack = createScriptCallStack(1, true); 136 RefPtr<ScriptCallStack> callStack = createScriptCallStack(1, true);
114 m_callFrameAtConnection = callstack && callstack->size() > 0 ? callstack->at (0) : ScriptCallFrame("", "", 0); 137 if (callStack && callStack->size() > 0)
138 m_callFrameAtConnection = callStack->at(0);
115 } 139 }
116 140
117 String MainThreadWebSocketChannel::subprotocol() 141 String MainThreadWebSocketChannel::subprotocol()
118 { 142 {
119 LOG(Network, "MainThreadWebSocketChannel %p subprotocol()", this); 143 LOG(Network, "MainThreadWebSocketChannel %p subprotocol()", this);
120 if (!m_handshake || m_handshake->mode() != WebSocketHandshake::Connected) 144 if (!m_handshake || m_handshake->mode() != WebSocketHandshake::Connected)
121 return ""; 145 return "";
122 String serverProtocol = m_handshake->serverWebSocketProtocol(); 146 String serverProtocol = m_handshake->serverWebSocketProtocol();
123 if (serverProtocol.isNull()) 147 if (serverProtocol.isNull())
124 return ""; 148 return "";
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 { 211 {
188 LOG(Network, "MainThreadWebSocketChannel %p close() code=%d reason='%s'", th is, code, reason.utf8().data()); 212 LOG(Network, "MainThreadWebSocketChannel %p close() code=%d reason='%s'", th is, code, reason.utf8().data());
189 ASSERT(!m_suspended); 213 ASSERT(!m_suspended);
190 if (!m_handle) 214 if (!m_handle)
191 return; 215 return;
192 startClosingHandshake(code, reason); 216 startClosingHandshake(code, reason);
193 if (m_closing && !m_closingTimer.isActive()) 217 if (m_closing && !m_closingTimer.isActive())
194 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime); 218 m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime);
195 } 219 }
196 220
197 void MainThreadWebSocketChannel::fail(const String& reason) 221 void MainThreadWebSocketChannel::fail(const String& reason, MessageLevel level)
222 {
223 fail(reason, level, 0);
224 }
225
226 void MainThreadWebSocketChannel::fail(const String& reason, MessageLevel level, PassOwnPtr<CallStackWrapper> wrapper)
198 { 227 {
199 LOG(Network, "MainThreadWebSocketChannel %p fail() reason='%s'", this, reaso n.utf8().data()); 228 LOG(Network, "MainThreadWebSocketChannel %p fail() reason='%s'", this, reaso n.utf8().data());
200 ASSERT(!m_suspended); 229 ASSERT(!m_suspended);
201 if (m_document) { 230 if (m_document) {
202 InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_id entifier, reason); 231 InspectorInstrumentation::didReceiveWebSocketFrameError(m_document, m_id entifier, reason);
203 const String message = "WebSocket connection to '" + m_handshake->url(). elidedString() + "' failed: " + reason; 232 const String message = "WebSocket connection to '" + m_handshake->url(). elidedString() + "' failed: " + reason;
204 RefPtr<ScriptCallStack> callstack = createScriptCallStack(1, true); 233 RefPtr<ScriptCallStack> callStack = wrapper ? wrapper->callStack() : 0;
205 if (callstack && callstack->size() > 0) { 234 if (callStack && callStack->size() > 0) {
206 // We are in a JS callstack. 235 String url = callStack->at(0).sourceURL();
207 // So, the addConsoleMessage method will show the stack appropriatel y. 236 unsigned lineNumber = callStack->at(0).lineNumber();
208 m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, me ssage); 237 static_cast<ScriptExecutionContext*>(m_document)->addConsoleMessage( JSMessageSource, level, message, url, lineNumber);
209 } else { 238 } else {
210 // We are not in a JS callstack. 239 RefPtr<ScriptCallStack> callStack = createScriptCallStack(1, true);
211 // Then show the source file and the line number at the connection i nitiation. 240 if (callStack && callStack->size() > 0) {
212 const String& url = m_callFrameAtConnection.sourceURL(); 241 // We are in a JS callstack.
213 unsigned lineNumber = m_callFrameAtConnection.lineNumber(); 242 // So, the addConsoleMessage method will show the stack appropri ately.
214 static_cast<ScriptExecutionContext*>(m_document)->addConsoleMessage( JSMessageSource, ErrorMessageLevel, message, url, lineNumber, 0, 0); 243 m_document->addConsoleMessage(JSMessageSource, level, message);
244 } else {
245 // We are not in a JS callstack.
246 // Then show the source file and the line number at the connecti on initiation.
247 const String& url = m_callFrameAtConnection.sourceURL();
248 unsigned lineNumber = m_callFrameAtConnection.lineNumber();
249 static_cast<ScriptExecutionContext*>(m_document)->addConsoleMess age(JSMessageSource, level, message, url, lineNumber);
250 }
215 } 251 }
216 } 252 }
253 failInternal();
254 }
217 255
256 void MainThreadWebSocketChannel::failInternal()
257 {
218 // Hybi-10 specification explicitly states we must not continue to handle in coming data 258 // Hybi-10 specification explicitly states we must not continue to handle in coming data
219 // once the WebSocket connection is failed (section 7.1.7). 259 // once the WebSocket connection is failed (section 7.1.7).
220 RefPtr<MainThreadWebSocketChannel> protect(this); // The client can close th e channel, potentially removing the last reference. 260 RefPtr<MainThreadWebSocketChannel> protect(this); // The client can close th e channel, potentially removing the last reference.
221 m_shouldDiscardReceivedData = true; 261 m_shouldDiscardReceivedData = true;
222 if (!m_buffer.isEmpty()) 262 if (!m_buffer.isEmpty())
223 skipBuffer(m_buffer.size()); // Save memory. 263 skipBuffer(m_buffer.size()); // Save memory.
224 m_deflateFramer.didFail(); 264 m_deflateFramer.didFail();
225 m_hasContinuousFrame = false; 265 m_hasContinuousFrame = false;
226 m_continuousFrameData.clear(); 266 m_continuousFrameData.clear();
227 if (!m_didFailOfClientAlreadyRun) { 267 if (!m_didFailOfClientAlreadyRun) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 void MainThreadWebSocketChannel::didOpenSocketStream(SocketStreamHandle* handle) 309 void MainThreadWebSocketChannel::didOpenSocketStream(SocketStreamHandle* handle)
270 { 310 {
271 LOG(Network, "MainThreadWebSocketChannel %p didOpenSocketStream()", this); 311 LOG(Network, "MainThreadWebSocketChannel %p didOpenSocketStream()", this);
272 ASSERT(handle == m_handle); 312 ASSERT(handle == m_handle);
273 if (!m_document) 313 if (!m_document)
274 return; 314 return;
275 if (m_identifier) 315 if (m_identifier)
276 InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document, m_identifier, *m_handshake->clientHandshakeRequest()); 316 InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document, m_identifier, *m_handshake->clientHandshakeRequest());
277 CString handshakeMessage = m_handshake->clientHandshakeMessage(); 317 CString handshakeMessage = m_handshake->clientHandshakeMessage();
278 if (!handle->send(handshakeMessage.data(), handshakeMessage.length())) 318 if (!handle->send(handshakeMessage.data(), handshakeMessage.length()))
279 fail("Failed to send WebSocket handshake."); 319 failAsError("Failed to send WebSocket handshake.");
280 } 320 }
281 321
282 void MainThreadWebSocketChannel::didCloseSocketStream(SocketStreamHandle* handle ) 322 void MainThreadWebSocketChannel::didCloseSocketStream(SocketStreamHandle* handle )
283 { 323 {
284 LOG(Network, "MainThreadWebSocketChannel %p didCloseSocketStream()", this); 324 LOG(Network, "MainThreadWebSocketChannel %p didCloseSocketStream()", this);
285 if (m_identifier && m_document) 325 if (m_identifier && m_document)
286 InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier); 326 InspectorInstrumentation::didCloseWebSocket(m_document, m_identifier);
287 ASSERT_UNUSED(handle, handle == m_handle || !m_handle); 327 ASSERT_UNUSED(handle, handle == m_handle || !m_handle);
288 m_closed = true; 328 m_closed = true;
289 if (m_closingTimer.isActive()) 329 if (m_closingTimer.isActive())
(...skipping 27 matching lines...) Expand all
317 } 357 }
318 if (!m_client) { 358 if (!m_client) {
319 m_shouldDiscardReceivedData = true; 359 m_shouldDiscardReceivedData = true;
320 handle->disconnect(); 360 handle->disconnect();
321 return; 361 return;
322 } 362 }
323 if (m_shouldDiscardReceivedData) 363 if (m_shouldDiscardReceivedData)
324 return; 364 return;
325 if (!appendToBuffer(data, len)) { 365 if (!appendToBuffer(data, len)) {
326 m_shouldDiscardReceivedData = true; 366 m_shouldDiscardReceivedData = true;
327 fail("Ran out of memory while receiving WebSocket data."); 367 failAsError("Ran out of memory while receiving WebSocket data.");
328 return; 368 return;
329 } 369 }
330 while (!m_suspended && m_client && !m_buffer.isEmpty()) 370 while (!m_suspended && m_client && !m_buffer.isEmpty())
331 if (!processBuffer()) 371 if (!processBuffer())
332 break; 372 break;
333 } 373 }
334 374
335 void MainThreadWebSocketChannel::didUpdateBufferedAmount(SocketStreamHandle*, si ze_t bufferedAmount) 375 void MainThreadWebSocketChannel::didUpdateBufferedAmount(SocketStreamHandle*, si ze_t bufferedAmount)
336 { 376 {
337 if (m_client) 377 if (m_client)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 deref(); 428 deref();
389 } 429 }
390 430
391 void MainThreadWebSocketChannel::didFail(int errorCode) 431 void MainThreadWebSocketChannel::didFail(int errorCode)
392 { 432 {
393 LOG(Network, "MainThreadWebSocketChannel %p didFail() errorCode=%d", this, e rrorCode); 433 LOG(Network, "MainThreadWebSocketChannel %p didFail() errorCode=%d", this, e rrorCode);
394 ASSERT(m_blobLoader); 434 ASSERT(m_blobLoader);
395 ASSERT(m_blobLoaderStatus == BlobLoaderStarted); 435 ASSERT(m_blobLoaderStatus == BlobLoaderStarted);
396 m_blobLoader.clear(); 436 m_blobLoader.clear();
397 m_blobLoaderStatus = BlobLoaderFailed; 437 m_blobLoaderStatus = BlobLoaderFailed;
398 fail("Failed to load Blob: error code = " + String::number(errorCode)); // F IXME: Generate human-friendly reason message. 438 failAsError("Failed to load Blob: error code = " + String::number(errorCode) ); // FIXME: Generate human-friendly reason message.
399 deref(); 439 deref();
400 } 440 }
401 441
402 bool MainThreadWebSocketChannel::appendToBuffer(const char* data, size_t len) 442 bool MainThreadWebSocketChannel::appendToBuffer(const char* data, size_t len)
403 { 443 {
404 size_t newBufferSize = m_buffer.size() + len; 444 size_t newBufferSize = m_buffer.size() + len;
405 if (newBufferSize < m_buffer.size()) { 445 if (newBufferSize < m_buffer.size()) {
406 LOG(Network, "MainThreadWebSocketChannel %p appendToBuffer() Buffer over flow (%lu bytes already in receive buffer and appending %lu bytes)", this, stati c_cast<unsigned long>(m_buffer.size()), static_cast<unsigned long>(len)); 446 LOG(Network, "MainThreadWebSocketChannel %p appendToBuffer() Buffer over flow (%lu bytes already in receive buffer and appending %lu bytes)", this, stati c_cast<unsigned long>(m_buffer.size()), static_cast<unsigned long>(len));
407 return false; 447 return false;
408 } 448 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 LOG(Network, "MainThreadWebSocketChannel %p Connected", this); 491 LOG(Network, "MainThreadWebSocketChannel %p Connected", this);
452 skipBuffer(headerLength); 492 skipBuffer(headerLength);
453 m_client->didConnect(); 493 m_client->didConnect();
454 LOG(Network, "MainThreadWebSocketChannel %p %lu bytes remaining in m _buffer", this, static_cast<unsigned long>(m_buffer.size())); 494 LOG(Network, "MainThreadWebSocketChannel %p %lu bytes remaining in m _buffer", this, static_cast<unsigned long>(m_buffer.size()));
455 return !m_buffer.isEmpty(); 495 return !m_buffer.isEmpty();
456 } 496 }
457 ASSERT(m_handshake->mode() == WebSocketHandshake::Failed); 497 ASSERT(m_handshake->mode() == WebSocketHandshake::Failed);
458 LOG(Network, "MainThreadWebSocketChannel %p Connection failed", this); 498 LOG(Network, "MainThreadWebSocketChannel %p Connection failed", this);
459 skipBuffer(headerLength); 499 skipBuffer(headerLength);
460 m_shouldDiscardReceivedData = true; 500 m_shouldDiscardReceivedData = true;
461 fail(m_handshake->failureReason()); 501 failAsError(m_handshake->failureReason());
462 return false; 502 return false;
463 } 503 }
464 if (m_handshake->mode() != WebSocketHandshake::Connected) 504 if (m_handshake->mode() != WebSocketHandshake::Connected)
465 return false; 505 return false;
466 506
467 return processFrame(); 507 return processFrame();
468 } 508 }
469 509
470 void MainThreadWebSocketChannel::resumeTimerFired(Timer<MainThreadWebSocketChann el>* timer) 510 void MainThreadWebSocketChannel::resumeTimerFired(Timer<MainThreadWebSocketChann el>* timer)
471 { 511 {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 { 555 {
516 ASSERT(!m_buffer.isEmpty()); 556 ASSERT(!m_buffer.isEmpty());
517 557
518 WebSocketFrame frame; 558 WebSocketFrame frame;
519 const char* frameEnd; 559 const char* frameEnd;
520 String errorString; 560 String errorString;
521 WebSocketFrame::ParseFrameResult result = WebSocketFrame::parseFrame(m_buffe r.data(), m_buffer.size(), frame, frameEnd, errorString); 561 WebSocketFrame::ParseFrameResult result = WebSocketFrame::parseFrame(m_buffe r.data(), m_buffer.size(), frame, frameEnd, errorString);
522 if (result == WebSocketFrame::FrameIncomplete) 562 if (result == WebSocketFrame::FrameIncomplete)
523 return false; 563 return false;
524 if (result == WebSocketFrame::FrameError) { 564 if (result == WebSocketFrame::FrameError) {
525 fail(errorString); 565 failAsError(errorString);
526 return false; 566 return false;
527 } 567 }
528 568
529 ASSERT(m_buffer.data() < frameEnd); 569 ASSERT(m_buffer.data() < frameEnd);
530 ASSERT(frameEnd <= m_buffer.data() + m_buffer.size()); 570 ASSERT(frameEnd <= m_buffer.data() + m_buffer.size());
531 571
532 OwnPtr<InflateResultHolder> inflateResult = m_deflateFramer.inflate(frame); 572 OwnPtr<InflateResultHolder> inflateResult = m_deflateFramer.inflate(frame);
533 if (!inflateResult->succeeded()) { 573 if (!inflateResult->succeeded()) {
534 fail(inflateResult->failureReason()); 574 failAsError(inflateResult->failureReason());
535 return false; 575 return false;
536 } 576 }
537 577
538 // Validate the frame data. 578 // Validate the frame data.
539 if (WebSocketFrame::isReservedOpCode(frame.opCode)) { 579 if (WebSocketFrame::isReservedOpCode(frame.opCode)) {
540 fail("Unrecognized frame opcode: " + String::number(frame.opCode)); 580 failAsError("Unrecognized frame opcode: " + String::number(frame.opCode) );
541 return false; 581 return false;
542 } 582 }
543 583
544 if (frame.reserved2 || frame.reserved3) { 584 if (frame.reserved2 || frame.reserved3) {
545 fail("One or more reserved bits are on: reserved2 = " + String::number(f rame.reserved2) + ", reserved3 = " + String::number(frame.reserved3)); 585 failAsError("One or more reserved bits are on: reserved2 = " + String::n umber(frame.reserved2) + ", reserved3 = " + String::number(frame.reserved3));
546 return false; 586 return false;
547 } 587 }
548 588
549 if (frame.masked) { 589 if (frame.masked) {
550 fail("A server must not mask any frames that it sends to the client."); 590 failAsError("A server must not mask any frames that it sends to the clie nt.");
551 return false; 591 return false;
552 } 592 }
553 593
554 // All control frames must not be fragmented. 594 // All control frames must not be fragmented.
555 if (WebSocketFrame::isControlOpCode(frame.opCode) && !frame.final) { 595 if (WebSocketFrame::isControlOpCode(frame.opCode) && !frame.final) {
556 fail("Received fragmented control frame: opcode = " + String::number(fra me.opCode)); 596 failAsError("Received fragmented control frame: opcode = " + String::num ber(frame.opCode));
557 return false; 597 return false;
558 } 598 }
559 599
560 // All control frames must have a payload of 125 bytes or less, which means the frame must not contain 600 // All control frames must have a payload of 125 bytes or less, which means the frame must not contain
561 // the "extended payload length" field. 601 // the "extended payload length" field.
562 if (WebSocketFrame::isControlOpCode(frame.opCode) && WebSocketFrame::needsEx tendedLengthField(frame.payloadLength)) { 602 if (WebSocketFrame::isControlOpCode(frame.opCode) && WebSocketFrame::needsEx tendedLengthField(frame.payloadLength)) {
563 fail("Received control frame having too long payload: " + String::number (frame.payloadLength) + " bytes"); 603 failAsError("Received control frame having too long payload: " + String: :number(frame.payloadLength) + " bytes");
564 return false; 604 return false;
565 } 605 }
566 606
567 // A new data frame is received before the previous continuous frame finishe s. 607 // A new data frame is received before the previous continuous frame finishe s.
568 // Note that control frames are allowed to come in the middle of continuous frames. 608 // Note that control frames are allowed to come in the middle of continuous frames.
569 if (m_hasContinuousFrame && frame.opCode != WebSocketFrame::OpCodeContinuati on && !WebSocketFrame::isControlOpCode(frame.opCode)) { 609 if (m_hasContinuousFrame && frame.opCode != WebSocketFrame::OpCodeContinuati on && !WebSocketFrame::isControlOpCode(frame.opCode)) {
570 fail("Received new data frame but previous continuous frame is unfinishe d."); 610 failAsError("Received new data frame but previous continuous frame is un finished.");
571 return false; 611 return false;
572 } 612 }
573 613
574 InspectorInstrumentation::didReceiveWebSocketFrame(m_document, m_identifier, frame); 614 InspectorInstrumentation::didReceiveWebSocketFrame(m_document, m_identifier, frame);
575 615
576 switch (frame.opCode) { 616 switch (frame.opCode) {
577 case WebSocketFrame::OpCodeContinuation: 617 case WebSocketFrame::OpCodeContinuation:
578 // An unexpected continuation frame is received without any leading fram e. 618 // An unexpected continuation frame is received without any leading fram e.
579 if (!m_hasContinuousFrame) { 619 if (!m_hasContinuousFrame) {
580 fail("Received unexpected continuation frame."); 620 failAsError("Received unexpected continuation frame.");
581 return false; 621 return false;
582 } 622 }
583 m_continuousFrameData.append(frame.payload, frame.payloadLength); 623 m_continuousFrameData.append(frame.payload, frame.payloadLength);
584 skipBuffer(frameEnd - m_buffer.data()); 624 skipBuffer(frameEnd - m_buffer.data());
585 if (frame.final) { 625 if (frame.final) {
586 // onmessage handler may eventually call the other methods of this c hannel, 626 // onmessage handler may eventually call the other methods of this c hannel,
587 // so we should pretend that we have finished to read this frame and 627 // so we should pretend that we have finished to read this frame and
588 // make sure that the member variables are in a consistent state bef ore 628 // make sure that the member variables are in a consistent state bef ore
589 // the handler is invoked. 629 // the handler is invoked.
590 // Vector<char>::swap() is used here to clear m_continuousFrameData. 630 // Vector<char>::swap() is used here to clear m_continuousFrameData.
591 OwnPtr<Vector<char> > continuousFrameData = adoptPtr(new Vector<char >); 631 OwnPtr<Vector<char> > continuousFrameData = adoptPtr(new Vector<char >);
592 m_continuousFrameData.swap(*continuousFrameData); 632 m_continuousFrameData.swap(*continuousFrameData);
593 m_hasContinuousFrame = false; 633 m_hasContinuousFrame = false;
594 if (m_continuousFrameOpCode == WebSocketFrame::OpCodeText) { 634 if (m_continuousFrameOpCode == WebSocketFrame::OpCodeText) {
595 String message; 635 String message;
596 if (continuousFrameData->size()) 636 if (continuousFrameData->size())
597 message = String::fromUTF8(continuousFrameData->data(), cont inuousFrameData->size()); 637 message = String::fromUTF8(continuousFrameData->data(), cont inuousFrameData->size());
598 else 638 else
599 message = ""; 639 message = "";
600 if (message.isNull()) 640 if (message.isNull())
601 fail("Could not decode a text frame as UTF-8."); 641 failAsError("Could not decode a text frame as UTF-8.");
602 else 642 else
603 m_client->didReceiveMessage(message); 643 m_client->didReceiveMessage(message);
604 } else if (m_continuousFrameOpCode == WebSocketFrame::OpCodeBinary) 644 } else if (m_continuousFrameOpCode == WebSocketFrame::OpCodeBinary)
605 m_client->didReceiveBinaryData(continuousFrameData.release()); 645 m_client->didReceiveBinaryData(continuousFrameData.release());
606 } 646 }
607 break; 647 break;
608 648
609 case WebSocketFrame::OpCodeText: 649 case WebSocketFrame::OpCodeText:
610 if (frame.final) { 650 if (frame.final) {
611 String message; 651 String message;
612 if (frame.payloadLength) 652 if (frame.payloadLength)
613 message = String::fromUTF8(frame.payload, frame.payloadLength); 653 message = String::fromUTF8(frame.payload, frame.payloadLength);
614 else 654 else
615 message = ""; 655 message = "";
616 skipBuffer(frameEnd - m_buffer.data()); 656 skipBuffer(frameEnd - m_buffer.data());
617 if (message.isNull()) 657 if (message.isNull())
618 fail("Could not decode a text frame as UTF-8."); 658 failAsError("Could not decode a text frame as UTF-8.");
619 else 659 else
620 m_client->didReceiveMessage(message); 660 m_client->didReceiveMessage(message);
621 } else { 661 } else {
622 m_hasContinuousFrame = true; 662 m_hasContinuousFrame = true;
623 m_continuousFrameOpCode = WebSocketFrame::OpCodeText; 663 m_continuousFrameOpCode = WebSocketFrame::OpCodeText;
624 ASSERT(m_continuousFrameData.isEmpty()); 664 ASSERT(m_continuousFrameData.isEmpty());
625 m_continuousFrameData.append(frame.payload, frame.payloadLength); 665 m_continuousFrameData.append(frame.payload, frame.payloadLength);
626 skipBuffer(frameEnd - m_buffer.data()); 666 skipBuffer(frameEnd - m_buffer.data());
627 } 667 }
628 break; 668 break;
(...skipping 11 matching lines...) Expand all
640 m_continuousFrameData.append(frame.payload, frame.payloadLength); 680 m_continuousFrameData.append(frame.payload, frame.payloadLength);
641 skipBuffer(frameEnd - m_buffer.data()); 681 skipBuffer(frameEnd - m_buffer.data());
642 } 682 }
643 break; 683 break;
644 684
645 case WebSocketFrame::OpCodeClose: 685 case WebSocketFrame::OpCodeClose:
646 if (!frame.payloadLength) 686 if (!frame.payloadLength)
647 m_closeEventCode = CloseEventCodeNoStatusRcvd; 687 m_closeEventCode = CloseEventCodeNoStatusRcvd;
648 else if (frame.payloadLength == 1) { 688 else if (frame.payloadLength == 1) {
649 m_closeEventCode = CloseEventCodeAbnormalClosure; 689 m_closeEventCode = CloseEventCodeAbnormalClosure;
650 fail("Received a broken close frame containing an invalid size body. "); 690 failAsError("Received a broken close frame containing an invalid siz e body.");
651 return false; 691 return false;
652 } else { 692 } else {
653 unsigned char highByte = static_cast<unsigned char>(frame.payload[0] ); 693 unsigned char highByte = static_cast<unsigned char>(frame.payload[0] );
654 unsigned char lowByte = static_cast<unsigned char>(frame.payload[1]) ; 694 unsigned char lowByte = static_cast<unsigned char>(frame.payload[1]) ;
655 m_closeEventCode = highByte << 8 | lowByte; 695 m_closeEventCode = highByte << 8 | lowByte;
656 if (m_closeEventCode == CloseEventCodeNoStatusRcvd || m_closeEventCo de == CloseEventCodeAbnormalClosure || m_closeEventCode == CloseEventCodeTLSHand shake) { 696 if (m_closeEventCode == CloseEventCodeNoStatusRcvd || m_closeEventCo de == CloseEventCodeAbnormalClosure || m_closeEventCode == CloseEventCodeTLSHand shake) {
657 m_closeEventCode = CloseEventCodeAbnormalClosure; 697 m_closeEventCode = CloseEventCodeAbnormalClosure;
658 fail("Received a broken close frame containing a reserved status code."); 698 failAsError("Received a broken close frame containing a reserved status code.");
659 return false; 699 return false;
660 } 700 }
661 } 701 }
662 if (frame.payloadLength >= 3) 702 if (frame.payloadLength >= 3)
663 m_closeEventReason = String::fromUTF8(&frame.payload[2], frame.paylo adLength - 2); 703 m_closeEventReason = String::fromUTF8(&frame.payload[2], frame.paylo adLength - 2);
664 else 704 else
665 m_closeEventReason = ""; 705 m_closeEventReason = "";
666 skipBuffer(frameEnd - m_buffer.data()); 706 skipBuffer(frameEnd - m_buffer.data());
667 m_receivedClosingHandshake = true; 707 m_receivedClosingHandshake = true;
668 startClosingHandshake(m_closeEventCode, m_closeEventReason); 708 startClosingHandshake(m_closeEventCode, m_closeEventReason);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 void MainThreadWebSocketChannel::processOutgoingFrameQueue() 768 void MainThreadWebSocketChannel::processOutgoingFrameQueue()
729 { 769 {
730 if (m_outgoingFrameQueueStatus == OutgoingFrameQueueClosed) 770 if (m_outgoingFrameQueueStatus == OutgoingFrameQueueClosed)
731 return; 771 return;
732 772
733 while (!m_outgoingFrameQueue.isEmpty()) { 773 while (!m_outgoingFrameQueue.isEmpty()) {
734 OwnPtr<QueuedFrame> frame = m_outgoingFrameQueue.takeFirst(); 774 OwnPtr<QueuedFrame> frame = m_outgoingFrameQueue.takeFirst();
735 switch (frame->frameType) { 775 switch (frame->frameType) {
736 case QueuedFrameTypeString: { 776 case QueuedFrameTypeString: {
737 if (!sendFrame(frame->opCode, frame->stringData.data(), frame->strin gData.length())) 777 if (!sendFrame(frame->opCode, frame->stringData.data(), frame->strin gData.length()))
738 fail("Failed to send WebSocket frame."); 778 failAsError("Failed to send WebSocket frame.");
739 break; 779 break;
740 } 780 }
741 781
742 case QueuedFrameTypeVector: 782 case QueuedFrameTypeVector:
743 if (!sendFrame(frame->opCode, frame->vectorData.data(), frame->vecto rData.size())) 783 if (!sendFrame(frame->opCode, frame->vectorData.data(), frame->vecto rData.size()))
744 fail("Failed to send WebSocket frame."); 784 failAsError("Failed to send WebSocket frame.");
745 break; 785 break;
746 786
747 case QueuedFrameTypeBlob: { 787 case QueuedFrameTypeBlob: {
748 switch (m_blobLoaderStatus) { 788 switch (m_blobLoaderStatus) {
749 case BlobLoaderNotStarted: 789 case BlobLoaderNotStarted:
750 ref(); // Will be derefed after didFinishLoading() or didFail(). 790 ref(); // Will be derefed after didFinishLoading() or didFail().
751 ASSERT(!m_blobLoader); 791 ASSERT(!m_blobLoader);
752 m_blobLoader = adoptPtr(new FileReaderLoader(FileReaderLoader::R eadAsArrayBuffer, this)); 792 m_blobLoader = adoptPtr(new FileReaderLoader(FileReaderLoader::R eadAsArrayBuffer, this));
753 m_blobLoaderStatus = BlobLoaderStarted; 793 m_blobLoaderStatus = BlobLoaderStarted;
754 m_blobLoader->start(m_document, frame->blobData.get()); 794 m_blobLoader->start(m_document, frame->blobData.get());
755 m_outgoingFrameQueue.prepend(frame.release()); 795 m_outgoingFrameQueue.prepend(frame.release());
756 return; 796 return;
757 797
758 case BlobLoaderStarted: 798 case BlobLoaderStarted:
759 case BlobLoaderFailed: 799 case BlobLoaderFailed:
760 m_outgoingFrameQueue.prepend(frame.release()); 800 m_outgoingFrameQueue.prepend(frame.release());
761 return; 801 return;
762 802
763 case BlobLoaderFinished: { 803 case BlobLoaderFinished: {
764 RefPtr<ArrayBuffer> result = m_blobLoader->arrayBufferResult(); 804 RefPtr<ArrayBuffer> result = m_blobLoader->arrayBufferResult();
765 m_blobLoader.clear(); 805 m_blobLoader.clear();
766 m_blobLoaderStatus = BlobLoaderNotStarted; 806 m_blobLoaderStatus = BlobLoaderNotStarted;
767 if (!sendFrame(frame->opCode, static_cast<const char*>(result->d ata()), result->byteLength())) 807 if (!sendFrame(frame->opCode, static_cast<const char*>(result->d ata()), result->byteLength()))
768 fail("Failed to send WebSocket frame."); 808 failAsError("Failed to send WebSocket frame.");
769 break; 809 break;
770 } 810 }
771 } 811 }
772 break; 812 break;
773 } 813 }
774 814
775 default: 815 default:
776 ASSERT_NOT_REACHED(); 816 ASSERT_NOT_REACHED();
777 break; 817 break;
778 } 818 }
(...skipping 19 matching lines...) Expand all
798 bool MainThreadWebSocketChannel::sendFrame(WebSocketFrame::OpCode opCode, const char* data, size_t dataLength) 838 bool MainThreadWebSocketChannel::sendFrame(WebSocketFrame::OpCode opCode, const char* data, size_t dataLength)
799 { 839 {
800 ASSERT(m_handle); 840 ASSERT(m_handle);
801 ASSERT(!m_suspended); 841 ASSERT(!m_suspended);
802 842
803 WebSocketFrame frame(opCode, true, false, true, data, dataLength); 843 WebSocketFrame frame(opCode, true, false, true, data, dataLength);
804 InspectorInstrumentation::didSendWebSocketFrame(m_document, m_identifier, fr ame); 844 InspectorInstrumentation::didSendWebSocketFrame(m_document, m_identifier, fr ame);
805 845
806 OwnPtr<DeflateResultHolder> deflateResult = m_deflateFramer.deflate(frame); 846 OwnPtr<DeflateResultHolder> deflateResult = m_deflateFramer.deflate(frame);
807 if (!deflateResult->succeeded()) { 847 if (!deflateResult->succeeded()) {
808 fail(deflateResult->failureReason()); 848 failAsError(deflateResult->failureReason());
809 return false; 849 return false;
810 } 850 }
811 851
812 Vector<char> frameData; 852 Vector<char> frameData;
813 frame.makeFrameData(frameData); 853 frame.makeFrameData(frameData);
814 854
815 return m_handle->send(frameData.data(), frameData.size()); 855 return m_handle->send(frameData.data(), frameData.size());
816 } 856 }
817 857
818 } // namespace WebCore 858 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698