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

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

Issue 690883002: Rename NewWebSocketChannelImpl to DocumentWebSocketChannel. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase Created 6 years, 1 month 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
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "modules/websockets/NewWebSocketChannelImpl.h"
33
34 #include "core/dom/Document.h"
35 #include "core/dom/ExecutionContext.h"
36 #include "core/fileapi/FileReaderLoader.h"
37 #include "core/fileapi/FileReaderLoaderClient.h"
38 #include "core/frame/LocalFrame.h"
39 #include "core/inspector/ConsoleMessage.h"
40 #include "core/inspector/InspectorInstrumentation.h"
41 #include "core/inspector/InspectorTraceEvents.h"
42 #include "core/loader/FrameLoader.h"
43 #include "core/loader/FrameLoaderClient.h"
44 #include "core/loader/MixedContentChecker.h"
45 #include "core/loader/UniqueIdentifier.h"
46 #include "modules/websockets/WebSocketChannelClient.h"
47 #include "modules/websockets/WebSocketFrame.h"
48 #include "platform/Logging.h"
49 #include "platform/network/WebSocketHandshakeRequest.h"
50 #include "platform/weborigin/SecurityOrigin.h"
51 #include "public/platform/Platform.h"
52 #include "public/platform/WebSerializedOrigin.h"
53 #include "public/platform/WebSocketHandshakeRequestInfo.h"
54 #include "public/platform/WebSocketHandshakeResponseInfo.h"
55 #include "public/platform/WebString.h"
56 #include "public/platform/WebURL.h"
57 #include "public/platform/WebVector.h"
58
59 using blink::WebSocketHandle;
60
61 namespace blink {
62
63 class NewWebSocketChannelImpl::BlobLoader final : public GarbageCollectedFinaliz ed<NewWebSocketChannelImpl::BlobLoader>, public FileReaderLoaderClient {
64 public:
65 BlobLoader(PassRefPtr<BlobDataHandle>, NewWebSocketChannelImpl*);
66 virtual ~BlobLoader() { }
67
68 void cancel();
69
70 // FileReaderLoaderClient functions.
71 virtual void didStartLoading() override { }
72 virtual void didReceiveData() override { }
73 virtual void didFinishLoading() override;
74 virtual void didFail(FileError::ErrorCode) override;
75
76 void trace(Visitor* visitor)
77 {
78 visitor->trace(m_channel);
79 }
80
81 private:
82 Member<NewWebSocketChannelImpl> m_channel;
83 FileReaderLoader m_loader;
84 };
85
86 NewWebSocketChannelImpl::BlobLoader::BlobLoader(PassRefPtr<BlobDataHandle> blobD ataHandle, NewWebSocketChannelImpl* channel)
87 : m_channel(channel)
88 , m_loader(FileReaderLoader::ReadAsArrayBuffer, this)
89 {
90 m_loader.start(channel->executionContext(), blobDataHandle);
91 }
92
93 void NewWebSocketChannelImpl::BlobLoader::cancel()
94 {
95 m_loader.cancel();
96 // didFail will be called immediately.
97 // |this| is deleted here.
98 }
99
100 void NewWebSocketChannelImpl::BlobLoader::didFinishLoading()
101 {
102 m_channel->didFinishLoadingBlob(m_loader.arrayBufferResult());
103 // |this| is deleted here.
104 }
105
106 void NewWebSocketChannelImpl::BlobLoader::didFail(FileError::ErrorCode errorCode )
107 {
108 m_channel->didFailLoadingBlob(errorCode);
109 // |this| is deleted here.
110 }
111
112 NewWebSocketChannelImpl::NewWebSocketChannelImpl(ExecutionContext* context, WebS ocketChannelClient* client, const String& sourceURL, unsigned lineNumber, WebSoc ketHandle *handle)
113 : ContextLifecycleObserver(context)
114 , m_handle(adoptPtr(handle ? handle : Platform::current()->createWebSocketHa ndle()))
115 , m_client(client)
116 , m_identifier(0)
117 , m_sendingQuota(0)
118 , m_receivedDataSizeForFlowControl(receivedDataSizeForFlowControlHighWaterMa rk * 2) // initial quota
119 , m_sentSizeOfTopMessage(0)
120 , m_sourceURLAtConstruction(sourceURL)
121 , m_lineNumberAtConstruction(lineNumber)
122 {
123 if (context->isDocument() && toDocument(context)->page())
124 m_identifier = createUniqueIdentifier();
125 }
126
127 NewWebSocketChannelImpl::~NewWebSocketChannelImpl()
128 {
129 ASSERT(!m_blobLoader);
130 }
131
132 bool NewWebSocketChannelImpl::connect(const KURL& url, const String& protocol)
133 {
134 WTF_LOG(Network, "NewWebSocketChannelImpl %p connect()", this);
135 if (!m_handle)
136 return false;
137
138 if (executionContext()->isDocument() && document()->frame()) {
139 if (!document()->frame()->loader().mixedContentChecker()->canConnectInse cureWebSocket(document()->securityOrigin(), url))
140 return false;
141 }
142 if (MixedContentChecker::isMixedContent(document()->securityOrigin(), url)) {
143 String message = "Connecting to a non-secure WebSocket server from a sec ure origin is deprecated.";
144 document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, Wa rningMessageLevel, message));
145 }
146
147 m_url = url;
148 Vector<String> protocols;
149 // Avoid placing an empty token in the Vector when the protocol string is
150 // empty.
151 if (!protocol.isEmpty()) {
152 // Since protocol is already verified and escaped, we can simply split
153 // it.
154 protocol.split(", ", true, protocols);
155 }
156 WebVector<WebString> webProtocols(protocols.size());
157 for (size_t i = 0; i < protocols.size(); ++i) {
158 webProtocols[i] = protocols[i];
159 }
160
161 if (executionContext()->isDocument() && document()->frame())
162 document()->frame()->loader().client()->dispatchWillOpenWebSocket(m_hand le.get());
163 m_handle->connect(url, webProtocols, *executionContext()->securityOrigin(), this);
164
165 flowControlIfNecessary();
166 if (m_identifier) {
167 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "We bSocketCreate", "data", InspectorWebSocketCreateEvent::data(document(), m_identi fier, url, protocol));
168 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack" ), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
169 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Ti meline migrates to tracing.
170 InspectorInstrumentation::didCreateWebSocket(document(), m_identifier, u rl, protocol);
171 }
172 return true;
173 }
174
175 void NewWebSocketChannelImpl::send(const String& message)
176 {
177 WTF_LOG(Network, "NewWebSocketChannelImpl %p sendText(%s)", this, message.ut f8().data());
178 if (m_identifier) {
179 // FIXME: Change the inspector API to show the entire message instead
180 // of individual frames.
181 CString data = message.utf8();
182 InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier , WebSocketFrame::OpCodeText, true, data.data(), data.length());
183 }
184 m_messages.append(adoptPtr(new Message(message)));
185 sendInternal();
186 }
187
188 void NewWebSocketChannelImpl::send(PassRefPtr<BlobDataHandle> blobDataHandle)
189 {
190 WTF_LOG(Network, "NewWebSocketChannelImpl %p sendBlob(%s, %s, %llu)", this, blobDataHandle->uuid().utf8().data(), blobDataHandle->type().utf8().data(), blob DataHandle->size());
191 if (m_identifier) {
192 // FIXME: Change the inspector API to show the entire message instead
193 // of individual frames.
194 // FIXME: We can't access the data here.
195 // Since Binary data are not displayed in Inspector, this does not
196 // affect actual behavior.
197 InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier , WebSocketFrame::OpCodeBinary, true, "", 0);
198 }
199 m_messages.append(adoptPtr(new Message(blobDataHandle)));
200 sendInternal();
201 }
202
203 void NewWebSocketChannelImpl::send(const ArrayBuffer& buffer, unsigned byteOffse t, unsigned byteLength)
204 {
205 WTF_LOG(Network, "NewWebSocketChannelImpl %p sendArrayBuffer(%p, %u, %u)", t his, buffer.data(), byteOffset, byteLength);
206 if (m_identifier) {
207 // FIXME: Change the inspector API to show the entire message instead
208 // of individual frames.
209 InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier , WebSocketFrame::OpCodeBinary, true, static_cast<const char*>(buffer.data()) + byteOffset, byteLength);
210 }
211 // buffer.slice copies its contents.
212 // FIXME: Reduce copy by sending the data immediately when we don't need to
213 // queue the data.
214 m_messages.append(adoptPtr(new Message(buffer.slice(byteOffset, byteOffset + byteLength))));
215 sendInternal();
216 }
217
218 void NewWebSocketChannelImpl::send(PassOwnPtr<Vector<char> > data)
219 {
220 WTF_LOG(Network, "NewWebSocketChannelImpl %p sendVector(%p, %llu)", this, da ta.get(), static_cast<unsigned long long>(data->size()));
221 if (m_identifier) {
222 // FIXME: Change the inspector API to show the entire message instead
223 // of individual frames.
224 InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier , WebSocketFrame::OpCodeBinary, true, data->data(), data->size());
225 }
226 m_messages.append(adoptPtr(new Message(data)));
227 sendInternal();
228 }
229
230 void NewWebSocketChannelImpl::close(int code, const String& reason)
231 {
232 WTF_LOG(Network, "NewWebSocketChannelImpl %p close(%d, %s)", this, code, rea son.utf8().data());
233 ASSERT(m_handle);
234 unsigned short codeToSend = static_cast<unsigned short>(code == CloseEventCo deNotSpecified ? CloseEventCodeNoStatusRcvd : code);
235 m_messages.append(adoptPtr(new Message(codeToSend, reason)));
236 sendInternal();
237 }
238
239 void NewWebSocketChannelImpl::fail(const String& reason, MessageLevel level, con st String& sourceURL, unsigned lineNumber)
240 {
241 WTF_LOG(Network, "NewWebSocketChannelImpl %p fail(%s)", this, reason.utf8(). data());
242 // m_handle and m_client can be null here.
243
244 if (m_identifier)
245 InspectorInstrumentation::didReceiveWebSocketFrameError(document(), m_id entifier, reason);
246 const String message = "WebSocket connection to '" + m_url.elidedString() + "' failed: " + reason;
247 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource , level, message, sourceURL, lineNumber));
248
249 if (m_client)
250 m_client->didError();
251 // |reason| is only for logging and should not be provided for scripts,
252 // hence close reason must be empty.
253 handleDidClose(false, CloseEventCodeAbnormalClosure, String());
254 // handleDidClose may delete this object.
255 }
256
257 void NewWebSocketChannelImpl::disconnect()
258 {
259 WTF_LOG(Network, "NewWebSocketChannelImpl %p disconnect()", this);
260 if (m_identifier) {
261 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "We bSocketDestroy", "data", InspectorWebSocketEvent::data(document(), m_identifier) );
262 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack" ), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
263 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Ti meline migrates to tracing.
264 InspectorInstrumentation::didCloseWebSocket(document(), m_identifier);
265 }
266 abortAsyncOperations();
267 m_handle.clear();
268 m_client = nullptr;
269 m_identifier = 0;
270 }
271
272 void NewWebSocketChannelImpl::suspend()
273 {
274 WTF_LOG(Network, "NewWebSocketChannelImpl %p suspend()", this);
275 }
276
277 void NewWebSocketChannelImpl::resume()
278 {
279 WTF_LOG(Network, "NewWebSocketChannelImpl %p resume()", this);
280 }
281
282 NewWebSocketChannelImpl::Message::Message(const String& text)
283 : type(MessageTypeText)
284 , text(text.utf8(StrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD)) { }
285
286 NewWebSocketChannelImpl::Message::Message(PassRefPtr<BlobDataHandle> blobDataHan dle)
287 : type(MessageTypeBlob)
288 , blobDataHandle(blobDataHandle) { }
289
290 NewWebSocketChannelImpl::Message::Message(PassRefPtr<ArrayBuffer> arrayBuffer)
291 : type(MessageTypeArrayBuffer)
292 , arrayBuffer(arrayBuffer) { }
293
294 NewWebSocketChannelImpl::Message::Message(PassOwnPtr<Vector<char> > vectorData)
295 : type(MessageTypeVector)
296 , vectorData(vectorData) { }
297
298 NewWebSocketChannelImpl::Message::Message(unsigned short code, const String& rea son)
299 : type(MessageTypeClose)
300 , code(code)
301 , reason(reason) { }
302
303 void NewWebSocketChannelImpl::sendInternal()
304 {
305 ASSERT(m_handle);
306 unsigned long consumedBufferedAmount = 0;
307 while (!m_messages.isEmpty() && !m_blobLoader) {
308 bool final = false;
309 Message* message = m_messages.first().get();
310 if (m_sendingQuota <= 0 && message->type != MessageTypeClose)
311 break;
312 switch (message->type) {
313 case MessageTypeText: {
314 WebSocketHandle::MessageType type =
315 m_sentSizeOfTopMessage ? WebSocketHandle::MessageTypeContinuatio n : WebSocketHandle::MessageTypeText;
316 size_t size = std::min(static_cast<size_t>(m_sendingQuota), message- >text.length() - m_sentSizeOfTopMessage);
317 final = (m_sentSizeOfTopMessage + size == message->text.length());
318 m_handle->send(final, type, message->text.data() + m_sentSizeOfTopMe ssage, size);
319 m_sentSizeOfTopMessage += size;
320 m_sendingQuota -= size;
321 consumedBufferedAmount += size;
322 break;
323 }
324 case MessageTypeBlob:
325 ASSERT(!m_blobLoader);
326 m_blobLoader = new BlobLoader(message->blobDataHandle, this);
327 break;
328 case MessageTypeArrayBuffer: {
329 WebSocketHandle::MessageType type =
330 m_sentSizeOfTopMessage ? WebSocketHandle::MessageTypeContinuatio n : WebSocketHandle::MessageTypeBinary;
331 size_t size = std::min(static_cast<size_t>(m_sendingQuota), message- >arrayBuffer->byteLength() - m_sentSizeOfTopMessage);
332 final = (m_sentSizeOfTopMessage + size == message->arrayBuffer->byte Length());
333 m_handle->send(final, type, static_cast<const char*>(message->arrayB uffer->data()) + m_sentSizeOfTopMessage, size);
334 m_sentSizeOfTopMessage += size;
335 m_sendingQuota -= size;
336 consumedBufferedAmount += size;
337 break;
338 }
339 case MessageTypeVector: {
340 WebSocketHandle::MessageType type =
341 m_sentSizeOfTopMessage ? WebSocketHandle::MessageTypeContinuatio n : WebSocketHandle::MessageTypeBinary;
342 size_t size = std::min(static_cast<size_t>(m_sendingQuota), message- >vectorData->size() - m_sentSizeOfTopMessage);
343 final = (m_sentSizeOfTopMessage + size == message->vectorData->size( ));
344 m_handle->send(final, type, message->vectorData->data() + m_sentSize OfTopMessage, size);
345 m_sentSizeOfTopMessage += size;
346 m_sendingQuota -= size;
347 consumedBufferedAmount += size;
348 break;
349 }
350 case MessageTypeClose: {
351 // No message should be sent from now on.
352 ASSERT(m_messages.size() == 1);
353 m_handle->close(message->code, message->reason);
354 final = true;
355 break;
356 }
357 }
358 if (final) {
359 m_messages.removeFirst();
360 m_sentSizeOfTopMessage = 0;
361 }
362 }
363 if (m_client && consumedBufferedAmount > 0)
364 m_client->didConsumeBufferedAmount(consumedBufferedAmount);
365 }
366
367 void NewWebSocketChannelImpl::flowControlIfNecessary()
368 {
369 if (!m_handle || m_receivedDataSizeForFlowControl < receivedDataSizeForFlowC ontrolHighWaterMark) {
370 return;
371 }
372 m_handle->flowControl(m_receivedDataSizeForFlowControl);
373 m_receivedDataSizeForFlowControl = 0;
374 }
375
376 void NewWebSocketChannelImpl::abortAsyncOperations()
377 {
378 if (m_blobLoader) {
379 m_blobLoader->cancel();
380 m_blobLoader.clear();
381 }
382 }
383
384 void NewWebSocketChannelImpl::handleDidClose(bool wasClean, unsigned short code, const String& reason)
385 {
386 m_handle.clear();
387 abortAsyncOperations();
388 if (!m_client) {
389 return;
390 }
391 WebSocketChannelClient* client = m_client;
392 m_client = nullptr;
393 WebSocketChannelClient::ClosingHandshakeCompletionStatus status =
394 wasClean ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketC hannelClient::ClosingHandshakeIncomplete;
395 client->didClose(status, code, reason);
396 // client->didClose may delete this object.
397 }
398
399 Document* NewWebSocketChannelImpl::document()
400 {
401 ASSERT(m_identifier);
402 ExecutionContext* context = executionContext();
403 ASSERT(context->isDocument());
404 return toDocument(context);
405 }
406
407 void NewWebSocketChannelImpl::didConnect(WebSocketHandle* handle, bool fail, con st WebString& selectedProtocol, const WebString& extensions)
408 {
409 WTF_LOG(Network, "NewWebSocketChannelImpl %p didConnect(%p, %d, %s, %s)", th is, handle, fail, selectedProtocol.utf8().data(), extensions.utf8().data());
410
411 ASSERT(m_handle);
412 ASSERT(handle == m_handle);
413 ASSERT(m_client);
414
415 if (fail) {
416 failAsError("Cannot connect to " + m_url.string() + ".");
417 // failAsError may delete this object.
418 return;
419 }
420 m_client->didConnect(selectedProtocol, extensions);
421 }
422
423 void NewWebSocketChannelImpl::didStartOpeningHandshake(WebSocketHandle* handle, const WebSocketHandshakeRequestInfo& request)
424 {
425 WTF_LOG(Network, "NewWebSocketChannelImpl %p didStartOpeningHandshake(%p)", this, handle);
426
427 ASSERT(m_handle);
428 ASSERT(handle == m_handle);
429
430 if (m_identifier) {
431 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "We bSocketSendHandshakeRequest", "data", InspectorWebSocketEvent::data(document(), m_identifier));
432 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack" ), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
433 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Ti meline migrates to tracing.
434 InspectorInstrumentation::willSendWebSocketHandshakeRequest(document(), m_identifier, &request.toCoreRequest());
435 m_handshakeRequest = WebSocketHandshakeRequest::create(request.toCoreReq uest());
436 }
437 }
438
439 void NewWebSocketChannelImpl::didFinishOpeningHandshake(WebSocketHandle* handle, const WebSocketHandshakeResponseInfo& response)
440 {
441 WTF_LOG(Network, "NewWebSocketChannelImpl %p didFinishOpeningHandshake(%p)", this, handle);
442
443 ASSERT(m_handle);
444 ASSERT(handle == m_handle);
445
446 if (m_identifier) {
447 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "We bSocketReceiveHandshakeResponse", "data", InspectorWebSocketEvent::data(document (), m_identifier));
448 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Ti meline migrates to tracing.
449 InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(document( ), m_identifier, m_handshakeRequest.get(), &response.toCoreResponse());
450 }
451 m_handshakeRequest.clear();
452 }
453
454 void NewWebSocketChannelImpl::didFail(WebSocketHandle* handle, const WebString& message)
455 {
456 WTF_LOG(Network, "NewWebSocketChannelImpl %p didFail(%p, %s)", this, handle, message.utf8().data());
457
458 ASSERT(m_handle);
459 ASSERT(handle == m_handle);
460
461 // This function is called when the browser is required to fail the
462 // WebSocketConnection. Hence we fail this channel by calling
463 // |this->failAsError| function.
464 failAsError(message);
465 // |this| may be deleted.
466 }
467
468 void NewWebSocketChannelImpl::didReceiveData(WebSocketHandle* handle, bool fin, WebSocketHandle::MessageType type, const char* data, size_t size)
469 {
470 WTF_LOG(Network, "NewWebSocketChannelImpl %p didReceiveData(%p, %d, %d, (%p, %zu))", this, handle, fin, type, data, size);
471
472 ASSERT(m_handle);
473 ASSERT(handle == m_handle);
474 ASSERT(m_client);
475 // Non-final frames cannot be empty.
476 ASSERT(fin || size);
477
478 switch (type) {
479 case WebSocketHandle::MessageTypeText:
480 ASSERT(m_receivingMessageData.isEmpty());
481 m_receivingMessageTypeIsText = true;
482 break;
483 case WebSocketHandle::MessageTypeBinary:
484 ASSERT(m_receivingMessageData.isEmpty());
485 m_receivingMessageTypeIsText = false;
486 break;
487 case WebSocketHandle::MessageTypeContinuation:
488 ASSERT(!m_receivingMessageData.isEmpty());
489 break;
490 }
491
492 m_receivingMessageData.append(data, size);
493 m_receivedDataSizeForFlowControl += size;
494 flowControlIfNecessary();
495 if (!fin) {
496 return;
497 }
498 if (m_identifier) {
499 // FIXME: Change the inspector API to show the entire message instead
500 // of individual frames.
501 WebSocketFrame::OpCode opcode = m_receivingMessageTypeIsText ? WebSocket Frame::OpCodeText : WebSocketFrame::OpCodeBinary;
502 WebSocketFrame frame(opcode, m_receivingMessageData.data(), m_receivingM essageData.size(), WebSocketFrame::Final);
503 InspectorInstrumentation::didReceiveWebSocketFrame(document(), m_identif ier, frame.opCode, frame.masked, frame.payload, frame.payloadLength);
504 }
505 if (m_receivingMessageTypeIsText) {
506 String message = m_receivingMessageData.isEmpty() ? emptyString() : Stri ng::fromUTF8(m_receivingMessageData.data(), m_receivingMessageData.size());
507 m_receivingMessageData.clear();
508 if (message.isNull()) {
509 failAsError("Could not decode a text frame as UTF-8.");
510 // failAsError may delete this object.
511 } else {
512 m_client->didReceiveTextMessage(message);
513 }
514 } else {
515 OwnPtr<Vector<char> > binaryData = adoptPtr(new Vector<char>);
516 binaryData->swap(m_receivingMessageData);
517 m_client->didReceiveBinaryMessage(binaryData.release());
518 }
519 }
520
521 void NewWebSocketChannelImpl::didClose(WebSocketHandle* handle, bool wasClean, u nsigned short code, const WebString& reason)
522 {
523 WTF_LOG(Network, "NewWebSocketChannelImpl %p didClose(%p, %d, %u, %s)", this , handle, wasClean, code, String(reason).utf8().data());
524
525 ASSERT(m_handle);
526 ASSERT(handle == m_handle);
527
528 m_handle.clear();
529
530 if (m_identifier) {
531 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "We bSocketDestroy", "data", InspectorWebSocketEvent::data(document(), m_identifier) );
532 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack" ), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
533 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Ti meline migrates to tracing.
534 InspectorInstrumentation::didCloseWebSocket(document(), m_identifier);
535 m_identifier = 0;
536 }
537
538 handleDidClose(wasClean, code, reason);
539 // handleDidClose may delete this object.
540 }
541
542 void NewWebSocketChannelImpl::didReceiveFlowControl(WebSocketHandle* handle, int 64_t quota)
543 {
544 WTF_LOG(Network, "NewWebSocketChannelImpl %p didReceiveFlowControl(%p, %ld)" , this, handle, static_cast<long>(quota));
545
546 ASSERT(m_handle);
547 ASSERT(handle == m_handle);
548
549 m_sendingQuota += quota;
550 sendInternal();
551 }
552
553 void NewWebSocketChannelImpl::didStartClosingHandshake(WebSocketHandle* handle)
554 {
555 WTF_LOG(Network, "NewWebSocketChannelImpl %p didStartClosingHandshake(%p)", this, handle);
556
557 ASSERT(m_handle);
558 ASSERT(handle == m_handle);
559
560 if (m_client)
561 m_client->didStartClosingHandshake();
562 }
563
564 void NewWebSocketChannelImpl::didFinishLoadingBlob(PassRefPtr<ArrayBuffer> buffe r)
565 {
566 m_blobLoader.clear();
567 ASSERT(m_handle);
568 // The loaded blob is always placed on m_messages[0].
569 ASSERT(m_messages.size() > 0 && m_messages.first()->type == MessageTypeBlob) ;
570 // We replace it with the loaded blob.
571 m_messages.first() = adoptPtr(new Message(buffer));
572 sendInternal();
573 }
574
575 void NewWebSocketChannelImpl::didFailLoadingBlob(FileError::ErrorCode errorCode)
576 {
577 m_blobLoader.clear();
578 if (errorCode == FileError::ABORT_ERR) {
579 // The error is caused by cancel().
580 return;
581 }
582 // FIXME: Generate human-friendly reason message.
583 failAsError("Failed to load Blob: error code = " + String::number(errorCode) );
584 // |this| can be deleted here.
585 }
586
587 void NewWebSocketChannelImpl::trace(Visitor* visitor)
588 {
589 visitor->trace(m_blobLoader);
590 visitor->trace(m_client);
591 WebSocketChannel::trace(visitor);
592 }
593
594 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/websockets/NewWebSocketChannelImpl.h ('k') | Source/modules/websockets/NewWebSocketChannelImplTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698