Пример #1
0
bool HTTPHeaderMap::remove(const String& name)
{
    HTTPHeaderName headerName;
    if (findHTTPHeaderName(name, headerName))
        return remove(headerName);
    return m_uncommonHeaders.remove(name);
}
Пример #2
0
static bool isForbiddenRequestHeader(const String& name)
{
    HTTPHeaderName headerName;
    if (!findHTTPHeaderName(name, headerName))
        return false;

    switch (headerName) {
    case HTTPHeaderName::AcceptCharset:
    case HTTPHeaderName::AcceptEncoding:
    case HTTPHeaderName::AccessControlRequestHeaders:
    case HTTPHeaderName::AccessControlRequestMethod:
    case HTTPHeaderName::Connection:
    case HTTPHeaderName::ContentLength:
    case HTTPHeaderName::ContentTransferEncoding:
    case HTTPHeaderName::Cookie:
    case HTTPHeaderName::Cookie2:
    case HTTPHeaderName::Date:
    case HTTPHeaderName::DNT:
    case HTTPHeaderName::Expect:
    case HTTPHeaderName::Host:
    case HTTPHeaderName::KeepAlive:
    case HTTPHeaderName::Origin:
    case HTTPHeaderName::Referer:
    case HTTPHeaderName::TE:
    case HTTPHeaderName::Trailer:
    case HTTPHeaderName::TransferEncoding:
    case HTTPHeaderName::Upgrade:
    case HTTPHeaderName::UserAgent:
    case HTTPHeaderName::Via:
        return true;

    default:
        return false;
    }
}
Пример #3
0
String HTTPHeaderMap::get(const String& name) const
{
    HTTPHeaderName headerName;
    if (!findHTTPHeaderName(name, headerName))
        return m_uncommonHeaders.get(name);
    return m_commonHeaders.get(headerName);
}
Пример #4
0
bool HTTPHeaderMap::contains(const String& name) const
{
    HTTPHeaderName headerName;
    if (findHTTPHeaderName(name, headerName))
        return contains(headerName);
    return m_uncommonHeaders.contains(name);
}
Пример #5
0
// FIXME: Optimize these routines for HTTPHeaderMap keys and/or refactor them with XMLHttpRequest code.
static bool isForbiddenHeaderName(const String& name)
{
    HTTPHeaderName headerName;
    if (findHTTPHeaderName(name, headerName)) {
        switch (headerName) {
        case HTTPHeaderName::AcceptCharset:
        case HTTPHeaderName::AcceptEncoding:
        case HTTPHeaderName::AccessControlRequestHeaders:
        case HTTPHeaderName::AccessControlRequestMethod:
        case HTTPHeaderName::Connection:
        case HTTPHeaderName::ContentLength:
        case HTTPHeaderName::Cookie:
        case HTTPHeaderName::Cookie2:
        case HTTPHeaderName::Date:
        case HTTPHeaderName::DNT:
        case HTTPHeaderName::Expect:
        case HTTPHeaderName::Host:
        case HTTPHeaderName::KeepAlive:
        case HTTPHeaderName::Origin:
        case HTTPHeaderName::Referer:
        case HTTPHeaderName::TE:
        case HTTPHeaderName::Trailer:
        case HTTPHeaderName::TransferEncoding:
        case HTTPHeaderName::Upgrade:
        case HTTPHeaderName::Via:
            return true;
        default:
            break;
        }
    }
    return name.startsWithIgnoringASCIICase(ASCIILiteral("Sec-")) || name.startsWithIgnoringASCIICase(ASCIILiteral("Proxy-"));
}
Пример #6
0
void HTTPHeaderMap::set(const String& name, const String& value)
{
    HTTPHeaderName headerName;
    if (!findHTTPHeaderName(name, headerName)) {
        m_uncommonHeaders.set(name, value);
        return;
    }
    m_commonHeaders.set(headerName, value);
}
Пример #7
0
void HTTPHeaderMap::add(const String& name, const String& value)
{
    HTTPHeaderName headerName;
    if (!findHTTPHeaderName(name, headerName)) {
        auto result = m_uncommonHeaders.add(name, value);
        if (!result.isNewEntry)
            result.iterator->value = result.iterator->value + ", " + value;
        return;
    }
    add(headerName, value);
}
Пример #8
0
void HTTPHeaderMap::set(CFStringRef name, const String& value)
{
    // Fast path: avoid constructing a temporary String in the common header case.
    if (auto* nameCharacters = CFStringGetCStringPtr(name, kCFStringEncodingASCII)) {
        unsigned length = CFStringGetLength(name);
        HTTPHeaderName headerName;
        if (findHTTPHeaderName(StringView(reinterpret_cast<const LChar*>(nameCharacters), length), headerName))
            m_commonHeaders.set(headerName, value);
        else
            m_uncommonHeaders.set(String(nameCharacters, length), value);
        return;
    }

    set(String(name), value);
}
Пример #9
0
static bool isSimpleHeader(const String& name, const String& value)
{
    HTTPHeaderName headerName;
    if (!findHTTPHeaderName(name, headerName))
        return false;
    switch (headerName) {
    case HTTPHeaderName::Accept:
    case HTTPHeaderName::AcceptLanguage:
    case HTTPHeaderName::ContentLanguage:
        return true;
    case HTTPHeaderName::ContentType: {
        String mimeType = extractMIMETypeFromMediaType(value);
        return equalLettersIgnoringASCIICase(mimeType, "application/x-www-form-urlencoded") || equalLettersIgnoringASCIICase(mimeType, "multipart/form-data") || equalLettersIgnoringASCIICase(mimeType, "text/plain");
    }
    default:
        return false;
    }
}
Пример #10
0
static bool shouldIgnoreHeaderForCacheReuse(const String& headerName)
{
    HTTPHeaderName name;
    if (!findHTTPHeaderName(headerName, name))
        return false;

    switch (name) {
    // FIXME: This list of headers that don't affect cache policy almost certainly isn't complete.
    case HTTPHeaderName::Accept:
    case HTTPHeaderName::CacheControl:
    case HTTPHeaderName::Pragma:
    case HTTPHeaderName::Purpose:
    case HTTPHeaderName::Referer:
    case HTTPHeaderName::UserAgent:
        return true;

    default:
        return false;
    }
}
Пример #11
0
const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* end)
{
    StringView name;
    String value;
    bool sawSecWebSocketExtensionsHeaderField = false;
    bool sawSecWebSocketAcceptHeaderField = false;
    bool sawSecWebSocketProtocolHeaderField = false;
    const char* p = start;
    for (; p < end; p++) {
        size_t consumedLength = parseHTTPHeader(p, end - p, m_failureReason, name, value);
        if (!consumedLength)
            return nullptr;
        p += consumedLength;

        // Stop once we consumed an empty line.
        if (name.isEmpty())
            break;

        HTTPHeaderName headerName;
        if (!findHTTPHeaderName(name, headerName)) {
            // Evidence in the wild shows that services make use of custom headers in the handshake
            m_serverHandshakeResponse.addHTTPHeaderField(name.toString(), value);
            continue;
        }

        // https://tools.ietf.org/html/rfc7230#section-3.2.4
        // "Newly defined header fields SHOULD limit their field values to US-ASCII octets."
        if ((headerName == HTTPHeaderName::SecWebSocketExtensions
            || headerName == HTTPHeaderName::SecWebSocketAccept
            || headerName == HTTPHeaderName::SecWebSocketProtocol)
            && !value.containsOnlyASCII()) {
            m_failureReason = makeString(name, " header value should only contain ASCII characters");
            return nullptr;
        }
        
        if (headerName == HTTPHeaderName::SecWebSocketExtensions) {
            if (sawSecWebSocketExtensionsHeaderField) {
                m_failureReason = ASCIILiteral("The Sec-WebSocket-Extensions header must not appear more than once in an HTTP response");
                return nullptr;
            }
            if (!m_extensionDispatcher.processHeaderValue(value)) {
                m_failureReason = m_extensionDispatcher.failureReason();
                return nullptr;
            }
            sawSecWebSocketExtensionsHeaderField = true;
        } else {
            if (headerName == HTTPHeaderName::SecWebSocketAccept) {
                if (sawSecWebSocketAcceptHeaderField) {
                    m_failureReason = ASCIILiteral("The Sec-WebSocket-Accept header must not appear more than once in an HTTP response");
                    return nullptr;
                }
                sawSecWebSocketAcceptHeaderField = true;
            } else if (headerName == HTTPHeaderName::SecWebSocketProtocol) {
                if (sawSecWebSocketProtocolHeaderField) {
                    m_failureReason = ASCIILiteral("The Sec-WebSocket-Protocol header must not appear more than once in an HTTP response");
                    return nullptr;
                }
                sawSecWebSocketProtocolHeaderField = true;
            }

            m_serverHandshakeResponse.addHTTPHeaderField(headerName, value);
        }
    }
    return p;
}