static bool setReferrer(FetchRequest::InternalRequest& request, ScriptExecutionContext& context, const Dictionary& init) { String referrer; if (!init.get("referrer", referrer)) return true; if (referrer.isEmpty()) { request.referrer = ASCIILiteral("no-referrer"); return true; } // FIXME: Tighten the URL parsing algorithm according https://url.spec.whatwg.org/#concept-url-parser. URL referrerURL = context.completeURL(referrer); if (!referrerURL.isValid()) return false; if (referrerURL.protocolIs("about") && referrerURL.path() == "client") { request.referrer = ASCIILiteral("client"); return true; } if (!(context.securityOrigin() && context.securityOrigin()->canRequest(referrerURL))) return false; request.referrer = referrerURL.string(); return true; }
RefPtr<FetchRequest> FetchRequest::create(ScriptExecutionContext& context, const String& url, const Dictionary& init, ExceptionCode& ec) { // FIXME: Tighten the URL parsing algorithm according https://url.spec.whatwg.org/#concept-url-parser. URL requestURL = context.completeURL(url); if (!requestURL.isValid() || !requestURL.user().isEmpty() || !requestURL.pass().isEmpty()) { ec = TypeError; return nullptr; } FetchRequest::InternalRequest internalRequest; internalRequest.options.setMode(FetchOptions::Mode::Cors); internalRequest.options.setCredentials(FetchOptions::Credentials::Omit); internalRequest.referrer = ASCIILiteral("client"); internalRequest.request.setURL(requestURL); if (!buildOptions(internalRequest, context, init)) { ec = TypeError; return nullptr; } RefPtr<FetchHeaders> headers = buildHeaders(init, internalRequest); if (!headers) { ec = TypeError; return nullptr; } FetchBody body = buildBody(init, *headers); if (!validateBodyAndMethod(body, internalRequest)) { ec = TypeError; return nullptr; } return adoptRef(*new FetchRequest(context, WTFMove(body), headers.releaseNonNull(), WTFMove(internalRequest))); }
PassRefPtr<EventSource> EventSource::create(ScriptExecutionContext& context, const String& url, const Dictionary& eventSourceInit, ExceptionCode& ec) { if (url.isEmpty()) { ec = SYNTAX_ERR; return 0; } URL fullURL = context.completeURL(url); if (!fullURL.isValid()) { ec = SYNTAX_ERR; return 0; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (context.isDocument()) { Document& document = toDocument(context); shouldBypassMainWorldContentSecurityPolicy = document.frame()->script().shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !context.contentSecurityPolicy()->allowConnectToSource(fullURL)) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return 0; } RefPtr<EventSource> source = adoptRef(new EventSource(context, fullURL, eventSourceInit)); source->setPendingActivity(source.get()); source->scheduleInitialConnect(); source->suspendIfNeeded(); return source.release(); }
RefPtr<EventSource> EventSource::create(ScriptExecutionContext& context, const String& url, const Init& eventSourceInit, ExceptionCode& ec) { if (url.isEmpty()) { ec = SYNTAX_ERR; return nullptr; } URL fullURL = context.completeURL(url); if (!fullURL.isValid()) { ec = SYNTAX_ERR; return nullptr; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. if (!context.contentSecurityPolicy()->allowConnectToSource(fullURL, context.shouldBypassMainWorldContentSecurityPolicy())) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return nullptr; } auto source = adoptRef(*new EventSource(context, fullURL, eventSourceInit)); source->setPendingActivity(source.ptr()); source->scheduleInitialConnect(); source->suspendIfNeeded(); return WTFMove(source); }
bool NavigatorBeacon::sendBeacon(Navigator& navigator, ScriptExecutionContext& context, const String& urlstring, const RefPtr<JSC::ArrayBufferView>& data, ExceptionCode& ec) { NavigatorBeacon& impl = NavigatorBeacon::from(navigator); URL url = context.completeURL(urlstring); if (!impl.canSendBeacon(context, url, ec)) return false; int allowance = impl.maxAllowance(); int bytes = 0; bool allowed = BeaconLoader::sendBeacon(*impl.frame(), allowance, url, data.get(), bytes); return impl.beaconResult(context, allowed, bytes); }
RefPtr<WebSocket> WebSocket::create(ScriptExecutionContext& context, const String& url, const Vector<String>& protocols, ExceptionCode& ec) { if (url.isNull()) { ec = SYNTAX_ERR; return nullptr; } RefPtr<WebSocket> webSocket(adoptRef(*new WebSocket(context))); webSocket->suspendIfNeeded(); webSocket->connect(context.completeURL(url), protocols, ec); if (ec) return nullptr; return WTF::move(webSocket); }
RefPtr<FetchResponse> FetchResponse::redirect(ScriptExecutionContext& context, const String& url, int status, ExceptionCode& ec) { // FIXME: Tighten the URL parsing algorithm according https://url.spec.whatwg.org/#concept-url-parser. URL requestURL = context.completeURL(url); if (!requestURL.isValid() || !requestURL.user().isEmpty() || !requestURL.pass().isEmpty()) { ec = TypeError; return nullptr; } if (!isRedirectStatus(status)) { ec = TypeError; return nullptr; } auto redirectResponse = adoptRef(*new FetchResponse(context, { }, FetchHeaders::create(FetchHeaders::Guard::Immutable), { })); redirectResponse->m_response.setHTTPStatusCode(status); redirectResponse->m_headers->fastSet(HTTPHeaderName::Location, requestURL.string()); return WTFMove(redirectResponse); }
v8::Handle<v8::Value> V8XMLHttpRequest::openCallback(const v8::Arguments& args) { INC_STATS("DOM.XMLHttpRequest.open()"); // Four cases: // open(method, url) // open(method, url, async) // open(method, url, async, user) // open(method, url, async, user, passwd) if (args.Length() < 2) return throwError("Not enough arguments", V8Proxy::SyntaxError); XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); String method = toWebCoreString(args[0]); String urlstring = toWebCoreString(args[1]); ScriptExecutionContext* context = getScriptExecutionContext(); if (!context) return v8::Undefined(); KURL url = context->completeURL(urlstring); ExceptionCode ec = 0; if (args.Length() >= 3) { bool async = args[2]->BooleanValue(); if (args.Length() >= 4 && !args[3]->IsUndefined()) { String user = toWebCoreStringWithNullCheck(args[3]); if (args.Length() >= 5 && !args[4]->IsUndefined()) { String passwd = toWebCoreStringWithNullCheck(args[4]); xmlHttpRequest->open(method, url, async, user, passwd, ec); } else xmlHttpRequest->open(method, url, async, user, ec); } else xmlHttpRequest->open(method, url, async, ec); } else xmlHttpRequest->open(method, url, ec); if (ec) return throwError(ec); return v8::Undefined(); }
v8::Handle<v8::Value> V8XMLHttpRequest::openMethodCustom(const v8::Arguments& args) { // Four cases: // open(method, url) // open(method, url, async) // open(method, url, async, user) // open(method, url, async, user, passwd) if (args.Length() < 2) return throwNotEnoughArgumentsError(args.GetIsolate()); XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(args.Holder()); String method = toWebCoreString(args[0]); String urlstring = toWebCoreString(args[1]); ScriptExecutionContext* context = getScriptExecutionContext(); KURL url = context->completeURL(urlstring); ExceptionCode ec = 0; if (args.Length() >= 3) { bool async = args[2]->BooleanValue(); if (args.Length() >= 4 && !args[3]->IsUndefined()) { String user = toWebCoreStringWithNullCheck(args[3]); if (args.Length() >= 5 && !args[4]->IsUndefined()) { String passwd = toWebCoreStringWithNullCheck(args[4]); xmlHttpRequest->open(method, url, async, user, passwd, ec); } else xmlHttpRequest->open(method, url, async, user, ec); } else xmlHttpRequest->open(method, url, async, ec); } else xmlHttpRequest->open(method, url, ec); if (ec) return setDOMException(ec, args.GetIsolate()); return v8::Undefined(); }
PassRefPtr<Notification> Notification::create(ScriptExecutionContext& context, const String& title, const Dictionary& options) { RefPtr<Notification> notification(adoptRef(new Notification(context, title))); String argument; if (options.get("body", argument)) notification->setBody(argument); if (options.get("tag", argument)) notification->setTag(argument); if (options.get("lang", argument)) notification->setLang(argument); if (options.get("dir", argument)) notification->setDir(argument); if (options.get("icon", argument)) { URL iconURI = argument.isEmpty() ? URL() : context.completeURL(argument); if (!iconURI.isEmpty() && iconURI.isValid()) notification->setIconURL(iconURI); } notification->suspendIfNeeded(); return notification.release(); }
v8::Handle<v8::Value> V8WebSocket::constructorCallback(const v8::Arguments& args) { INC_STATS("DOM.WebSocket.Constructor"); if (!args.IsConstructCall()) return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError); if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) return args.Holder(); if (args.Length() == 0) return throwError("Not enough arguments", V8Proxy::SyntaxError); v8::TryCatch tryCatch; v8::Handle<v8::String> urlstring = args[0]->ToString(); if (tryCatch.HasCaught()) return throwError(tryCatch.Exception()); if (urlstring.IsEmpty()) return throwError("Empty URL", V8Proxy::SyntaxError); // Get the script execution context. ScriptExecutionContext* context = getScriptExecutionContext(); if (!context) return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError); const KURL& url = context->completeURL(toWebCoreString(urlstring)); RefPtr<WebSocket> webSocket = WebSocket::create(context); ExceptionCode ec = 0; if (args.Length() < 2) webSocket->connect(url, ec); else { v8::Local<v8::Value> protocolsValue = args[1]; if (protocolsValue->IsArray()) { Vector<String> protocols; v8::Local<v8::Array> protocolsArray = v8::Local<v8::Array>::Cast(protocolsValue); for (uint32_t i = 0; i < protocolsArray->Length(); ++i) { v8::TryCatch tryCatchProtocol; v8::Handle<v8::String> protocol = protocolsArray->Get(v8::Int32::New(i))->ToString(); if (tryCatchProtocol.HasCaught()) return throwError(tryCatchProtocol.Exception()); protocols.append(toWebCoreString(protocol)); } webSocket->connect(url, protocols, ec); } else { v8::TryCatch tryCatchProtocol; v8::Handle<v8::String> protocol = protocolsValue->ToString(); if (tryCatchProtocol.HasCaught()) return throwError(tryCatchProtocol.Exception()); webSocket->connect(url, toWebCoreString(protocol), ec); } } if (ec) return throwError(ec); // Setup the standard wrapper object internal fields. V8DOMWrapper::setDOMWrapper(args.Holder(), &info, webSocket.get()); // Add object to the wrapper map. webSocket->ref(); V8DOMWrapper::setJSWrapperForActiveDOMObject(webSocket.get(), v8::Persistent<v8::Object>::New(args.Holder())); return args.Holder(); }