"Not enough arguments" error should be TypeError
[WebKit-https.git] / Source / WebCore / bindings / js / JSWebSocketCustom.cpp
1 /*
2  * Copyright (C) 2011 Google Inc.  All rights reserved.
3  * Copyright (C) 2009, 2010 Apple, Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "config.h"
33
34 #if ENABLE(WEB_SOCKETS)
35
36 #include "JSWebSocket.h"
37
38 #include "ExceptionCode.h"
39 #include "JSArrayBuffer.h"
40 #include "JSBlob.h"
41 #include "JSEventListener.h"
42 #include "KURL.h"
43 #include "WebSocket.h"
44 #include "WebSocketChannel.h"
45 #include <runtime/Error.h>
46 #include <wtf/MathExtras.h>
47 #include <wtf/Vector.h>
48
49 using namespace JSC;
50
51 namespace WebCore {
52
53 EncodedJSValue JSC_HOST_CALL JSWebSocketConstructor::constructJSWebSocket(ExecState* exec)
54 {
55     JSWebSocketConstructor* jsConstructor = jsCast<JSWebSocketConstructor*>(exec->callee());
56     ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
57     if (!context)
58         return throwVMError(exec, createReferenceError(exec, "WebSocket constructor associated document is unavailable"));
59
60     if (!exec->argumentCount())
61         return throwVMError(exec, createTypeError(exec, "Not enough arguments"));
62
63     String urlString = ustringToString(exec->argument(0).toString(exec)->value(exec));
64     if (exec->hadException())
65         return throwVMError(exec, createSyntaxError(exec, "wrong URL"));
66     RefPtr<WebSocket> webSocket = WebSocket::create(context);
67     ExceptionCode ec = 0;
68     if (exec->argumentCount() < 2)
69         webSocket->connect(urlString, ec);
70     else {
71         JSValue protocolsValue = exec->argument(1);
72         if (isJSArray(protocolsValue)) {
73             Vector<String> protocols;
74             JSArray* protocolsArray = asArray(protocolsValue);
75             for (unsigned i = 0; i < protocolsArray->length(); ++i) {
76                 String protocol = ustringToString(protocolsArray->getIndex(i).toString(exec)->value(exec));
77                 if (exec->hadException())
78                     return JSValue::encode(JSValue());
79                 protocols.append(protocol);
80             }
81             webSocket->connect(urlString, protocols, ec);
82         } else {
83             String protocol = ustringToString(protocolsValue.toString(exec)->value(exec));
84             if (exec->hadException())
85                 return JSValue::encode(JSValue());
86             webSocket->connect(urlString, protocol, ec);
87         }
88     }
89     setDOMException(exec, ec);
90     return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), WebSocket, webSocket.get()));
91 }
92
93 JSValue JSWebSocket::send(ExecState* exec)
94 {
95     if (!exec->argumentCount())
96         return throwError(exec, createTypeError(exec, "Not enough arguments"));
97
98     JSValue message = exec->argument(0);
99     ExceptionCode ec = 0;
100     bool result;
101     if (message.inherits(&JSArrayBuffer::s_info))
102         result = impl()->send(toArrayBuffer(message), ec);
103     else if (message.inherits(&JSBlob::s_info))
104         result = impl()->send(toBlob(message), ec);
105     else {
106         String stringMessage = ustringToString(message.toString(exec)->value(exec));
107         if (exec->hadException())
108             return jsUndefined();
109         result = impl()->send(stringMessage, ec);
110     }
111     if (ec) {
112         setDOMException(exec, ec);
113         return jsUndefined();
114     }
115
116     return jsBoolean(result);
117 }
118
119 JSValue JSWebSocket::close(ExecState* exec)
120 {
121     // FIXME: We should implement [Clamp] for IDL binding code generator, and
122     // remove this custom method.
123     WebSocket* webSocket = static_cast<WebSocket*>(impl());
124     size_t argumentCount = exec->argumentCount();
125     int code = WebSocketChannel::CloseEventCodeNotSpecified;
126     String reason = "";
127     if (argumentCount >= 1) {
128         JSValue v = exec->argument(0);
129         double x = v.toNumber(exec);
130         double maxValue = static_cast<double>(std::numeric_limits<uint16_t>::max());
131         double minValue = static_cast<double>(std::numeric_limits<uint16_t>::min());
132         if (isnan(x))
133             x = 0.0;
134         else
135             x = clampTo(x, minValue, maxValue);
136         code = clampToInteger(x);
137         if (argumentCount >= 2) {
138             reason = ustringToString(exec->argument(1).toString(exec)->value(exec));
139             if (exec->hadException()) {
140                 setDOMException(exec, SYNTAX_ERR);
141                 return jsUndefined();
142             }
143         }
144     }
145     ExceptionCode ec = 0;
146     webSocket->close(code, reason, ec);
147     setDOMException(exec, ec);
148     return jsUndefined();
149 }
150
151 } // namespace WebCore
152
153 #endif