// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sky/engine/config.h"
#include "sky/engine/core/fetch/FetchUtils.h"

#include "sky/engine/platform/network/HTTPHeaderMap.h"
#include "sky/engine/platform/network/HTTPParsers.h"
#include "sky/engine/wtf/HashSet.h"
#include "sky/engine/wtf/Threading.h"
#include "sky/engine/wtf/text/AtomicString.h"
#include "sky/engine/wtf/text/WTFString.h"

namespace blink {

namespace {

class ForbiddenHeaderNames {
    WTF_MAKE_NONCOPYABLE(ForbiddenHeaderNames); WTF_MAKE_FAST_ALLOCATED;
public:
    bool has(const String& name) const
    {
        return m_fixedNames.contains(name)
            || name.startsWith(m_proxyHeaderPrefix, false)
            || name.startsWith(m_secHeaderPrefix, false);
    }

    static const ForbiddenHeaderNames* get();

private:
    ForbiddenHeaderNames();

    String m_proxyHeaderPrefix;
    String m_secHeaderPrefix;
    HashSet<String, CaseFoldingHash> m_fixedNames;
};

ForbiddenHeaderNames::ForbiddenHeaderNames()
    : m_proxyHeaderPrefix("proxy-")
    , m_secHeaderPrefix("sec-")
{
    m_fixedNames.add("accept-charset");
    m_fixedNames.add("accept-encoding");
    m_fixedNames.add("access-control-request-headers");
    m_fixedNames.add("access-control-request-method");
    m_fixedNames.add("connection");
    m_fixedNames.add("content-length");
    m_fixedNames.add("cookie");
    m_fixedNames.add("cookie2");
    m_fixedNames.add("date");
    m_fixedNames.add("dnt");
    m_fixedNames.add("expect");
    m_fixedNames.add("host");
    m_fixedNames.add("keep-alive");
    m_fixedNames.add("origin");
    m_fixedNames.add("referer");
    m_fixedNames.add("te");
    m_fixedNames.add("trailer");
    m_fixedNames.add("transfer-encoding");
    m_fixedNames.add("upgrade");
    m_fixedNames.add("user-agent");
    m_fixedNames.add("via");
}

const ForbiddenHeaderNames* ForbiddenHeaderNames::get()
{
    AtomicallyInitializedStatic(const ForbiddenHeaderNames*, instance = new ForbiddenHeaderNames);
    return instance;
}

} // namespace

bool FetchUtils::isSimpleMethod(const String& method)
{
    // http://fetch.spec.whatwg.org/#simple-method
    // "A simple method is a method that is `GET`, `HEAD`, or `POST`."
    return method == "GET" || method == "HEAD" || method == "POST";
}

bool FetchUtils::isSimpleHeader(const AtomicString& name, const AtomicString& value)
{
    // http://fetch.spec.whatwg.org/#simple-header
    // "A simple header is a header whose name is either one of `Accept`,
    // `Accept-Language`, and `Content-Language`, or whose name is
    // `Content-Type` and value, once parsed, is one of
    // `application/x-www-form-urlencoded`, `multipart/form-data`, and
    // `text/plain`."

    if (equalIgnoringCase(name, "accept")
        || equalIgnoringCase(name, "accept-language")
        || equalIgnoringCase(name, "content-language"))
        return true;

    if (equalIgnoringCase(name, "content-type")) {
        AtomicString mimeType = extractMIMETypeFromMediaType(value);
        return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded")
            || equalIgnoringCase(mimeType, "multipart/form-data")
            || equalIgnoringCase(mimeType, "text/plain");
    }

    return false;
}

bool FetchUtils::isSimpleRequest(const String& method, const HTTPHeaderMap& headerMap)
{
    if (!isSimpleMethod(method))
        return false;

    HTTPHeaderMap::const_iterator end = headerMap.end();
    for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
        // Preflight is required for MIME types that can not be sent via form
        // submission.
        if (!isSimpleHeader(it->key, it->value))
            return false;
    }

    return true;
}

bool FetchUtils::isForbiddenMethod(const String& method)
{
    // http://fetch.spec.whatwg.org/#forbidden-method
    // "A forbidden method is a method that is a byte case-insensitive match"
    //  for one of `CONNECT`, `TRACE`, and `TRACK`."
    return equalIgnoringCase(method, "TRACE")
        || equalIgnoringCase(method, "TRACK")
        || equalIgnoringCase(method, "CONNECT");
}

bool FetchUtils::isForbiddenHeaderName(const String& name)
{
    // http://fetch.spec.whatwg.org/#forbidden-header-name
    // "A forbidden header name is a header names that is one of:
    //   `Accept-Charset`, `Accept-Encoding`, `Access-Control-Request-Headers`,
    //   `Access-Control-Request-Method`, `Connection`,
    //   `Content-Length, Cookie`, `Cookie2`, `Date`, `DNT`, `Expect`, `Host`,
    //   `Keep-Alive`, `Origin`, `Referer`, `TE`, `Trailer`,
    //   `Transfer-Encoding`, `Upgrade`, `User-Agent`, `Via`
    // or starts with `Proxy-` or `Sec-` (including when it is just `Proxy-` or
    // `Sec-`)."

    return ForbiddenHeaderNames::get()->has(name);
}

bool FetchUtils::isForbiddenResponseHeaderName(const String& name)
{
    // http://fetch.spec.whatwg.org/#forbidden-response-header-name
    // "A forbidden response header name is a header name that is one of:
    // `Set-Cookie`, `Set-Cookie2`"

    return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set-cookie2");
}

bool FetchUtils::isSimpleOrForbiddenRequest(const String& method, const HTTPHeaderMap& headerMap)
{
    if (!isSimpleMethod(method))
        return false;

    HTTPHeaderMap::const_iterator end = headerMap.end();
    for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
        if (!isSimpleHeader(it->key, it->value) && !isForbiddenHeaderName(it->key))
            return false;
    }

    return true;
}

} // namespace blink
