/*
 * 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)) != ContentTypeOptionsNosniff)
        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_isNull(true)
{
}

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_isNull(false)
{
}

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();
    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);
    response.m_networkLoadMetrics = data.networkLoadMetrics;
    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)
{
    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);

    if (response.tainting() == Tainting::Basic) {
        filteredResponse.setType(Type::Basic);
        filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie);
        filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie2);
        return filteredResponse;
    }

    ASSERT(response.tainting() == Tainting::Cors);
    filteredResponse.setType(Type::Cors);

    auto accessControlExposeHeaderSet = parseAccessControlAllowList<ASCIICaseInsensitiveHash>(response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders));
    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;
}

// FIXME: Name does not make it clear this is true for HTTPS!
bool ResourceResponseBase::isHTTP() 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::XWebKitCSP
        || name == HTTPHeaderName::XWebKitCSPReportOnly
        || name == HTTPHeaderName::XXSSProtection;
}

void ResourceResponseBase::sanitizeHTTPHeaderFieldsAccordingToTainting()
{
    switch (m_tainting) {
    case ResourceResponse::Tainting::Basic:
        return;
    case ResourceResponse::Tainting::Cors: {
        HTTPHeaderMap filteredHeaders;
        for (auto& header : m_httpHeaderFields.commonHeaders()) {
            if (isSafeCrossOriginResponseHeader(header.key))
                filteredHeaders.add(header.key, WTFMove(header.value));
        }
        auto corsSafeHeaderSet = parseAccessControlAllowList<ASCIICaseInsensitiveHash>(httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders));
        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;
    }
    }
}

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;
}

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.deprecatedNetworkLoadMetrics() != b.deprecatedNetworkLoadMetrics())
        return false;
    return ResourceResponse::platformCompare(a, b);
}

}
