1 /* 2 * Copyright (C) 2008, 2009, 2010 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 "V8XMLHttpRequest.h" 33 34 #include "ArrayBuffer.h" 35 #include "Frame.h" 36 #include "InspectorInstrumentation.h" 37 #include "V8ArrayBuffer.h" 38 #include "V8Binding.h" 39 #include "V8Blob.h" 40 #include "V8DOMFormData.h" 41 #include "V8Document.h" 42 #include "V8HTMLDocument.h" 43 #include "V8Proxy.h" 44 #include "V8Utilities.h" 45 #include "WorkerContext.h" 46 #include "WorkerContextExecutionProxy.h" 47 #include "XMLHttpRequest.h" 48 49 namespace WebCore { 50 51 v8::Handle<v8::Value> V8XMLHttpRequest::responseTextAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 52 { 53 INC_STATS("DOM.XMLHttpRequest.responsetext._get"); 54 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder()); 55 ExceptionCode ec = 0; 56 const String& text = xmlHttpRequest->responseText(ec); 57 if (ec) 58 return throwError(ec); 59 return v8String(text); 60 } 61 62 v8::Handle<v8::Value> V8XMLHttpRequest::responseAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 63 { 64 INC_STATS("DOM.XMLHttpRequest.response._get"); 65 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder()); 66 67 switch (xmlHttpRequest->responseTypeCode()) { 68 case XMLHttpRequest::ResponseTypeDefault: 69 case XMLHttpRequest::ResponseTypeText: 70 return responseTextAccessorGetter(name, info); 71 72 case XMLHttpRequest::ResponseTypeDocument: 73 { 74 ExceptionCode ec = 0; 75 Document* document = xmlHttpRequest->responseXML(ec); 76 if (ec) { 77 V8Proxy::setDOMException(ec); 78 return v8::Undefined(); 79 } 80 return toV8(document); 81 } 82 83 case XMLHttpRequest::ResponseTypeBlob: 84 #if ENABLE(XHR_RESPONSE_BLOB) 85 { 86 ExceptionCode ec = 0; 87 Blob* blob = xmlHttpRequest->responseBlob(ec); 88 if (ec) { 89 V8Proxy::setDOMException(ec); 90 return v8::Undefined(); 91 } 92 return toV8(blob); 93 } 94 #else 95 return v8::Undefined(); 96 #endif 97 98 #if ENABLE(WEBGL) || ENABLE(BLOB) 99 case XMLHttpRequest::ResponseTypeArrayBuffer: 100 { 101 ExceptionCode ec = 0; 102 ArrayBuffer* arrayBuffer = xmlHttpRequest->responseArrayBuffer(ec); 103 if (ec) { 104 V8Proxy::setDOMException(ec); 105 return v8::Undefined(); 106 } 107 return toV8(arrayBuffer); 108 } 109 #endif 110 } 111 112 return v8::Undefined(); 113 } 114 115 v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args) 116 { 117 INC_STATS("DOM.XMLHttpRequest.open()"); 118 // Four cases: 119 // open(method, url) 120 // open(method, url, async) 121 // open(method, url, async, user) 122 // open(method, url, async, user, passwd) 123 124 if (args.Length() < 2) 125 return throwError("Not enough arguments", V8Proxy::SyntaxError); 126 127 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 128 129 String method = toWebCoreString(args[0]); 130 String urlstring = toWebCoreString(args[1]); 131 ScriptExecutionContext* context = getScriptExecutionContext(); 132 if (!context) 133 return v8::Undefined(); 134 135 KURL url = context->completeURL(urlstring); 136 137 ExceptionCode ec = 0; 138 139 if (args.Length() >= 3) { 140 bool async = args[2]->BooleanValue(); 141 142 if (args.Length() >= 4 && !args[3]->IsUndefined()) { 143 String user = toWebCoreStringWithNullCheck(args[3]); 144 145 if (args.Length() >= 5 && !args[4]->IsUndefined()) { 146 String passwd = toWebCoreStringWithNullCheck(args[4]); 147 xmlHttpRequest->open(method, url, async, user, passwd, ec); 148 } else 149 xmlHttpRequest->open(method, url, async, user, ec); 150 } else 151 xmlHttpRequest->open(method, url, async, ec); 152 } else 153 xmlHttpRequest->open(method, url, ec); 154 155 if (ec) 156 return throwError(ec); 157 158 return v8::Undefined(); 159 } 160 161 static bool isDocumentType(v8::Handle<v8::Value> value) 162 { 163 // FIXME: add other document types. 164 return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value); 165 } 166 167 v8::Handle<v8::Value> V8XMLHttpRequest::sendCallback(const v8::Arguments& args) 168 { 169 INC_STATS("DOM.XMLHttpRequest.send()"); 170 XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); 171 172 InspectorInstrumentation::willSendXMLHttpRequest(xmlHttpRequest->scriptExecutionContext(), xmlHttpRequest->url()); 173 174 ExceptionCode ec = 0; 175 if (args.Length() < 1) 176 xmlHttpRequest->send(ec); 177 else { 178 v8::Handle<v8::Value> arg = args[0]; 179 if (isUndefinedOrNull(arg)) 180 xmlHttpRequest->send(ec); 181 else if (isDocumentType(arg)) { 182 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); 183 Document* document = V8Document::toNative(object); 184 ASSERT(document); 185 xmlHttpRequest->send(document, ec); 186 } else if (V8Blob::HasInstance(arg)) { 187 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); 188 Blob* blob = V8Blob::toNative(object); 189 ASSERT(blob); 190 xmlHttpRequest->send(blob, ec); 191 } else if (V8DOMFormData::HasInstance(arg)) { 192 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); 193 DOMFormData* domFormData = V8DOMFormData::toNative(object); 194 ASSERT(domFormData); 195 xmlHttpRequest->send(domFormData, ec); 196 #if ENABLE(WEBGL) || ENABLE(BLOB) 197 } else if (V8ArrayBuffer::HasInstance(arg)) { 198 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg); 199 ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(object); 200 ASSERT(arrayBuffer); 201 xmlHttpRequest->send(arrayBuffer, ec); 202 #endif 203 } else 204 xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec); 205 } 206 207 if (ec) 208 return throwError(ec); 209 210 return v8::Undefined(); 211 } 212 213 } // namespace WebCore 214