⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlhttprequest.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    dispatchAbortEvent();    if (!m_uploadComplete) {        m_uploadComplete = true;        if (m_upload)            m_upload->dispatchAbortEvent();    }}void XMLHttpRequest::dropProtection()        {#if USE(JSC)    // The XHR object itself holds on to the responseText, and    // thus has extra cost even independent of any    // responseText or responseXML objects it has handed    // out. But it is protected from GC while loading, so this    // can't be recouped until the load is done, so only    // report the extra cost at that point.   if (JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext()))       if (DOMObject* wrapper = getCachedDOMObjectWrapper(*globalObject->globalData(), this))           JSC::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);#endif    unsetPendingActivity(this);}void XMLHttpRequest::overrideMimeType(const String& override){    m_mimeTypeOverride = override;}static void reportUnsafeUsage(ScriptExecutionContext* context, const String& message){    if (!context)        return;    // FIXME: It's not good to report the bad usage without indicating what source line it came from.    // We should pass additional parameters so we can tell the console where the mistake occurred.    context->addMessage(ConsoleDestination, JSMessageSource, ErrorMessageLevel, message, 1, String());}void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& value, ExceptionCode& ec){    if (m_state != OPENED || m_loader) {#if ENABLE(DASHBOARD_SUPPORT)        if (usesDashboardBackwardCompatibilityMode())            return;#endif        ec = INVALID_STATE_ERR;        return;    }    if (!isValidToken(name) || !isValidHeaderValue(value)) {        ec = SYNTAX_ERR;        return;    }    // A privileged script (e.g. a Dashboard widget) can set any headers.    if (!scriptExecutionContext()->securityOrigin()->canLoadLocalResources() && !isSafeRequestHeader(name)) {        reportUnsafeUsage(scriptExecutionContext(), "Refused to set unsafe header \"" + name + "\"");        return;    }    setRequestHeaderInternal(name, value);}void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const String& value){    pair<HTTPHeaderMap::iterator, bool> result = m_requestHeaders.add(name, value);     if (!result.second)        result.first->second += ", " + value;}bool XMLHttpRequest::isSafeRequestHeader(const String& name) const{    return !staticData->m_forbiddenRequestHeaders.contains(name) && !name.startsWith(staticData->m_proxyHeaderPrefix, false)        && !name.startsWith(staticData->m_secHeaderPrefix, false);}String XMLHttpRequest::getRequestHeader(const AtomicString& name) const{    return m_requestHeaders.get(name);}String XMLHttpRequest::getAllResponseHeaders(ExceptionCode& ec) const{    if (m_state < LOADING) {        ec = INVALID_STATE_ERR;        return "";    }    Vector<UChar> stringBuilder;    HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end();    for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin(); it!= end; ++it) {        // Hide Set-Cookie header fields from the XMLHttpRequest client for these reasons:        //     1) If the client did have access to the fields, then it could read HTTP-only        //        cookies; those cookies are supposed to be hidden from scripts.        //     2) There's no known harm in hiding Set-Cookie header fields entirely; we don't        //        know any widely used technique that requires access to them.        //     3) Firefox has implemented this policy.        if (isSetCookieHeader(it->first) && !scriptExecutionContext()->securityOrigin()->canLoadLocalResources())            continue;        if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(it->first))            continue;        stringBuilder.append(it->first.characters(), it->first.length());        stringBuilder.append(':');        stringBuilder.append(' ');        stringBuilder.append(it->second.characters(), it->second.length());        stringBuilder.append('\r');        stringBuilder.append('\n');    }    return String::adopt(stringBuilder);}String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionCode& ec) const{    if (m_state < LOADING) {        ec = INVALID_STATE_ERR;        return "";    }    if (!isValidToken(name))        return "";    // See comment in getAllResponseHeaders above.    if (isSetCookieHeader(name) && !scriptExecutionContext()->securityOrigin()->canLoadLocalResources()) {        reportUnsafeUsage(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");        return "";    }    if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name)) {        reportUnsafeUsage(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");        return "";    }    return m_response.httpHeaderField(name);}bool XMLHttpRequest::isOnAccessControlResponseHeaderWhitelist(const String& name) const{    return staticData->m_allowedCrossSiteResponseHeaders.contains(name);}String XMLHttpRequest::responseMIMEType() const{    String mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride);    if (mimeType.isEmpty()) {        if (m_response.isHTTP())            mimeType = extractMIMETypeFromMediaType(m_response.httpHeaderField("Content-Type"));        else            mimeType = m_response.mimeType();    }    if (mimeType.isEmpty())        mimeType = "text/xml";        return mimeType;}bool XMLHttpRequest::responseIsXML() const{    return DOMImplementation::isXMLMIMEType(responseMIMEType());}int XMLHttpRequest::status(ExceptionCode& ec) const{    if (m_response.httpStatusCode())        return m_response.httpStatusCode();    if (m_state == OPENED) {        // Firefox only raises an exception in this state; we match it.        // Note the case of local file requests, where we have no HTTP response code! Firefox never raises an exception for those, but we match HTTP case for consistency.        ec = INVALID_STATE_ERR;    }    return 0;}String XMLHttpRequest::statusText(ExceptionCode& ec) const{    // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=3547> XMLHttpRequest.statusText returns always "OK".    if (m_response.httpStatusCode())        return "OK";    if (m_state == OPENED) {        // See comments in getStatus() above.        ec = INVALID_STATE_ERR;    }    return String();}void XMLHttpRequest::didFail(const ResourceError& error){    // If we are already in an error state, for instance we called abort(), bail out early.    if (m_error)        return;    if (error.isCancellation()) {        m_exceptionCode = XMLHttpRequestException::ABORT_ERR;        abortError();        return;    }    m_exceptionCode = XMLHttpRequestException::NETWORK_ERR;    networkError();}void XMLHttpRequest::didFailRedirectCheck(){    internalAbort();    networkError();}void XMLHttpRequest::didFinishLoading(unsigned long identifier){    if (m_error)        return;    if (m_inPreflight) {        didFinishLoadingPreflight();        return;    }    if (m_state < HEADERS_RECEIVED)        changeState(HEADERS_RECEIVED);    if (m_decoder)        m_responseText += m_decoder->flush();    scriptExecutionContext()->resourceRetrievedByXMLHttpRequest(identifier, m_responseText);    scriptExecutionContext()->addMessage(InspectorControllerDestination, JSMessageSource, LogMessageLevel, "XHR finished loading: \"" + m_url + "\".", m_lastSendLineNumber, m_lastSendURL);    bool hadLoader = m_loader;    m_loader = 0;    changeState(DONE);    m_decoder = 0;    if (hadLoader)        dropProtection();}void XMLHttpRequest::didFinishLoadingPreflight(){    ASSERT(m_inPreflight);    ASSERT(!m_sameOriginRequest);    // FIXME: this can probably be moved to didReceiveResponsePreflight.    if (m_async)        handleAsynchronousPreflightResult();    if (m_loader)        unsetPendingActivity(this);}void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent){    if (!m_upload)        return;    m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);    if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {        m_uploadComplete = true;        m_upload->dispatchLoadEvent();    }}bool XMLHttpRequest::accessControlCheck(const ResourceResponse& response){    const String& accessControlOriginString = response.httpHeaderField("Access-Control-Allow-Origin");    if (accessControlOriginString == "*" && !m_includeCredentials)        return true;    RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);    if (!accessControlOrigin->isSameSchemeHostPort(scriptExecutionContext()->securityOrigin()))        return false;    if (m_includeCredentials) {        const String& accessControlCredentialsString = response.httpHeaderField("Access-Control-Allow-Credentials");        if (accessControlCredentialsString != "true")            return false;    }    return true;}void XMLHttpRequest::didReceiveResponse(const ResourceResponse& response){    if (m_inPreflight) {        didReceiveResponsePreflight(response);        return;    }    if (!m_sameOriginRequest) {        if (!accessControlCheck(response)) {            networkError();            return;        }    }    m_response = response;    m_responseEncoding = extractCharsetFromMediaType(m_mimeTypeOverride);    if (m_responseEncoding.isEmpty())        m_responseEncoding = response.textEncodingName();}void XMLHttpRequest::didReceiveResponsePreflight(const ResourceResponse& response){    ASSERT(m_inPreflight);    ASSERT(!m_sameOriginRequest);    if (!accessControlCheck(response)) {        networkError();        return;    }    OwnPtr<PreflightResultCacheItem> preflightResult(new PreflightResultCacheItem(m_includeCredentials));    if (!preflightResult->parse(response)        || !preflightResult->allowsCrossSiteMethod(m_method)        || !preflightResult->allowsCrossSiteHeaders(m_requestHeaders)) {        networkError();        return;    }    PreflightResultCache::shared().appendEntry(scriptExecutionContext()->securityOrigin()->toString(), m_url, preflightResult.release());}void XMLHttpRequest::didReceiveAuthenticationCancellation(const ResourceResponse& failureResponse){    m_response = failureResponse;}void XMLHttpRequest::didReceiveData(const char* data, int len){    if (m_inPreflight)        return;    if (m_state < HEADERS_RECEIVED)        changeState(HEADERS_RECEIVED);      if (!m_decoder) {        if (!m_responseEncoding.isEmpty())            m_decoder = TextResourceDecoder::create("text/plain", m_responseEncoding);        // allow TextResourceDecoder to look inside the m_response if it's XML or HTML        else if (responseIsXML()) {            m_decoder = TextResourceDecoder::create("application/xml");            // Don't stop on encoding errors, unlike it is done for other kinds of XML resources. This matches the behavior of previous WebKit versions, Firefox and Opera.            m_decoder->useLenientXMLDecoding();        } else if (responseMIMEType() == "text/html")            m_decoder = TextResourceDecoder::create("text/html", "UTF-8");        else            m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");    }    if (!len)        return;    if (len == -1)        len = strlen(data);    m_responseText += m_decoder->decode(data, len);    if (!m_error) {        updateAndDispatchOnProgress(len);        if (m_state != LOADING)            changeState(LOADING);        else            // Firefox calls readyStateChanged every time it receives data, 4449442            callReadyStateChangeListener();    }}void XMLHttpRequest::updateAndDispatchOnProgress(unsigned int len){    long long expectedLength = m_response.expectedContentLength();    m_receivedLength += len;    // FIXME: the spec requires that we dispatch the event according to the least    // frequent method between every 350ms (+/-200ms) and for every byte received.    dispatchProgressEvent(expectedLength);}void XMLHttpRequest::dispatchReadyStateChangeEvent(){    RefPtr<Event> evt = Event::create(eventNames().readystatechangeEvent, false, false);    if (m_onReadyStateChangeListener) {        evt->setTarget(this);        evt->setCurrentTarget(this);        m_onReadyStateChangeListener->handleEvent(evt.get(), false);    }    ExceptionCode ec = 0;    dispatchEvent(evt.release(), ec);    ASSERT(!ec);}void XMLHttpRequest::dispatchXMLHttpRequestProgressEvent(EventListener* listener, const AtomicString& type, bool lengthComputable, unsigned loaded, unsigned total){    RefPtr<XMLHttpRequestProgressEvent> evt = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total);    if (listener) {        evt->setTarget(this);        evt->setCurrentTarget(this);        listener->handleEvent(evt.get(), false);    }    ExceptionCode ec = 0;    dispatchEvent(evt.release(), ec);    ASSERT(!ec);}void XMLHttpRequest::dispatchAbortEvent(){    dispatchXMLHttpRequestProgressEvent(m_onAbortListener.get(), eventNames().abortEvent, false, 0, 0);}void XMLHttpRequest::dispatchErrorEvent(){    dispatchXMLHttpRequestProgressEvent(m_onErrorListener.get(), eventNames().errorEvent, false, 0, 0);}void XMLHttpRequest::dispatchLoadEvent(){    dispatchXMLHttpRequestProgressEvent(m_onLoadListener.get(), eventNames().loadEvent, false, 0, 0);}void XMLHttpRequest::dispatchLoadStartEvent(){    dispatchXMLHttpRequestProgressEvent(m_onLoadStartListener.get(), eventNames().loadstartEvent, false, 0, 0);}void XMLHttpRequest::dispatchProgressEvent(long long expectedLength){    dispatchXMLHttpRequestProgressEvent(m_onProgressListener.get(), eventNames().progressEvent, expectedLength && m_receivedLength <= expectedLength,                                         static_cast<unsigned>(m_receivedLength), static_cast<unsigned>(expectedLength));}bool XMLHttpRequest::canSuspend() const{    return !m_loader;}void XMLHttpRequest::stop(){    internalAbort();}void XMLHttpRequest::contextDestroyed(){    ASSERT(!m_loader);    ActiveDOMObject::contextDestroyed();}ScriptExecutionContext* XMLHttpRequest::scriptExecutionContext() const{    return ActiveDOMObject::scriptExecutionContext();}} // namespace WebCore 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -