コード例 #1
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderTwoLines)
{
    const char data[] = "foo: bar\r\nhoge: fuga\r\nxxx";
    String failureReason;
    AtomicString name, value;

    EXPECT_EQ(10u, parseHTTPHeader(data, failureReason, name, value));
    EXPECT_TRUE(failureReason.isEmpty());
    EXPECT_EQ("foo", name.string());
    EXPECT_EQ("bar", value.string());

    EXPECT_EQ(12u, parseHTTPHeader(data + 10, failureReason, name, value));
    EXPECT_TRUE(failureReason.isEmpty());
    EXPECT_EQ("hoge", name.string());
    EXPECT_EQ("fuga", value.string());
}
コード例 #2
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderUnexpectedLFinValue)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(0u, parseHTTPHeader("foo: bar\notherdata\n", failureReason, name, value));
    EXPECT_EQ("Unexpected LF in value at bar", failureReason);
}
コード例 #3
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderNoLF)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(0u, parseHTTPHeader("foo: bar\rhoge\r\n", failureReason, name, value));
    EXPECT_EQ("LF doesn't follow CR after value at hoge\r\n", failureReason);
}
コード例 #4
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderInvalidValue)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(0u, parseHTTPHeader("foo: \xfa\r\notherdata", failureReason, name, value));
    EXPECT_EQ("Invalid UTF-8 sequence in header value", failureReason);
}
コード例 #5
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderUnexpectedCRinName)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(0u, parseHTTPHeader("foo\rotherdata\n", failureReason, name, value));
    EXPECT_EQ("Unexpected CR in name at foo", failureReason);
}
コード例 #6
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderEmpty)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(0u, parseHTTPHeader("", failureReason, name, value));
    EXPECT_EQ("Unterminated header name", failureReason);
}
コード例 #7
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderEmptyName)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(0u, parseHTTPHeader(": bar\r\notherdata", failureReason, name, value));
    EXPECT_EQ("Header name is missing", failureReason);
}
コード例 #8
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderEmptyLine)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(2u, parseHTTPHeader("\r\notherdata", failureReason, name, value));
    EXPECT_TRUE(failureReason.isEmpty());
    EXPECT_TRUE(name.isNull());
    EXPECT_TRUE(value.isNull());
}
コード例 #9
0
ファイル: HTTPParsersTest.cpp プロジェクト: dstockwell/blink
TEST(HTTPParsersTest, parseHTTPHeaderEmptyValue)
{
    String failureReason;
    AtomicString name, value;
    EXPECT_EQ(7u, parseHTTPHeader("foo: \r\notherdata", failureReason, name, value));
    EXPECT_TRUE(failureReason.isEmpty());
    EXPECT_EQ("foo", name.string());
    EXPECT_TRUE(value.isEmpty());
}
コード例 #10
0
const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* end)
{
    m_response.clearHeaderFields();

    AtomicString name;
    AtomicString value;
    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 0;
        p += consumedLength;

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

        // Sec-WebSocket-Extensions may be split. We parse and check the
        // header value every time the header appears.
        if (equalIgnoringCase("Sec-WebSocket-Extensions", name)) {
            if (!m_extensionDispatcher.processHeaderValue(value)) {
                m_failureReason = formatHandshakeFailureReason(m_extensionDispatcher.failureReason());
                return 0;
            }
        } else if (equalIgnoringCase("Sec-WebSocket-Accept", name)) {
            if (sawSecWebSocketAcceptHeaderField) {
                m_failureReason = formatHandshakeFailureReason("'Sec-WebSocket-Accept' header must not appear more than once in a response");
                return 0;
            }
            m_response.addHeaderField(name, value);
            sawSecWebSocketAcceptHeaderField = true;
        } else if (equalIgnoringCase("Sec-WebSocket-Protocol", name)) {
            if (sawSecWebSocketProtocolHeaderField) {
                m_failureReason = formatHandshakeFailureReason("'Sec-WebSocket-Protocol' header must not appear more than once in a response");
                return 0;
            }
            m_response.addHeaderField(name, value);
            sawSecWebSocketProtocolHeaderField = true;
        } else {
            m_response.addHeaderField(name, value);
        }
    }

    String extensions = m_extensionDispatcher.acceptedExtensions();
    if (!extensions.isEmpty())
        m_response.addHeaderField("Sec-WebSocket-Extensions", AtomicString(extensions));
    return p;
}
コード例 #11
0
const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* end)
{
    AtomicString 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 0;
        p += consumedLength;

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

        if (equalIgnoringCase("sec-websocket-extensions", name)) {
            if (sawSecWebSocketExtensionsHeaderField) {
                m_failureReason = "The Sec-WebSocket-Extensions header MUST NOT appear more than once in an HTTP response";
                return 0;
            }
            if (!m_extensionDispatcher.processHeaderValue(value)) {
                m_failureReason = m_extensionDispatcher.failureReason();
                return 0;
            }
            sawSecWebSocketExtensionsHeaderField = true;
        } else if (equalIgnoringCase("Sec-WebSocket-Accept", name)) {
            if (sawSecWebSocketAcceptHeaderField) {
                m_failureReason = "The Sec-WebSocket-Accept header MUST NOT appear more than once in an HTTP response";
                return 0;
            }
            m_serverHandshakeResponse.addHTTPHeaderField(name, value);
            sawSecWebSocketAcceptHeaderField = true;
        } else if (equalIgnoringCase("Sec-WebSocket-Protocol", name)) {
            if (sawSecWebSocketProtocolHeaderField) {
                m_failureReason = "The Sec-WebSocket-Protocol header MUST NOT appear more than once in an HTTP response";
                return 0;
            }
            m_serverHandshakeResponse.addHTTPHeaderField(name, value);
            sawSecWebSocketProtocolHeaderField = true;
        } else
            m_serverHandshakeResponse.addHTTPHeaderField(name, value);
    }
    return p;
}
コード例 #12
0
size_t HTTPRequest::parseHeaders(const char* data, size_t length, String& failureReason)
{
    const char* p = data;
    const char* end = data + length;
    AtomicString name;
    String value;
    for (; p < data + length; p++) {
        size_t consumedLength = parseHTTPHeader(p, end - p, failureReason, name, value);
        if (!consumedLength)
            return 0;
        p += consumedLength;
        if (name.isEmpty())
            break;
        m_headerFields.add(name, value);
    }
    return p - data;
}
コード例 #13
0
ファイル: MultipartHandle.cpp プロジェクト: PTaylour/webkit
bool MultipartHandle::parseHeadersIfPossible()
{
    size_t contentLength = m_buffer.size();

    if (!contentLength)
        return false;

    const char* content = m_buffer.data();

    // Check if we have the header closing strings.
    if (!strnstr(content, "\r\n\r\n", contentLength)) {
        // Some servers closes the headers with only \n-s.
        if (!strnstr(content, "\n\n", contentLength)) {
            // Don't have the header closing string. Wait for more data.
            return false;
        }
    }

    // Parse the HTTP headers.
    String value;
    AtomicString name;
    char* p = const_cast<char*>(content);
    const char* end = content + contentLength;
    size_t totalConsumedLength = 0;
    for (; p < end; ++p) {
        String failureReason;
        size_t consumedLength = parseHTTPHeader(p, end - p, failureReason, name, value, false);
        if (!consumedLength)
            break; // No more header to parse.

        p += consumedLength;
        totalConsumedLength += consumedLength;

        // The name should not be empty, but the value could be empty.
        if (name.isEmpty())
            break;

        m_headers.add(name, value);
    }

    m_buffer.remove(0, totalConsumedLength + 1);
    return true;
}
コード例 #14
0
ファイル: WebSocketHandshake.cpp プロジェクト: eocanha/webkit
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;
}