ContentDispositionType contentDispositionType(const String& contentDisposition)
{
    if (contentDisposition.isEmpty())
        return ContentDispositionNone;

    Vector<String> parameters;
    contentDisposition.split(';', parameters);

    String dispositionType = parameters[0];
    dispositionType.stripWhiteSpace();

    if (equalIgnoringCase(dispositionType, "inline"))
        return ContentDispositionInline;

    // Some broken sites just send bogus headers like
    //
    //   Content-Disposition: ; filename="file"
    //   Content-Disposition: filename="file"
    //   Content-Disposition: name="file"
    //
    // without a disposition token... screen those out.
    if (!isValidHTTPToken(dispositionType))
        return ContentDispositionNone;

    // We have a content-disposition of "attachment" or unknown.
    // RFC 2183, section 2.8 says that an unknown disposition
    // value should be treated as "attachment"
    return ContentDispositionAttachment;  
}
bool FetchHeaders::has(const String& name, ExceptionCode& ec) const
{
    if (!isValidHTTPToken(name)) {
        ec = TypeError;
        return false;
    }
    return m_headers.contains(name);
}
String FetchHeaders::get(const String& name, ExceptionCode& ec) const
{
    if (!isValidHTTPToken(name)) {
        ec = TypeError;
        return String();
    }
    return m_headers.get(name);
}
Exemple #4
0
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec)
{
    internalAbort();
    State previousState = m_state;
    m_state = UNSENT;
    m_error = false;
    m_uploadComplete = false;

    // clear stuff from possible previous load
    clearResponse();
    clearRequest();

    ASSERT(m_state == UNSENT);

    if (!isValidHTTPToken(method)) {
        ec = SYNTAX_ERR;
        return;
    }

    if (!isAllowedHTTPMethod(method)) {
        ec = SECURITY_ERR;
        return;
    }

    if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectFromSource(url)) {
        // FIXME: Should this be throwing an exception?
        ec = SECURITY_ERR;
        return;
    }

    // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated 
    // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
    // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
    // such as file: and data: still make sense to allow.
    if (!async && scriptExecutionContext()->isDocument() && url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) {
        logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) requests made from the window context cannot have XMLHttpRequest.responseType set.");
        ec = INVALID_ACCESS_ERR;
        return;
    }

    m_method = uppercaseKnownHTTPMethod(method);

    m_url = url;

    m_async = async;

    ASSERT(!m_loader);

    // Check previous state to avoid dispatching readyState event
    // when calling open several times in a row.
    if (previousState != OPENED)
        changeState(OPENED);
    else
        m_state = OPENED;
}
Exemple #5
0
static bool setMethod(ResourceRequest& request, const String& initMethod)
{
    if (!isValidHTTPToken(initMethod))
        return false;

    String method = initMethod.convertToASCIIUppercase();
    if (method == "CONNECT" || method == "TRACE" || method == "TRACK")
        return false;

    request.setHTTPMethod((method == "DELETE" || method == "GET" || method == "HEAD" || method == "OPTIONS" || method == "POST" || method == "PUT") ? method : initMethod);

    return true;
}
void AssociatedURLLoader::loadAsynchronously(const WebURLRequest& request, WebURLLoaderClient* client)
{
    ASSERT(!m_loader);
    ASSERT(!m_client);

    m_client = client;
    ASSERT(m_client);

    bool allowLoad = true;
    WebURLRequest newRequest(request);
    if (m_options.untrustedHTTP) {
        WebString method = newRequest.httpMethod();
        allowLoad = isValidHTTPToken(method) && FetchUtils::isUsefulMethod(method);
        if (allowLoad) {
            newRequest.setHTTPMethod(FetchUtils::normalizeMethod(method));
            HTTPRequestHeaderValidator validator;
            newRequest.visitHTTPHeaderFields(&validator);
            allowLoad = validator.isSafe();
        }
    }

    m_clientAdapter = ClientAdapter::create(this, m_client, m_options);

    if (allowLoad) {
        ThreadableLoaderOptions options;
        options.preflightPolicy = static_cast<PreflightPolicy>(m_options.preflightPolicy);
        options.crossOriginRequestPolicy = static_cast<CrossOriginRequestPolicy>(m_options.crossOriginRequestPolicy);

        ResourceLoaderOptions resourceLoaderOptions;
        resourceLoaderOptions.allowCredentials = m_options.allowCredentials ? AllowStoredCredentials : DoNotAllowStoredCredentials;
        resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;

        const ResourceRequest& webcoreRequest = newRequest.toResourceRequest();
        if (webcoreRequest.requestContext() == WebURLRequest::RequestContextUnspecified) {
            // FIXME: We load URLs without setting a TargetType (and therefore a request context) in several
            // places in content/ (P2PPortAllocatorSession::AllocateLegacyRelaySession, for example). Remove
            // this once those places are patched up.
            newRequest.setRequestContext(WebURLRequest::RequestContextInternal);
        }

        Document* webcoreDocument = m_frameImpl->frame()->document();
        ASSERT(webcoreDocument);
        m_loader = DocumentThreadableLoader::create(*webcoreDocument, m_clientAdapter.get(), webcoreRequest, options, resourceLoaderOptions);
    }

    if (!m_loader) {
        // FIXME: return meaningful error codes.
        m_clientAdapter->setDelayedError(ResourceError());
    }
    m_clientAdapter->enableErrorNotifications();
}
Exemple #7
0
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec)
{
    internalAbort();
    State previousState = m_state;
    m_state = UNSENT;
    m_error = false;
    m_responseTypeCode = ResponseTypeDefault;
    m_uploadComplete = false;

    // clear stuff from possible previous load
    clearResponse();
    clearRequest();

    ASSERT(m_state == UNSENT);

    if (!isValidHTTPToken(method)) {
        ec = SYNTAX_ERR;
        return;
    }

    if (!isAllowedHTTPMethod(method)) {
        ec = SECURITY_ERR;
        return;
    }

    if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectFromSource(url)) {
        // FIXME: Should this be throwing an exception?
        ec = SECURITY_ERR;
        return;
    }

    m_method = uppercaseKnownHTTPMethod(method);

    m_url = url;

    m_async = async;

    ASSERT(!m_loader);

    // Check previous state to avoid dispatching readyState event
    // when calling open several times in a row.
    if (previousState != OPENED)
        changeState(OPENED);
    else
        m_state = OPENED;
}
static bool canWriteHeader(const String& name, const String& value, FetchHeaders::Guard guard, ExceptionCode& ec)
{
    if (!isValidHTTPToken(name) || !isValidHTTPHeaderValue(value)) {
        ec = TypeError;
        return false;
    }
    if (guard == FetchHeaders::Guard::Immutable) {
        ec = TypeError;
        return false;
    }
    if (guard == FetchHeaders::Guard::Request && isForbiddenHeaderName(name))
        return false;
    if (guard == FetchHeaders::Guard::RequestNoCors && !isSimpleHeader(name, value))
        return false;
    if (guard == FetchHeaders::Guard::Response && isForbiddenResponseHeaderName(name))
        return false;
    return true;
}
void AssociatedURLLoader::loadAsynchronously(const WebURLRequest& request, WebURLLoaderClient* client)
{
    ASSERT(!m_client);

    m_client = client;
    ASSERT(m_client);

    bool allowLoad = true;
    WebURLRequest newRequest(request);
    if (m_options.untrustedHTTP) {
        WebString method = newRequest.httpMethod();
        allowLoad = isValidHTTPToken(method) && XMLHttpRequest::isAllowedHTTPMethod(method);
        if (allowLoad) {
            newRequest.setHTTPMethod(XMLHttpRequest::uppercaseKnownHTTPMethod(method));
            HTTPRequestHeaderValidator validator;
            newRequest.visitHTTPHeaderFields(&validator);
            allowLoad = validator.isSafe();
        }
    }

    m_clientAdapter = ClientAdapter::create(this, m_client, m_options);

    if (allowLoad) {
        ThreadableLoaderOptions options;
        options.sendLoadCallbacks = SendCallbacks; // Always send callbacks.
        options.sniffContent = m_options.sniffContent ? SniffContent : DoNotSniffContent;
        options.allowCredentials = m_options.allowCredentials ? AllowStoredCredentials : DoNotAllowStoredCredentials;
        options.preflightPolicy = m_options.forcePreflight ? ForcePreflight : ConsiderPreflight;
        options.crossOriginRequestPolicy = static_cast<WebCore::CrossOriginRequestPolicy>(m_options.crossOriginRequestPolicy);
        options.dataBufferingPolicy = DoNotBufferData;

        const ResourceRequest& webcoreRequest = newRequest.toResourceRequest();
        Document* webcoreDocument = m_frameImpl->frame()->document();
        m_loader = DocumentThreadableLoader::create(webcoreDocument, m_clientAdapter.get(), webcoreRequest, options);
    } else {
        // FIXME: return meaningful error codes.
        m_clientAdapter->setDelayedError(ResourceError());
    }
    m_clientAdapter->enableErrorNotifications();
}
Exemple #10
0
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec)
{
    internalAbort();
    State previousState = m_state;
    m_state = UNSENT;
    m_error = false;
    m_uploadComplete = false;

    // clear stuff from possible previous load
    clearResponse();
    clearRequest();

    ASSERT(m_state == UNSENT);

    if (!isValidHTTPToken(method)) {
        ec = SYNTAX_ERR;
        return;
    }

    if (!isAllowedHTTPMethod(method)) {
        ec = SECURITY_ERR;
        return;
    }

    // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
    bool shouldBypassMainWorldContentSecurityPolicy = false;
    if (scriptExecutionContext()->isDocument()) {
        Document* document = static_cast<Document*>(scriptExecutionContext());
        shouldBypassMainWorldContentSecurityPolicy = document->frame()->script()->shouldBypassMainWorldContentSecurityPolicy();
    }
    if (!shouldBypassMainWorldContentSecurityPolicy && !scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)) {
        // FIXME: Should this be throwing an exception?
        ec = SECURITY_ERR;
        return;
    }

    if (!async && scriptExecutionContext()->isDocument()) {
        if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) {
            logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests are disabled for this page.");
            ec = INVALID_ACCESS_ERR;
            return;
        }

        // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
        // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
        // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
        // such as file: and data: still make sense to allow.
        if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) {
            logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) requests made from the window context cannot have XMLHttpRequest.responseType set.");
            ec = INVALID_ACCESS_ERR;
            return;
        }

#if ENABLE(XHR_TIMEOUT)
        // Similarly, timeouts are disabled for synchronous requests as well.
        if (m_timeoutMilliseconds > 0) {
            logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests must not have a timeout value set.");
            ec = INVALID_ACCESS_ERR;
            return;
        }
#endif
    }

    m_method = uppercaseKnownHTTPMethod(method);

    m_url = url;

    m_async = async;

    ASSERT(!m_loader);

    // Check previous state to avoid dispatching readyState event
    // when calling open several times in a row.
    if (previousState != OPENED)
        changeState(OPENED);
    else
        m_state = OPENED;
}
Exemple #11
0
void XMLHttpRequest::open(const String& method, const URL& url, bool async, ExceptionCode& ec)
{
    if (!internalAbort())
        return;

    State previousState = m_state;
    m_state = UNSENT;
    m_error = false;
    m_sendFlag = false;
    m_uploadComplete = false;

    // clear stuff from possible previous load
    clearResponse();
    clearRequest();

    ASSERT(m_state == UNSENT);

    if (!isValidHTTPToken(method)) {
        ec = SYNTAX_ERR;
        return;
    }

    if (!isAllowedHTTPMethod(method)) {
        ec = SECURITY_ERR;
        return;
    }

    if (!async && scriptExecutionContext()->isDocument()) {
        if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) {
            logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests are disabled for this page.");
            ec = INVALID_ACCESS_ERR;
            return;
        }

        // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
        // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
        // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
        // such as file: and data: still make sense to allow.
        if (url.protocolIsInHTTPFamily() && m_responseType != ResponseType::EmptyString) {
            logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) requests made from the window context cannot have XMLHttpRequest.responseType set.");
            ec = INVALID_ACCESS_ERR;
            return;
        }

        // Similarly, timeouts are disabled for synchronous requests as well.
        if (m_timeoutMilliseconds > 0) {
            logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpRequests must not have a timeout value set.");
            ec = INVALID_ACCESS_ERR;
            return;
        }
    }

    m_method = uppercaseKnownHTTPMethod(method);

    m_url = url;
    scriptExecutionContext()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(m_url, ContentSecurityPolicy::InsecureRequestType::Load);

    m_async = async;

    ASSERT(!m_loader);

    // Check previous state to avoid dispatching readyState event
    // when calling open several times in a row.
    if (previousState != OPENED)
        changeState(OPENED);
    else
        m_state = OPENED;
}
Exemple #12
0
Request* Request::createRequestWithRequestOrString(ExecutionContext* context, Request* inputRequest, const String& inputString, const RequestInit& init, ExceptionState& exceptionState)
{
    // "1. If input is a Request object, run these substeps:"
    if (inputRequest) {
        // "1. If input's used flag is set, throw a TypeError."
        if (inputRequest->bodyUsed()) {
            exceptionState.throwTypeError("Cannot construct a Request with a Request object that has already been used.");
            return 0;
        }
        // "2. Set input's used flag."
        inputRequest->lockBody(PassBody);
    }

    // "2. Let |request| be |input|'s associated request, if |input| is a
    // Request object, and a new request otherwise."
    // "3. Set |request| to a new request whose url is |request|'s url, method
    // is |request|'s method, header list is a copy of |request|'s header list,
    // unsafe request flag is set, body is |request|'s body, client is entry
    // settings object, origin is entry settings object's origin, force Origin
    // header flag is set, same-origin data URL flag is set, referrer is client,
    // context is fetch, mode is |request|'s mode, credentials mode is
    // |request|'s credentials mode, and cache mode is |request|'s cache mode."
    FetchRequestData* request = createCopyOfFetchRequestDataForFetch(context, inputRequest ? inputRequest->request() : FetchRequestData::create());

    if (inputRequest && inputRequest->blobDataHandle() && inputRequest->isBodyConsumed()) {
        // Currently the only methods that can consume body data without
        // setting 'body passed' flag consume entire body (e.g. text()). Thus
        // we can set an empty blob to the new request instead of creating a
        // draining stream.
        // TODO(yhirano): Fix this once Request.body is introduced.
        OwnPtr<BlobData> blobData = BlobData::create();
        blobData->setContentType(inputRequest->blobDataHandle()->type());
        request->setBlobDataHandle(BlobDataHandle::create(blobData.release(), 0));
    }

    // "4. Let |fallbackMode| be null."
    // "5. Let |fallbackCredentials| be null."
    // "6. Let |fallbackCache| be null."
    // We don't use fallback values. We set these flags directly in below.

    // "7. If |input| is a string, run these substeps:"
    if (!inputRequest) {
        // "1. Let |parsedURL| be the result of parsing |input| with entry
        // settings object's API base URL."
        KURL parsedURL = context->completeURL(inputString);
        // "2. If |parsedURL| is failure, throw a TypeError."
        if (!parsedURL.isValid()) {
            exceptionState.throwTypeError("Failed to parse URL from " + inputString);
            return 0;
        }
        // "3. Set |request|'s url to |parsedURL|."
        request->setURL(parsedURL);
        // "4. Set |fallbackMode| to CORS."
        // "5. Set |fallbackCredentials| to omit."
        // "6. Set |fallbackCache| to default."
        // We don't use fallback values. We set these flags directly in below.
    }

    // "8. Let |mode| be |init|'s mode member if it is present, and
    // |fallbackMode| otherwise."
    // "9. If |mode| is non-null, set |request|'s mode to |mode|."
    if (init.mode == "same-origin") {
        request->setMode(WebURLRequest::FetchRequestModeSameOrigin);
    } else if (init.mode == "no-cors") {
        request->setMode(WebURLRequest::FetchRequestModeNoCORS);
    } else if (init.mode == "cors") {
        request->setMode(WebURLRequest::FetchRequestModeCORS);
    } else {
        if (!inputRequest)
            request->setMode(WebURLRequest::FetchRequestModeCORS);
    }

    // "10. Let |credentials| be |init|'s credentials member if it is present,
    // and |fallbackCredentials| otherwise."
    // "11. If |credentials| is non-null, set |request|'s credentials mode to
    // |credentials|.
    if (init.credentials == "omit") {
        request->setCredentials(WebURLRequest::FetchCredentialsModeOmit);
    } else if (init.credentials == "same-origin") {
        request->setCredentials(WebURLRequest::FetchCredentialsModeSameOrigin);
    } else if (init.credentials == "include") {
        request->setCredentials(WebURLRequest::FetchCredentialsModeInclude);
    } else {
        if (!inputRequest)
            request->setCredentials(WebURLRequest::FetchCredentialsModeOmit);
    }

    // FIXME: "12. Let |cache| be |init|'s cache member if it is present, and
    // |fallbackCache| otherwise."
    // FIXME: "13. If |cache| is non-null, set |request|'s cache mode to
    // |cache|."

    // "14. If |init|'s method member is present, let |method| be it and run
    // these substeps:"
    if (!init.method.isNull()) {
        // "1. If |method| is not a method or method is a forbidden method,
        // throw a TypeError."
        if (!isValidHTTPToken(init.method)) {
            exceptionState.throwTypeError("'" + init.method + "' is not a valid HTTP method.");
            return 0;
        }
        if (FetchUtils::isForbiddenMethod(init.method)) {
            exceptionState.throwTypeError("'" + init.method + "' HTTP method is unsupported.");
            return 0;
        }
        // "2. Normalize |method|."
        // "3. Set |request|'s method to |method|."
        request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method)));
    }
    // "15. Let |r| be a new Request object associated with |request|, and a new
    // Headers object."
    Request* r = Request::create(context, request);
    // "16. Let |headers| be a copy of |r|'s Headers object."
    // "17. If |init|'s headers member is present, set |headers| to |init|'s
    // headers member."
    // We don't create a copy of r's Headers object when init's headers member
    // is present.
    Headers* headers = 0;
    if (!init.headers && init.headersDictionary.isUndefinedOrNull()) {
        headers = r->headers()->clone();
    }
    // "18. Empty |r|'s request's header list."
    r->clearHeaderList();
    // "19. If |r|'s request's mode is no CORS, run these substeps:
    if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) {
        // "1. If |r|'s request's method is not a simple method, throw a
        // TypeError."
        if (!FetchUtils::isSimpleMethod(r->request()->method())) {
            exceptionState.throwTypeError("'" + r->request()->method() + "' is unsupported in no-cors mode.");
            return 0;
        }
        // "Set |r|'s Headers object's guard to |request-no-CORS|.
        r->headers()->setGuard(Headers::RequestNoCORSGuard);
    }
    // "20. Fill |r|'s Headers object with |headers|. Rethrow any exceptions."
    if (init.headers) {
        ASSERT(init.headersDictionary.isUndefinedOrNull());
        r->headers()->fillWith(init.headers.get(), exceptionState);
    } else if (!init.headersDictionary.isUndefinedOrNull()) {
        r->headers()->fillWith(init.headersDictionary, exceptionState);
    } else {
        ASSERT(headers);
        r->headers()->fillWith(headers, exceptionState);
    }
    if (exceptionState.hadException())
        return 0;

    // "21. If |init|'s body member is present, run these substeps:"
    if (init.bodyBlobHandle) {
        // "1. If request's method is `GET` or `HEAD`, throw a TypeError."
        // "2. Let |stream| and |Content-Type| be the result of extracting
        //  |init|'s body member."
        // "3. Set |r|'s request's body to |stream|."
        // "4. If |Content-Type| is non-null and |r|'s request's header list
        //  contains no header named `Content-Type`, append
        //  `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any
        //  exception."
        if (request->method() == "GET" || request->method() == "HEAD") {
            exceptionState.throwTypeError("Request with GET/HEAD method cannot have body.");
            return 0;
        }
        r->setBodyBlobHandle(init.bodyBlobHandle);
        if (!init.bodyBlobHandle->type().isEmpty() && !r->headers()->has("Content-Type", exceptionState)) {
            r->headers()->append("Content-Type", init.bodyBlobHandle->type(), exceptionState);
        }
        if (exceptionState.hadException())
            return 0;
    }
    // "22. Set |r|'s MIME type to the result of extracting a MIME type from
    // |r|'s request's header list."
    r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType());

    // "23. Return |r|."
    return r;
}
Exemple #13
0
void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, ExceptionState& exceptionState)
{
    WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.string().utf8().data(), url.elidedString().utf8().data(), async);

    if (!internalAbort())
        return;

    State previousState = m_state;
    m_state = UNSENT;
    m_error = false;
    m_uploadComplete = false;

    // clear stuff from possible previous load
    clearResponse();
    clearRequest();

    ASSERT(m_state == UNSENT);

    if (!isValidHTTPToken(method)) {
        exceptionState.throwDOMException(SyntaxError, "'" + method + "' is not a valid HTTP method.");
        return;
    }

    if (!isAllowedHTTPMethod(method)) {
        exceptionState.throwSecurityError("'" + method + "' HTTP method is unsupported.");
        return;
    }

    if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !executionContext()->contentSecurityPolicy()->allowConnectToSource(url)) {
        // We can safely expose the URL to JavaScript, as these checks happen synchronously before redirection. JavaScript receives no new information.
        exceptionState.throwSecurityError("Refused to connect to '" + url.elidedString() + "' because it violates the document's Content Security Policy.");
        return;
    }

    if (!async && executionContext()->isDocument()) {
        if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) {
            exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests are disabled for this page.");
            return;
        }

        // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
        // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
        // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
        // such as file: and data: still make sense to allow.
        if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) {
            exceptionState.throwDOMException(InvalidAccessError, "Synchronous HTTP requests from a document must not set a response type.");
            return;
        }

        // Similarly, timeouts are disabled for synchronous requests as well.
        if (m_timeoutMilliseconds > 0) {
            exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests must not set a timeout.");
            return;
        }
    }

    m_method = uppercaseKnownHTTPMethod(method);

    m_url = url;

    m_async = async;

    ASSERT(!m_loader);

    // Check previous state to avoid dispatching readyState event
    // when calling open several times in a row.
    if (previousState != OPENED)
        changeState(OPENED);
    else
        m_state = OPENED;
}
bool FetchHeaderList::isValidHeaderName(const String& name)
{
    // "A name is a case-insensitive byte sequence that matches the field-name
    // token production."
    return isValidHTTPToken(name);
}