예제 #1
0
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;
}
예제 #2
0
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)));
}
예제 #3
0
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();
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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);
}
예제 #7
0
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();
}
예제 #9
0
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();
}
예제 #10
0
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();
}
예제 #11
0
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();
}