2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
33 #if ENABLE(WEB_SOCKETS)
35 #include "V8WebSocket.h"
37 #include "ExceptionCode.h"
40 #include "V8ArrayBuffer.h"
41 #include "V8Binding.h"
44 #include "V8Utilities.h"
45 #include "WebSocket.h"
46 #include "WebSocketChannel.h"
47 #include "WorkerContext.h"
48 #include "WorkerContextExecutionProxy.h"
49 #include <wtf/MathExtras.h>
50 #include <wtf/Vector.h>
54 v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args)
56 INC_STATS("DOM.WebSocket.Constructor");
58 if (!args.IsConstructCall())
59 return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);
61 if (ConstructorMode::current() == ConstructorMode::WrapExistingObject)
64 if (args.Length() == 0)
65 return throwError("Not enough arguments", V8Proxy::SyntaxError);
67 v8::TryCatch tryCatch;
68 v8::Handle<v8::String> urlstring = args[0]->ToString();
69 if (tryCatch.HasCaught())
70 return throwError(tryCatch.Exception());
71 if (urlstring.IsEmpty())
72 return throwError("Empty URL", V8Proxy::SyntaxError);
74 // Get the script execution context.
75 ScriptExecutionContext* context = getScriptExecutionContext();
77 return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError);
79 const KURL& url = context->completeURL(toWebCoreString(urlstring));
81 RefPtr<WebSocket> webSocket = WebSocket::create(context);
84 if (args.Length() < 2)
85 webSocket->connect(url, ec);
87 v8::Local<v8::Value> protocolsValue = args[1];
88 if (protocolsValue->IsArray()) {
89 Vector<String> protocols;
90 v8::Local<v8::Array> protocolsArray = v8::Local<v8::Array>::Cast(protocolsValue);
91 for (uint32_t i = 0; i < protocolsArray->Length(); ++i) {
92 v8::TryCatch tryCatchProtocol;
93 v8::Handle<v8::String> protocol = protocolsArray->Get(v8::Int32::New(i))->ToString();
94 if (tryCatchProtocol.HasCaught())
95 return throwError(tryCatchProtocol.Exception());
96 protocols.append(toWebCoreString(protocol));
98 webSocket->connect(url, protocols, ec);
100 v8::TryCatch tryCatchProtocol;
101 v8::Handle<v8::String> protocol = protocolsValue->ToString();
102 if (tryCatchProtocol.HasCaught())
103 return throwError(tryCatchProtocol.Exception());
104 webSocket->connect(url, toWebCoreString(protocol), ec);
108 return throwError(ec);
110 // Setup the standard wrapper object internal fields.
111 V8DOMWrapper::setDOMWrapper(args.Holder(), &info, webSocket.get());
113 // Add object to the wrapper map.
115 V8DOMWrapper::setJSWrapperForActiveDOMObject(webSocket.get(), v8::Persistent<v8::Object>::New(args.Holder()));
117 return args.Holder();
120 v8::Handle<v8::Value> V8WebSocket::sendCallback(const v8::Arguments& args)
122 INC_STATS("DOM.WebSocket.send()");
125 return throwError("Not enough arguments", V8Proxy::SyntaxError);
127 WebSocket* webSocket = V8WebSocket::toNative(args.Holder());
128 v8::Handle<v8::Value> message = args[0];
129 ExceptionCode ec = 0;
131 if (V8ArrayBuffer::HasInstance(message)) {
132 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(v8::Handle<v8::Object>::Cast(message));
134 result = webSocket->send(arrayBuffer, ec);
135 } else if (V8Blob::HasInstance(message)) {
136 Blob* blob = V8Blob::toNative(v8::Handle<v8::Object>::Cast(message));
138 result = webSocket->send(blob, ec);
140 v8::TryCatch tryCatch;
141 v8::Handle<v8::String> stringMessage = message->ToString();
142 if (tryCatch.HasCaught())
143 return throwError(tryCatch.Exception());
144 result = webSocket->send(toWebCoreString(stringMessage), ec);
147 return throwError(ec);
149 return v8Boolean(result);
152 v8::Handle<v8::Value> V8WebSocket::closeCallback(const v8::Arguments& args)
154 // FIXME: We should implement [Clamp] for IDL binding code generator, and
155 // remove this custom method.
156 WebSocket* webSocket = toNative(args.Holder());
157 int argumentCount = args.Length();
158 int code = WebSocketChannel::CloseEventCodeNotSpecified;
160 if (argumentCount >= 1) {
161 double x = args[0]->NumberValue();
162 double maxValue = static_cast<double>(std::numeric_limits<uint16_t>::max());
163 double minValue = static_cast<double>(std::numeric_limits<uint16_t>::min());
167 x = clampTo(x, minValue, maxValue);
168 code = clampToInteger(x);
169 if (argumentCount >= 2) {
170 v8::TryCatch tryCatch;
171 v8::Handle<v8::String> reasonValue = args[1]->ToString();
172 if (tryCatch.HasCaught())
173 return throwError(tryCatch.Exception());
174 reason = toWebCoreString(reasonValue);
177 ExceptionCode ec = 0;
178 webSocket->close(code, reason, ec);
180 return throwError(ec);
181 return v8::Undefined();
184 } // namespace WebCore
186 #endif // ENABLE(WEB_SOCKETS)