Browse Source

Fix webkitgtk compile error.

When compile webkitgtk, if has :
"collect2: fatal error: ld terminated with signal 9 [Killed]"

Please increase swap.
tianshuliang 3 years ago
parent
commit
7d22565122

+ 887 - 0
recipes-sato/webkit/webkitgtk/ResourceResponseBase.cpp

@@ -0,0 +1,887 @@
+/*
+ * Copyright (C) 2006, 2008, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ResourceResponseBase.h"
+
+#include "CacheValidation.h"
+#include "HTTPHeaderNames.h"
+#include "HTTPParsers.h"
+#include "MIMETypeRegistry.h"
+#include "ParsedContentRange.h"
+#include "ResourceResponse.h"
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/StringView.h>
+
+namespace WebCore {
+
+bool isScriptAllowedByNosniff(const ResourceResponse& response)
+{
+    if (parseContentTypeOptionsHeader(response.httpHeaderField(HTTPHeaderName::XContentTypeOptions)) != ContentTypeOptionsDisposition::Nosniff)
+        return true;
+    String mimeType = extractMIMETypeFromMediaType(response.httpHeaderField(HTTPHeaderName::ContentType));
+    return MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType);
+}
+
+ResourceResponseBase::ResourceResponseBase()
+    : m_haveParsedCacheControlHeader(false)
+    , m_haveParsedAgeHeader(false)
+    , m_haveParsedDateHeader(false)
+    , m_haveParsedExpiresHeader(false)
+    , m_haveParsedLastModifiedHeader(false)
+    , m_haveParsedContentRangeHeader(false)
+    , m_isRedirected(false)
+    , m_isRangeRequested(false)
+    , m_isNull(true)
+    , m_usedLegacyTLS(UsedLegacyTLS::No)
+    , m_tainting(Tainting::Basic)
+    , m_source(Source::Unknown)
+    , m_type(Type::Default)
+{
+}
+
+ResourceResponseBase::ResourceResponseBase(const URL& url, const String& mimeType, long long expectedLength, const String& textEncodingName)
+    : m_url(url)
+    , m_mimeType(mimeType)
+    , m_expectedContentLength(expectedLength)
+    , m_textEncodingName(textEncodingName)
+    , m_certificateInfo(CertificateInfo()) // Empty but valid for synthetic responses.
+    , m_haveParsedCacheControlHeader(false)
+    , m_haveParsedAgeHeader(false)
+    , m_haveParsedDateHeader(false)
+    , m_haveParsedExpiresHeader(false)
+    , m_haveParsedLastModifiedHeader(false)
+    , m_haveParsedContentRangeHeader(false)
+    , m_isRedirected(false)
+    , m_isRangeRequested(false)
+    , m_isNull(false)
+    , m_usedLegacyTLS(UsedLegacyTLS::No)
+    , m_tainting(Tainting::Basic)
+    , m_source(Source::Unknown)
+    , m_type(Type::Default)
+{
+}
+
+ResourceResponseBase::CrossThreadData ResourceResponseBase::crossThreadData() const
+{
+    CrossThreadData data;
+
+    data.url = url().isolatedCopy();
+    data.mimeType = mimeType().isolatedCopy();
+    data.expectedContentLength = expectedContentLength();
+    data.textEncodingName = textEncodingName().isolatedCopy();
+
+    data.httpStatusCode = httpStatusCode();
+    data.httpStatusText = httpStatusText().isolatedCopy();
+    data.httpVersion = httpVersion().isolatedCopy();
+
+    data.httpHeaderFields = httpHeaderFields().isolatedCopy();
+    if (m_networkLoadMetrics)
+        data.networkLoadMetrics = m_networkLoadMetrics->isolatedCopy();
+    data.type = m_type;
+    data.tainting = m_tainting;
+    data.isRedirected = m_isRedirected;
+    data.isRangeRequested = m_isRangeRequested;
+
+    return data;
+}
+
+ResourceResponse ResourceResponseBase::fromCrossThreadData(CrossThreadData&& data)
+{
+    ResourceResponse response;
+
+    response.setURL(data.url);
+    response.setMimeType(data.mimeType);
+    response.setExpectedContentLength(data.expectedContentLength);
+    response.setTextEncodingName(data.textEncodingName);
+
+    response.setHTTPStatusCode(data.httpStatusCode);
+    response.setHTTPStatusText(data.httpStatusText);
+    response.setHTTPVersion(data.httpVersion);
+
+    response.m_httpHeaderFields = WTFMove(data.httpHeaderFields);
+    if (data.networkLoadMetrics)
+        response.m_networkLoadMetrics = Box<NetworkLoadMetrics>::create(WTFMove(data.networkLoadMetrics.value()));
+    else
+        response.m_networkLoadMetrics = nullptr;
+    response.m_type = data.type;
+    response.m_tainting = data.tainting;
+    response.m_isRedirected = data.isRedirected;
+    response.m_isRangeRequested = data.isRangeRequested;
+
+    return response;
+}
+
+ResourceResponse ResourceResponseBase::syntheticRedirectResponse(const URL& fromURL, const URL& toURL)
+{
+    ResourceResponse redirectResponse;
+    redirectResponse.setURL(fromURL);
+    redirectResponse.setHTTPStatusCode(302);
+    redirectResponse.setHTTPVersion("HTTP/1.1"_s);
+    redirectResponse.setHTTPHeaderField(HTTPHeaderName::Location, toURL.string());
+    redirectResponse.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-store"_s);
+
+    return redirectResponse;
+}
+
+ResourceResponse ResourceResponseBase::filter(const ResourceResponse& response, PerformExposeAllHeadersCheck performCheck)
+{
+    if (response.tainting() == Tainting::Opaque) {
+        ResourceResponse opaqueResponse;
+        opaqueResponse.setTainting(Tainting::Opaque);
+        opaqueResponse.setType(Type::Opaque);
+        return opaqueResponse;
+    }
+
+    if (response.tainting() == Tainting::Opaqueredirect) {
+        ResourceResponse opaqueResponse;
+        opaqueResponse.setTainting(Tainting::Opaqueredirect);
+        opaqueResponse.setType(Type::Opaqueredirect);
+        opaqueResponse.setURL(response.url());
+        return opaqueResponse;
+    }
+
+    ResourceResponse filteredResponse = response;
+    // Let's initialize filteredResponse to remove some header fields.
+    filteredResponse.lazyInit(AllFields);
+
+    filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie);
+    filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie2);
+
+    if (response.tainting() == Tainting::Basic) {
+        filteredResponse.setType(Type::Basic);
+        return filteredResponse;
+    }
+
+    ASSERT(response.tainting() == Tainting::Cors);
+    filteredResponse.setType(Type::Cors);
+
+    auto accessControlExposeHeaderSet = parseAccessControlAllowList<ASCIICaseInsensitiveHash>(response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders)).valueOr(HashSet<String, ASCIICaseInsensitiveHash> { });
+    if (performCheck == PerformExposeAllHeadersCheck::Yes && accessControlExposeHeaderSet.contains("*"))
+        return filteredResponse;
+
+    filteredResponse.m_httpHeaderFields.uncommonHeaders().removeAllMatching([&](auto& entry) {
+        return !isCrossOriginSafeHeader(entry.key, accessControlExposeHeaderSet);
+    });
+    filteredResponse.m_httpHeaderFields.commonHeaders().removeAllMatching([&](auto& entry) {
+        return !isCrossOriginSafeHeader(entry.key, accessControlExposeHeaderSet);
+    });
+
+    return filteredResponse;
+}
+
+bool ResourceResponseBase::isInHTTPFamily() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    return m_url.protocolIsInHTTPFamily();
+}
+
+const URL& ResourceResponseBase::url() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    return m_url;
+}
+
+void ResourceResponseBase::setURL(const URL& url)
+{
+    lazyInit(CommonFieldsOnly);
+    m_isNull = false;
+
+    m_url = url;
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+const String& ResourceResponseBase::mimeType() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    return m_mimeType; 
+}
+
+void ResourceResponseBase::setMimeType(const String& mimeType)
+{
+    lazyInit(CommonFieldsOnly);
+    m_isNull = false;
+
+    // FIXME: MIME type is determined by HTTP Content-Type header. We should update the header, so that it doesn't disagree with m_mimeType.
+    m_mimeType = mimeType;
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+long long ResourceResponseBase::expectedContentLength() const 
+{
+    lazyInit(CommonFieldsOnly);
+
+    return m_expectedContentLength;
+}
+
+void ResourceResponseBase::setExpectedContentLength(long long expectedContentLength)
+{
+    lazyInit(CommonFieldsOnly);
+    m_isNull = false;
+
+    // FIXME: Content length is determined by HTTP Content-Length header. We should update the header, so that it doesn't disagree with m_expectedContentLength.
+    m_expectedContentLength = expectedContentLength; 
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+const String& ResourceResponseBase::textEncodingName() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    return m_textEncodingName;
+}
+
+void ResourceResponseBase::setTextEncodingName(const String& encodingName)
+{
+    lazyInit(CommonFieldsOnly);
+    m_isNull = false;
+
+    // FIXME: Text encoding is determined by HTTP Content-Type header. We should update the header, so that it doesn't disagree with m_textEncodingName.
+    m_textEncodingName = encodingName;
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+void ResourceResponseBase::setType(Type type)
+{
+    m_isNull = false;
+    m_type = type;
+}
+
+void ResourceResponseBase::includeCertificateInfo() const
+{
+    if (m_certificateInfo)
+        return;
+    m_certificateInfo = static_cast<const ResourceResponse*>(this)->platformCertificateInfo();
+}
+
+String ResourceResponseBase::suggestedFilename() const
+{
+    return static_cast<const ResourceResponse*>(this)->platformSuggestedFilename();
+}
+
+String ResourceResponseBase::sanitizeSuggestedFilename(const String& suggestedFilename)
+{
+    if (suggestedFilename.isEmpty())
+        return suggestedFilename;
+
+    ResourceResponse response(URL({ }, "http://example.com/"), String(), -1, String());
+    response.setHTTPStatusCode(200);
+    String escapedSuggestedFilename = String(suggestedFilename).replace('\\', "\\\\").replace('"', "\\\"");
+    String value = makeString("attachment; filename=\"", escapedSuggestedFilename, '"');
+    response.setHTTPHeaderField(HTTPHeaderName::ContentDisposition, value);
+    return response.suggestedFilename();
+}
+
+bool ResourceResponseBase::isSuccessful() const
+{
+    int code = httpStatusCode();
+    return code >= 200 && code < 300;
+}
+
+int ResourceResponseBase::httpStatusCode() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    return m_httpStatusCode;
+}
+
+void ResourceResponseBase::setHTTPStatusCode(int statusCode)
+{
+    lazyInit(CommonFieldsOnly);
+
+    m_httpStatusCode = statusCode;
+    m_isNull = false;
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+bool ResourceResponseBase::isRedirection() const
+{
+    return isRedirectionStatusCode(m_httpStatusCode);
+}
+
+const String& ResourceResponseBase::httpStatusText() const 
+{
+    lazyInit(AllFields);
+
+    return m_httpStatusText; 
+}
+
+void ResourceResponseBase::setHTTPStatusText(const String& statusText) 
+{
+    lazyInit(AllFields);
+
+    m_httpStatusText = statusText; 
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+const String& ResourceResponseBase::httpVersion() const
+{
+    lazyInit(AllFields);
+    
+    return m_httpVersion;
+}
+
+void ResourceResponseBase::setHTTPVersion(const String& versionText)
+{
+    lazyInit(AllFields);
+    
+    m_httpVersion = versionText;
+    
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+static bool isSafeRedirectionResponseHeader(HTTPHeaderName name)
+{
+    // WebCore needs to keep location and cache related headers as it does caching.
+    // We also keep CORS/ReferrerPolicy headers until CORS checks/Referrer computation are done in NetworkProcess.
+    return name == HTTPHeaderName::Location
+        || name == HTTPHeaderName::ReferrerPolicy
+        || name == HTTPHeaderName::CacheControl
+        || name == HTTPHeaderName::Date
+        || name == HTTPHeaderName::Expires
+        || name == HTTPHeaderName::ETag
+        || name == HTTPHeaderName::LastModified
+        || name == HTTPHeaderName::Age
+        || name == HTTPHeaderName::Pragma
+        || name == HTTPHeaderName::ReferrerPolicy
+        || name == HTTPHeaderName::Refresh
+        || name == HTTPHeaderName::Vary
+        || name == HTTPHeaderName::AccessControlAllowCredentials
+        || name == HTTPHeaderName::AccessControlAllowHeaders
+        || name == HTTPHeaderName::AccessControlAllowMethods
+        || name == HTTPHeaderName::AccessControlAllowOrigin
+        || name == HTTPHeaderName::AccessControlExposeHeaders
+        || name == HTTPHeaderName::AccessControlMaxAge
+        || name == HTTPHeaderName::CrossOriginResourcePolicy
+        || name == HTTPHeaderName::TimingAllowOrigin;
+}
+
+static bool isSafeCrossOriginResponseHeader(HTTPHeaderName name)
+{
+    // All known response headers used in WebProcesses.
+    return name == HTTPHeaderName::AcceptRanges
+        || name == HTTPHeaderName::AccessControlAllowCredentials
+        || name == HTTPHeaderName::AccessControlAllowHeaders
+        || name == HTTPHeaderName::AccessControlAllowMethods
+        || name == HTTPHeaderName::AccessControlAllowOrigin
+        || name == HTTPHeaderName::AccessControlExposeHeaders
+        || name == HTTPHeaderName::AccessControlMaxAge
+        || name == HTTPHeaderName::AccessControlRequestHeaders
+        || name == HTTPHeaderName::AccessControlRequestMethod
+        || name == HTTPHeaderName::Age
+        || name == HTTPHeaderName::CacheControl
+        || name == HTTPHeaderName::ContentDisposition
+        || name == HTTPHeaderName::ContentEncoding
+        || name == HTTPHeaderName::ContentLanguage
+        || name == HTTPHeaderName::ContentLength
+        || name == HTTPHeaderName::ContentRange
+        || name == HTTPHeaderName::ContentSecurityPolicy
+        || name == HTTPHeaderName::ContentSecurityPolicyReportOnly
+        || name == HTTPHeaderName::ContentType
+        || name == HTTPHeaderName::CrossOriginResourcePolicy
+        || name == HTTPHeaderName::Date
+        || name == HTTPHeaderName::ETag
+        || name == HTTPHeaderName::Expires
+        || name == HTTPHeaderName::IcyMetaInt
+        || name == HTTPHeaderName::IcyMetadata
+        || name == HTTPHeaderName::LastEventID
+        || name == HTTPHeaderName::LastModified
+        || name == HTTPHeaderName::Link
+        || name == HTTPHeaderName::Location
+        || name == HTTPHeaderName::Pragma
+        || name == HTTPHeaderName::Range
+        || name == HTTPHeaderName::ReferrerPolicy
+        || name == HTTPHeaderName::Refresh
+        || name == HTTPHeaderName::ServerTiming
+        || name == HTTPHeaderName::SourceMap
+        || name == HTTPHeaderName::XSourceMap
+        || name == HTTPHeaderName::TimingAllowOrigin
+        || name == HTTPHeaderName::Trailer
+        || name == HTTPHeaderName::Vary
+        || name == HTTPHeaderName::XContentTypeOptions
+        || name == HTTPHeaderName::XDNSPrefetchControl
+        || name == HTTPHeaderName::XFrameOptions
+        || name == HTTPHeaderName::XXSSProtection;
+}
+
+void ResourceResponseBase::sanitizeHTTPHeaderFieldsAccordingToTainting()
+{
+
+    if(m_tainting == ResourceResponse::Tainting::Basic) {
+        return;
+    }
+    else if(m_tainting == ResourceResponse::Tainting::Cors) {
+        auto corsSafeHeaderSet = parseAccessControlAllowList<ASCIICaseInsensitiveHash>(httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders)).valueOr(HashSet<String, ASCIICaseInsensitiveHash> { });
+        if (corsSafeHeaderSet.contains("*"))
+            return;
+    
+        HTTPHeaderMap filteredHeaders;
+        for (auto& header : m_httpHeaderFields.commonHeaders()) {
+            if (isSafeCrossOriginResponseHeader(header.key))
+                filteredHeaders.add(header.key, WTFMove(header.value));
+        }
+        for (auto& headerName : corsSafeHeaderSet) {
+            if (!filteredHeaders.contains(headerName)) {
+                auto value = m_httpHeaderFields.get(headerName);
+                if (!value.isNull())
+                    filteredHeaders.add(headerName, value);
+            }
+        }
+        m_httpHeaderFields = WTFMove(filteredHeaders);
+            return;
+    } else if((ResourceResponse::Tainting::Opaque ==m_tainting) ||  
+          (ResourceResponse::Tainting::Opaqueredirect == m_tainting)) {
+    	HTTPHeaderMap filteredHeaders;
+        for (auto& header : m_httpHeaderFields.commonHeaders()) {
+            if (isSafeCrossOriginResponseHeader(header.key))
+                filteredHeaders.add(header.key, WTFMove(header.value));
+        }
+        m_httpHeaderFields = WTFMove(filteredHeaders);
+        return;
+    } else {
+            return;
+    }
+#if 0
+    switch (m_tainting) {
+    case ResourceResponse::Tainting::Basic:
+        return;
+    case ResourceResponse::Tainting::Cors: {
+        auto corsSafeHeaderSet = parseAccessControlAllowList<ASCIICaseInsensitiveHash>(httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders)).valueOr(HashSet<String, ASCIICaseInsensitiveHash> { });
+        if (corsSafeHeaderSet.contains("*"))
+            return;
+
+        HTTPHeaderMap filteredHeaders;
+        for (auto& header : m_httpHeaderFields.commonHeaders()) {
+            if (isSafeCrossOriginResponseHeader(header.key))
+                filteredHeaders.add(header.key, WTFMove(header.value));
+        }
+        for (auto& headerName : corsSafeHeaderSet) {
+            if (!filteredHeaders.contains(headerName)) {
+                auto value = m_httpHeaderFields.get(headerName);
+                if (!value.isNull())
+                    filteredHeaders.add(headerName, value);
+            }
+        }
+        m_httpHeaderFields = WTFMove(filteredHeaders);
+        return;
+    }
+    case ResourceResponse::Tainting::Opaque:
+    case ResourceResponse::Tainting::Opaqueredirect: {
+        HTTPHeaderMap filteredHeaders;
+        for (auto& header : m_httpHeaderFields.commonHeaders()) {
+            if (isSafeCrossOriginResponseHeader(header.key))
+                filteredHeaders.add(header.key, WTFMove(header.value));
+        }
+        m_httpHeaderFields = WTFMove(filteredHeaders);
+        return;
+    }
+    }
+#endif
+}
+
+void ResourceResponseBase::sanitizeHTTPHeaderFields(SanitizationType type)
+{
+    lazyInit(AllFields);
+
+    m_httpHeaderFields.remove(HTTPHeaderName::SetCookie);
+    m_httpHeaderFields.remove(HTTPHeaderName::SetCookie2);
+
+    switch (type) {
+    case SanitizationType::RemoveCookies:
+        return;
+    case SanitizationType::Redirection: {
+        auto commonHeaders = WTFMove(m_httpHeaderFields.commonHeaders());
+        for (auto& header : commonHeaders) {
+            if (isSafeRedirectionResponseHeader(header.key))
+                m_httpHeaderFields.add(header.key, WTFMove(header.value));
+        }
+        m_httpHeaderFields.uncommonHeaders().clear();
+        return;
+    }
+    case SanitizationType::CrossOriginSafe:
+        sanitizeHTTPHeaderFieldsAccordingToTainting();
+    }
+}
+
+bool ResourceResponseBase::isHTTP09() const
+{
+    lazyInit(AllFields);
+
+    return m_httpVersion.startsWith("HTTP/0.9");
+}
+
+String ResourceResponseBase::httpHeaderField(const String& name) const
+{
+    lazyInit(CommonFieldsOnly);
+
+    // If we already have the header, just return it instead of consuming memory by grabing all headers.
+    String value = m_httpHeaderFields.get(name);
+    if (!value.isEmpty())        
+        return value;
+
+    lazyInit(AllFields);
+
+    return m_httpHeaderFields.get(name); 
+}
+
+String ResourceResponseBase::httpHeaderField(HTTPHeaderName name) const
+{
+    lazyInit(CommonFieldsOnly);
+
+    // If we already have the header, just return it instead of consuming memory by grabing all headers.
+    String value = m_httpHeaderFields.get(name);
+    if (!value.isEmpty())
+        return value;
+
+    lazyInit(AllFields);
+
+    return m_httpHeaderFields.get(name); 
+}
+
+void ResourceResponseBase::updateHeaderParsedState(HTTPHeaderName name)
+{
+    switch (name) {
+    case HTTPHeaderName::Age:
+        m_haveParsedAgeHeader = false;
+        break;
+
+    case HTTPHeaderName::CacheControl:
+    case HTTPHeaderName::Pragma:
+        m_haveParsedCacheControlHeader = false;
+        break;
+
+    case HTTPHeaderName::Date:
+        m_haveParsedDateHeader = false;
+        break;
+
+    case HTTPHeaderName::Expires:
+        m_haveParsedExpiresHeader = false;
+        break;
+
+    case HTTPHeaderName::LastModified:
+        m_haveParsedLastModifiedHeader = false;
+        break;
+
+    case HTTPHeaderName::ContentRange:
+        m_haveParsedContentRangeHeader = false;
+        break;
+
+    default:
+        break;
+    }
+}
+
+void ResourceResponseBase::setHTTPHeaderField(const String& name, const String& value)
+{
+    lazyInit(AllFields);
+
+    HTTPHeaderName headerName;
+    if (findHTTPHeaderName(name, headerName))
+        updateHeaderParsedState(headerName);
+
+    m_httpHeaderFields.set(name, value);
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+void ResourceResponseBase::setHTTPHeaderFields(HTTPHeaderMap&& headerFields)
+{
+    lazyInit(AllFields);
+
+    m_httpHeaderFields = WTFMove(headerFields);
+}
+
+void ResourceResponseBase::setHTTPHeaderField(HTTPHeaderName name, const String& value)
+{
+    lazyInit(AllFields);
+
+    updateHeaderParsedState(name);
+
+    m_httpHeaderFields.set(name, value);
+
+    // FIXME: Should invalidate or update platform response if present.
+}
+
+void ResourceResponseBase::addHTTPHeaderField(HTTPHeaderName name, const String& value)
+{
+    lazyInit(AllFields);
+    updateHeaderParsedState(name);
+    m_httpHeaderFields.add(name, value);
+}
+
+void ResourceResponseBase::addHTTPHeaderField(const String& name, const String& value)
+{
+    HTTPHeaderName headerName;
+    if (findHTTPHeaderName(name, headerName))
+        addHTTPHeaderField(headerName, value);
+    else {
+        lazyInit(AllFields);
+        m_httpHeaderFields.add(name, value);
+    }
+}
+
+const HTTPHeaderMap& ResourceResponseBase::httpHeaderFields() const
+{
+    lazyInit(AllFields);
+
+    return m_httpHeaderFields;
+}
+
+void ResourceResponseBase::parseCacheControlDirectives() const
+{
+    ASSERT(!m_haveParsedCacheControlHeader);
+
+    lazyInit(CommonFieldsOnly);
+
+    m_cacheControlDirectives = WebCore::parseCacheControlDirectives(m_httpHeaderFields);
+    m_haveParsedCacheControlHeader = true;
+}
+    
+bool ResourceResponseBase::cacheControlContainsNoCache() const
+{
+    if (!m_haveParsedCacheControlHeader)
+        parseCacheControlDirectives();
+    return m_cacheControlDirectives.noCache;
+}
+
+bool ResourceResponseBase::cacheControlContainsNoStore() const
+{
+    if (!m_haveParsedCacheControlHeader)
+        parseCacheControlDirectives();
+    return m_cacheControlDirectives.noStore;
+}
+
+bool ResourceResponseBase::cacheControlContainsMustRevalidate() const
+{
+    if (!m_haveParsedCacheControlHeader)
+        parseCacheControlDirectives();
+    return m_cacheControlDirectives.mustRevalidate;
+}
+    
+bool ResourceResponseBase::cacheControlContainsImmutable() const
+{
+    if (!m_haveParsedCacheControlHeader)
+        parseCacheControlDirectives();
+    return m_cacheControlDirectives.immutable;
+}
+
+bool ResourceResponseBase::hasCacheValidatorFields() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    return !m_httpHeaderFields.get(HTTPHeaderName::LastModified).isEmpty() || !m_httpHeaderFields.get(HTTPHeaderName::ETag).isEmpty();
+}
+
+Optional<Seconds> ResourceResponseBase::cacheControlMaxAge() const
+{
+    if (!m_haveParsedCacheControlHeader)
+        parseCacheControlDirectives();
+    return m_cacheControlDirectives.maxAge;
+}
+
+Optional<Seconds> ResourceResponseBase::cacheControlStaleWhileRevalidate() const
+{
+    if (!m_haveParsedCacheControlHeader)
+        parseCacheControlDirectives();
+    return m_cacheControlDirectives.staleWhileRevalidate;
+}
+
+static Optional<WallTime> parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName)
+{
+    String headerValue = headers.get(headerName);
+    if (headerValue.isEmpty())
+        return WTF::nullopt;
+    // This handles all date formats required by RFC2616:
+    // Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
+    // Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
+    // Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
+    return parseHTTPDate(headerValue);
+}
+
+Optional<WallTime> ResourceResponseBase::date() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    if (!m_haveParsedDateHeader) {
+        m_date = parseDateValueInHeader(m_httpHeaderFields, HTTPHeaderName::Date);
+        m_haveParsedDateHeader = true;
+    }
+    return m_date;
+}
+
+Optional<Seconds> ResourceResponseBase::age() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    if (!m_haveParsedAgeHeader) {
+        String headerValue = m_httpHeaderFields.get(HTTPHeaderName::Age);
+        bool ok;
+        double ageDouble = headerValue.toDouble(&ok);
+        if (ok)
+            m_age = Seconds { ageDouble };
+        m_haveParsedAgeHeader = true;
+    }
+    return m_age;
+}
+
+Optional<WallTime> ResourceResponseBase::expires() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    if (!m_haveParsedExpiresHeader) {
+        m_expires = parseDateValueInHeader(m_httpHeaderFields, HTTPHeaderName::Expires);
+        m_haveParsedExpiresHeader = true;
+    }
+    return m_expires;
+}
+
+Optional<WallTime> ResourceResponseBase::lastModified() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    if (!m_haveParsedLastModifiedHeader) {
+        m_lastModified = parseDateValueInHeader(m_httpHeaderFields, HTTPHeaderName::LastModified);
+#if PLATFORM(COCOA)
+        // CFNetwork converts malformed dates into Epoch so we need to treat Epoch as
+        // an invalid value (rdar://problem/22352838).
+        const WallTime epoch = WallTime::fromRawSeconds(0);
+        if (m_lastModified && m_lastModified.value() == epoch)
+            m_lastModified = WTF::nullopt;
+#endif
+        m_haveParsedLastModifiedHeader = true;
+    }
+    return m_lastModified;
+}
+
+static ParsedContentRange parseContentRangeInHeader(const HTTPHeaderMap& headers)
+{
+    String contentRangeValue = headers.get(HTTPHeaderName::ContentRange);
+    if (contentRangeValue.isEmpty())
+        return ParsedContentRange();
+
+    return ParsedContentRange(contentRangeValue);
+}
+
+const ParsedContentRange& ResourceResponseBase::contentRange() const
+{
+    lazyInit(CommonFieldsOnly);
+
+    if (!m_haveParsedContentRangeHeader) {
+        m_contentRange = parseContentRangeInHeader(m_httpHeaderFields);
+        m_haveParsedContentRangeHeader = true;
+    }
+
+    return m_contentRange;
+}
+
+bool ResourceResponseBase::isAttachment() const
+{
+    lazyInit(AllFields);
+
+    auto value = m_httpHeaderFields.get(HTTPHeaderName::ContentDisposition);
+    return equalLettersIgnoringASCIICase(value.left(value.find(';')).stripWhiteSpace(), "attachment");
+}
+
+bool ResourceResponseBase::isAttachmentWithFilename() const
+{
+    lazyInit(AllFields);
+
+    String contentDisposition = m_httpHeaderFields.get(HTTPHeaderName::ContentDisposition);
+    if (contentDisposition.isNull())
+        return false;
+
+    if (!equalLettersIgnoringASCIICase(contentDisposition.left(contentDisposition.find(';')).stripWhiteSpace(), "attachment"))
+        return false;
+
+    String filename = filenameFromHTTPContentDisposition(contentDisposition);
+    return !filename.isNull();
+}
+
+ResourceResponseBase::Source ResourceResponseBase::source() const
+{
+    lazyInit(AllFields);
+
+    return m_source;
+}
+
+void ResourceResponseBase::lazyInit(InitLevel initLevel) const
+{
+    const_cast<ResourceResponse*>(static_cast<const ResourceResponse*>(this))->platformLazyInit(initLevel);
+}
+
+bool ResourceResponseBase::compare(const ResourceResponse& a, const ResourceResponse& b)
+{
+    if (a.isNull() != b.isNull())
+        return false;  
+    if (a.url() != b.url())
+        return false;
+    if (a.mimeType() != b.mimeType())
+        return false;
+    if (a.expectedContentLength() != b.expectedContentLength())
+        return false;
+    if (a.textEncodingName() != b.textEncodingName())
+        return false;
+    if (a.suggestedFilename() != b.suggestedFilename())
+        return false;
+    if (a.httpStatusCode() != b.httpStatusCode())
+        return false;
+    if (a.httpStatusText() != b.httpStatusText())
+        return false;
+    if (a.httpHeaderFields() != b.httpHeaderFields())
+        return false;
+    if (a.m_networkLoadMetrics.get() != b.m_networkLoadMetrics.get()) {
+        if (!a.m_networkLoadMetrics) {
+            if (NetworkLoadMetrics() != *b.m_networkLoadMetrics.get())
+                return false;
+        } else if (!b.m_networkLoadMetrics) {
+            if (NetworkLoadMetrics() != *a.m_networkLoadMetrics.get())
+                return false;
+        } else if (*a.m_networkLoadMetrics.get() != *b.m_networkLoadMetrics.get())
+            return false;
+    }
+    return ResourceResponse::platformCompare(a, b);
+}
+
+bool ResourceResponseBase::containsInvalidHTTPHeaders() const
+{
+    for (auto& header : httpHeaderFields()) {
+        if (!isValidHTTPHeaderValue(stripLeadingAndTrailingHTTPSpaces(header.value)))
+            return true;
+    }
+    return false;
+}
+
+}

+ 17 - 0
recipes-sato/webkit/webkitgtk_2.30.2.bbappend

@@ -0,0 +1,17 @@
+SUMMARY = "WebKit web rendering engine for the GTK+ platform"
+HOMEPAGE = "https://www.webkitgtk.org/"
+BUGTRACKER = "https://bugs.webkit.org/"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI_append_riscv64 = "file://ResourceResponseBase.cpp \
+			           "
+
+do_configure_prepend_riscv64() {
+	  echo "THISDIR= ${THISDIR}/${PN}"
+	  echo "PN=${PN}"
+	  echo "PV=${PV}"
+      if [ -f "${WORKDIR}/ResourceResponseBase.cpp" -a -d "${WORKDIR}/${PN}-${PV}/Source/WebCore/platform/network/" ]; then
+	      cp -rf ${WORKDIR}/ResourceResponseBase.cpp ${WORKDIR}/${PN}-${PV}/Source/WebCore/platform/network/
+	  fi
+}