Changeset 94399 in webkit
- Timestamp:
- Sep 2, 2011, 3:36:43 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 18 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r94395 r94399 1 2011-09-02 Yuta Kitamura <yutak@chromium.org> 2 3 WebSocket: Send Blob as WebSocket binary message 4 https://bugs.webkit.org/show_bug.cgi?id=67465 5 6 Reviewed by Kent Tamura. 7 8 * http/tests/websocket/tests/hixie76/send-empty-expected.txt: Added. 9 * http/tests/websocket/tests/hixie76/send-empty.html: Added. 10 * http/tests/websocket/tests/hixie76/send-object-expected.txt: Added. 11 * http/tests/websocket/tests/hixie76/send-object.html: Added. 12 * http/tests/websocket/tests/hybi/bufferedAmount-after-close-expected.txt: 13 * http/tests/websocket/tests/hybi/bufferedAmount-after-close.html: 14 Updated. Added tests to send Blobs. 15 * http/tests/websocket/tests/hybi/send-blob-expected.txt: Added. 16 * http/tests/websocket/tests/hybi/send-blob.html: 17 Added. Send three Blobs each of which contains a small binary message. 18 * http/tests/websocket/tests/hybi/send-blob_wsh.py: 19 Added. receive_message() returns a unicode value if the received message was text, or 20 a str value if the message was binary. 21 * http/tests/websocket/tests/hybi/send-empty-expected.txt: Added. 22 * http/tests/websocket/tests/hybi/send-empty.html: Added. 23 * http/tests/websocket/tests/hybi/send-file-blob-expected.txt: Added. 24 * http/tests/websocket/tests/hybi/send-file-blob-fail-expected.txt: Added. 25 * http/tests/websocket/tests/hybi/send-file-blob-fail.html: 26 Added. If we delete a file before reading it, FileReaderLoader reliably fails. 27 * http/tests/websocket/tests/hybi/send-file-blob.html: 28 Added. Create a File and try to send it as a Blob. 29 * http/tests/websocket/tests/hybi/send-file-blob_wsh.py: Added. 30 * http/tests/websocket/tests/hybi/workers/resources/send-blob.js: 31 Added. Same as send-blob.html above. 32 * http/tests/websocket/tests/hybi/workers/resources/send-blob_wsh.py: 33 Added. Same as send-blob_wsh.py above. 34 * http/tests/websocket/tests/hybi/workers/send-blob-expected.txt: Added. 35 * http/tests/websocket/tests/hybi/workers/send-blob.html: Added. 36 * platform/gtk/Skipped: 37 send-file-blob.html and send-file-blob-fail.html depend on availability of File API. 38 * platform/mac/Skipped: Ditto. 39 * platform/qt/Skipped: Ditto. 40 * platform/win/Skipped: Ditto. 41 1 42 2011-09-02 Philippe Normand <pnormand@igalia.com> 2 43 -
trunk/LayoutTests/http/tests/websocket/tests/hybi/bufferedAmount-after-close-expected.txt
r94282 r94399 7 7 PASS ws.readyState is 3 8 8 PASS ws.bufferedAmount is 0 9 Testing send(string)... 9 10 PASS ws.send(messageToSend) is false 10 11 PASS bufferedAmountDifference is 27 12 PASS ws.send(messageToSend) is false 13 PASS bufferedAmountDifference is 6 14 PASS ws.send(messageToSend) is false 15 PASS bufferedAmountDifference is 7 16 PASS ws.send(messageToSend) is false 17 PASS bufferedAmountDifference is 131 18 PASS ws.send(messageToSend) is false 19 PASS bufferedAmountDifference is 134 20 PASS ws.send(messageToSend) is false 21 PASS bufferedAmountDifference is 65543 22 PASS ws.send(messageToSend) is false 23 PASS bufferedAmountDifference is 65550 24 Testing send(Blob)... 11 25 PASS ws.send(messageToSend) is false 12 26 PASS bufferedAmountDifference is 6 -
trunk/LayoutTests/http/tests/websocket/tests/hybi/bufferedAmount-after-close.html
r94282 r94399 23 23 } 24 24 25 function createBlobWithLength(length) 26 { 27 var builder = new WebKitBlobBuilder(); 28 builder.append(new ArrayBuffer(length)); 29 return builder.getBlob(); 30 } 31 25 32 var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/simple"); 26 33 … … 38 45 39 46 var baseOverhead = 2 + 4; // Base header size and masking key size. 47 debug("Testing send(string)..."); 40 48 testBufferedAmount('send to closed socket', 21 + baseOverhead); 41 49 testBufferedAmount('', baseOverhead); … … 45 53 testBufferedAmount(createStringWithLength(0xFFFF), 0xFFFF + baseOverhead + 2); 46 54 testBufferedAmount(createStringWithLength(0x10000), 0x10000 + baseOverhead + 8); // With 64-bit extended payload length field. 55 56 debug("Testing send(Blob)..."); 57 testBufferedAmount(createBlobWithLength(0), baseOverhead); 58 testBufferedAmount(createBlobWithLength(1), 1 + baseOverhead); 59 testBufferedAmount(createBlobWithLength(125), 125 + baseOverhead); 60 testBufferedAmount(createBlobWithLength(126), 126 + baseOverhead + 2); 61 testBufferedAmount(createBlobWithLength(0xFFFF), 0xFFFF + baseOverhead + 2); 62 testBufferedAmount(createBlobWithLength(0x10000), 0x10000 + baseOverhead + 8); 47 63 48 64 finishJSTest(); -
trunk/LayoutTests/platform/gtk/Skipped
r94300 r94399 367 367 http/tests/local/fileapi 368 368 http/tests/security/filesystem-iframe-from-remote.html 369 http/tests/websocket/tests/hybi/send-file-blob.html 370 http/tests/websocket/tests/hybi/send-file-blob-fail.html 369 371 370 372 # Requires WebP support. -
trunk/LayoutTests/platform/mac/Skipped
r94280 r94399 278 278 http/tests/filesystem 279 279 http/tests/security/filesystem-iframe-from-remote.html 280 http/tests/websocket/tests/hybi/send-file-blob.html 281 http/tests/websocket/tests/hybi/send-file-blob-fail.html 280 282 281 283 # https://bugs.webkit.org/show_bug.cgi?id=46223 -
trunk/LayoutTests/platform/qt/Skipped
r94283 r94399 100 100 http/tests/filesystem 101 101 http/tests/security/filesystem-iframe-from-remote.html 102 http/tests/websocket/tests/hybi/send-file-blob.html 103 http/tests/websocket/tests/hybi/send-file-blob-fail.html 102 104 103 105 # ENABLE(QUOTA) is disabled. -
trunk/LayoutTests/platform/win/Skipped
r94121 r94399 1203 1203 http/tests/filesystem 1204 1204 http/tests/security/filesystem-iframe-from-remote.html 1205 http/tests/websocket/tests/hybi/send-file-blob.html 1206 http/tests/websocket/tests/hybi/send-file-blob-fail.html 1205 1207 1206 1208 # LayoutTestController::nodesFromRect is not supported. -
trunk/Source/WebCore/ChangeLog
r94397 r94399 1 2011-09-02 Yuta Kitamura <yutak@chromium.org> 2 3 WebSocket: Send Blob as WebSocket binary message 4 https://bugs.webkit.org/show_bug.cgi?id=67465 5 6 Reviewed by Kent Tamura. 7 8 Tests: http/tests/websocket/tests/hixie76/send-empty.html 9 http/tests/websocket/tests/hixie76/send-object.html 10 http/tests/websocket/tests/hybi/send-blob.html 11 http/tests/websocket/tests/hybi/send-empty.html 12 http/tests/websocket/tests/hybi/send-file-blob-fail.html 13 http/tests/websocket/tests/hybi/send-file-blob.html 14 http/tests/websocket/tests/hybi/workers/send-blob.html 15 http/tests/websocket/tests/hybi/bufferedAmount-after-close.html (updated) 16 17 * bindings/js/JSWebSocketCustom.cpp: 18 (WebCore::JSWebSocket::send): 19 * bindings/v8/custom/V8WebSocketCustom.cpp: 20 (WebCore::V8WebSocket::sendCallback): 21 * websockets/ThreadableWebSocketChannel.h: 22 * websockets/WebSocket.cpp: 23 (WebCore::WebSocket::send): 24 * websockets/WebSocket.h: 25 * websockets/WebSocket.idl: 26 Fixing code generator did not sound easy, because there are some classes depending on 27 broken behavior of current code generator (one such example is CanvasRenderingContext2D). 28 As a temporary workaround, new custom handlers for send() are added. 29 * websockets/WebSocketChannel.cpp: 30 (WebCore::WebSocketChannel::send): 31 * websockets/WebSocketChannel.h: 32 * websockets/WorkerThreadableWebSocketChannel.cpp: 33 (WebCore::WorkerThreadableWebSocketChannel::send): 34 (WebCore::WorkerThreadableWebSocketChannel::Peer::send): 35 (WebCore::WorkerThreadableWebSocketChannel::mainThreadSendBlob): 36 A Blob can be deserialized from url, type and size. 37 (WebCore::WorkerThreadableWebSocketChannel::Bridge::send): 38 KURL, String and long long (corresponding to url, type and size, respectively) can be passed 39 safely across threads. 40 * websockets/WorkerThreadableWebSocketChannel.h: 41 1 42 2011-09-02 Philippe Normand <pnormand@igalia.com> 2 43 -
trunk/Source/WebCore/bindings/js/JSWebSocketCustom.cpp
r94387 r94399 37 37 38 38 #include "ExceptionCode.h" 39 #include "JSBlob.h" 40 #include "JSEventListener.h" 39 41 #include "KURL.h" 40 #include "JSEventListener.h"41 42 #include "WebSocket.h" 42 43 #include "WebSocketChannel.h" … … 89 90 } 90 91 92 JSValue JSWebSocket::send(ExecState* exec) 93 { 94 if (!exec->argumentCount()) 95 return throwError(exec, createSyntaxError(exec, "Not enough arguments")); 96 97 JSValue message = exec->argument(0); 98 ExceptionCode ec = 0; 99 bool result; 100 if (message.inherits(&JSBlob::s_info)) 101 result = impl()->send(toBlob(message), ec); 102 else { 103 String stringMessage = ustringToString(message.toString(exec)); 104 if (exec->hadException()) 105 return jsUndefined(); 106 result = impl()->send(stringMessage, ec); 107 } 108 if (ec) { 109 setDOMException(exec, ec); 110 return jsUndefined(); 111 } 112 113 return jsBoolean(result); 114 } 115 91 116 JSValue JSWebSocket::close(ExecState* exec) 92 117 { -
trunk/Source/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
r94387 r94399 39 39 #include "Settings.h" 40 40 #include "V8Binding.h" 41 #include "V8Blob.h" 41 42 #include "V8Proxy.h" 42 43 #include "V8Utilities.h" … … 112 113 } 113 114 115 v8::Handle<v8::Value> V8WebSocket::sendCallback(const v8::Arguments& args) 116 { 117 INC_STATS("DOM.WebSocket.send()"); 118 119 if (!args.Length()) 120 return throwError("Not enough arguments", V8Proxy::SyntaxError); 121 122 WebSocket* webSocket = V8WebSocket::toNative(args.Holder()); 123 v8::Handle<v8::Value> message = args[0]; 124 ExceptionCode ec = 0; 125 bool result; 126 if (V8Blob::HasInstance(message)) { 127 Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(message)); 128 ASSERT(blob); 129 result = webSocket->send(blob, ec); 130 } else { 131 v8::TryCatch tryCatch; 132 v8::Handle<v8::String> stringMessage = message->ToString(); 133 if (tryCatch.HasCaught()) 134 return throwError(tryCatch.Exception()); 135 result = webSocket->send(toWebCoreString(message), ec); 136 } 137 if (ec) 138 return throwError(ec); 139 140 return v8Boolean(result); 141 } 142 114 143 v8::Handle<v8::Value> V8WebSocket::closeCallback(const v8::Arguments& args) 115 144 { -
trunk/Source/WebCore/websockets/ThreadableWebSocketChannel.h
r94387 r94399 40 40 namespace WebCore { 41 41 42 class Blob; 42 43 class KURL; 43 44 class ScriptExecutionContext; … … 54 55 virtual String subprotocol() = 0; // Will be available after didConnect() callback is invoked. 55 56 virtual bool send(const String& message) = 0; 57 virtual bool send(const Blob&) = 0; 56 58 virtual unsigned long bufferedAmount() const = 0; 57 59 virtual void close(int code, const String& reason) = 0; -
trunk/Source/WebCore/websockets/WebSocket.cpp
r94387 r94399 266 266 } 267 267 268 bool WebSocket::send(Blob* binaryData, ExceptionCode& ec) 269 { 270 LOG(Network, "WebSocket %p send blob %s", this, binaryData->url().string().utf8().data()); 271 ASSERT(binaryData); 272 if (m_useHixie76Protocol) 273 return send("[object Blob]", ec); 274 if (m_state == CONNECTING) { 275 ec = INVALID_STATE_ERR; 276 return false; 277 } 278 if (m_state == CLOSING || m_state == CLOSED) { 279 m_bufferedAmountAfterClose += binaryData->size() + getFramingOverhead(binaryData->size()); 280 return false; 281 } 282 ASSERT(m_channel); 283 return m_channel->send(*binaryData); 284 } 285 268 286 void WebSocket::close(int code, const String& reason, ExceptionCode& ec) 269 287 { -
trunk/Source/WebCore/websockets/WebSocket.h
r94387 r94399 47 47 namespace WebCore { 48 48 49 class Blob; 49 50 class ThreadableWebSocketChannel; 50 51 … … 68 69 69 70 bool send(const String& message, ExceptionCode&); 71 bool send(Blob*, ExceptionCode&); 70 72 71 73 void close(int code, const String& reason, ExceptionCode&); -
trunk/Source/WebCore/websockets/WebSocket.idl
r94387 r94399 64 64 setter raises(DOMException); 65 65 66 [RequiresAllArguments] boolean send(in DOMString data) raises(DOMException); 66 // FIXME: Use overloading provided by our IDL code generator. 67 // According to Web IDL specification, overloaded function with DOMString argument 68 // should accept anything that can be converted to a string (including numbers, 69 // booleans, null, undefined and objects except Blob). Current code generator does 70 // not handle this rule correctly. 71 // [RequiresAllArguments] boolean send(in Blob data) raises(DOMException); 72 // [RequiresAllArguments] boolean send(in DOMString data) raises(DOMException); 73 [Custom] boolean send(in DOMString data) raises(DOMException); 74 67 75 // FIXME: Implement and apply [Clamp] attribute instead of [Custom]. 68 76 [Custom] void close(in [Optional] unsigned short code, in [Optional] DOMString reason) raises(DOMException); -
trunk/Source/WebCore/websockets/WebSocketChannel.cpp
r94387 r94399 171 171 } 172 172 173 bool WebSocketChannel::send(const Blob& binaryData) 174 { 175 LOG(Network, "WebSocketChannel %p send blob %s", this, binaryData.url().string().utf8().data()); 176 ASSERT(!m_useHixie76Protocol); 177 enqueueBlobFrame(OpCodeBinary, binaryData); 178 return true; 179 } 180 173 181 unsigned long WebSocketChannel::bufferedAmount() const 174 182 { -
trunk/Source/WebCore/websockets/WebSocketChannel.h
r94387 r94399 67 67 virtual String subprotocol(); 68 68 virtual bool send(const String& message); 69 virtual bool send(const Blob&); 69 70 virtual unsigned long bufferedAmount() const; 70 71 virtual void close(int code, const String& reason); // Start closing handshake. -
trunk/Source/WebCore/websockets/WorkerThreadableWebSocketChannel.cpp
r94387 r94399 35 35 #include "WorkerThreadableWebSocketChannel.h" 36 36 37 #include "Blob.h" 37 38 #include "CrossThreadTask.h" 38 39 #include "PlatformString.h" … … 88 89 } 89 90 91 bool WorkerThreadableWebSocketChannel::send(const Blob& binaryData) 92 { 93 if (!m_bridge) 94 return false; 95 return m_bridge->send(binaryData); 96 } 97 90 98 unsigned long WorkerThreadableWebSocketChannel::bufferedAmount() const 91 99 { … … 170 178 return; 171 179 bool sent = m_mainWebSocketChannel->send(message); 180 m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSend, m_workerClientWrapper, sent), m_taskMode); 181 } 182 183 void WorkerThreadableWebSocketChannel::Peer::send(const Blob& binaryData) 184 { 185 ASSERT(isMainThread()); 186 if (!m_mainWebSocketChannel || !m_workerClientWrapper) 187 return; 188 bool sent = m_mainWebSocketChannel->send(binaryData); 172 189 m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSend, m_workerClientWrapper, sent), m_taskMode); 173 190 } … … 359 376 } 360 377 378 void WorkerThreadableWebSocketChannel::mainThreadSendBlob(ScriptExecutionContext* context, Peer* peer, const KURL& url, const String& type, long long size) 379 { 380 ASSERT(isMainThread()); 381 ASSERT_UNUSED(context, context->isDocument()); 382 ASSERT(peer); 383 384 RefPtr<Blob> blob = Blob::create(url, type, size); 385 peer->send(*blob); 386 } 387 361 388 bool WorkerThreadableWebSocketChannel::Bridge::send(const String& message) 362 389 { … … 366 393 setMethodNotCompleted(); 367 394 m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, AllowCrossThreadAccess(m_peer), message)); 395 RefPtr<Bridge> protect(this); 396 waitForMethodCompletion(); 397 ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get(); 398 return clientWrapper && clientWrapper->sent(); 399 } 400 401 bool WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData) 402 { 403 if (!m_workerClientWrapper) 404 return false; 405 ASSERT(m_peer); 406 setMethodNotCompleted(); 407 m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendBlob, AllowCrossThreadAccess(m_peer), binaryData.url(), binaryData.type(), binaryData.size())); 368 408 RefPtr<Bridge> protect(this); 369 409 waitForMethodCompletion(); -
trunk/Source/WebCore/websockets/WorkerThreadableWebSocketChannel.h
r94387 r94399 65 65 virtual String subprotocol(); 66 66 virtual bool send(const String& message); 67 virtual bool send(const Blob&); 67 68 virtual unsigned long bufferedAmount() const; 68 69 virtual void close(int code, const String& reason); … … 94 95 void connect(const KURL&, const String& protocol); 95 96 void send(const String& message); 97 void send(const Blob&); 96 98 void bufferedAmount(); 97 99 void close(int code, const String& reason); … … 126 128 void connect(const KURL&, const String& protocol); 127 129 bool send(const String& message); 130 bool send(const Blob&); 128 131 unsigned long bufferedAmount(); 129 132 void close(int code, const String& reason); … … 161 164 static void mainThreadConnect(ScriptExecutionContext*, Peer*, const KURL&, const String& protocol); 162 165 static void mainThreadSend(ScriptExecutionContext*, Peer*, const String& message); 166 static void mainThreadSendBlob(ScriptExecutionContext*, Peer*, const KURL&, const String& type, long long size); 163 167 static void mainThreadBufferedAmount(ScriptExecutionContext*, Peer*); 164 168 static void mainThreadClose(ScriptExecutionContext*, Peer*, int code, const String& reason);
Note:
See TracChangeset
for help on using the changeset viewer.