mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-13 06:04:42 +02:00
http_bitcoin was mostly used during #35182 to distinguish from http_libevent counterpart: - The http_libevent namespace was introduced around the legacy code in89c54ae4cb. - The http_bitcoin namespace was introduced in68b5d289d1and extended in subsequent commits. - The http_libevent namespace together with code it contained was removed in8c1eea0777. bitcoin_http is a better name as it is Bitcoin Core's implementation of the HTTP protocol, not HTTP protocol's implementation of bitcoin 402 payment required codes or anything like that. The namespace only remains for a few constants and a type which don't have HTTP in their names.
68 lines
2.7 KiB
C++
68 lines
2.7 KiB
C++
// Copyright (c) 2020-present The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <httpserver.h>
|
|
#include <netaddress.h>
|
|
#include <test/fuzz/FuzzedDataProvider.h>
|
|
#include <test/fuzz/fuzz.h>
|
|
#include <test/fuzz/util.h>
|
|
#include <util/signalinterrupt.h>
|
|
#include <util/strencodings.h>
|
|
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
|
|
std::string_view RequestMethodString(HTTPRequestMethod m);
|
|
|
|
FUZZ_TARGET(http_request)
|
|
{
|
|
using util::LineReader;
|
|
using namespace bitcoin_http;
|
|
|
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
|
const std::string http_buffer{fuzzed_data_provider.ConsumeRandomLengthString(4096)};
|
|
|
|
HTTPRequest http_request;
|
|
LineReader reader(http_buffer, MAX_HEADERS_SIZE);
|
|
try {
|
|
if (!http_request.LoadControlData(reader)) return;
|
|
if (!http_request.LoadHeaders(reader)) return;
|
|
if (!http_request.LoadBody(reader)) return;
|
|
} catch (const std::runtime_error&) {
|
|
return;
|
|
}
|
|
|
|
const HTTPRequestMethod request_method = http_request.GetRequestMethod();
|
|
(void)RequestMethodString(request_method);
|
|
(void)http_request.GetURI();
|
|
(void)http_request.GetHeader("Host");
|
|
std::string header = fuzzed_data_provider.ConsumeRandomLengthString(16);
|
|
(void)http_request.GetHeader(header);
|
|
(void)http_request.WriteHeader(std::string(header), fuzzed_data_provider.ConsumeRandomLengthString(16));
|
|
(void)http_request.GetHeader(header);
|
|
// Reaching here means LoadControlData/LoadHeaders/LoadBody all succeeded, so the
|
|
// parsed body must be consistent with the message framing. Before libevent was
|
|
// replaced with HTTPRequest (#35182), ReadBody() always returned an
|
|
// empty string here; LoadBody now populates the body per RFC 9112 framing, so mirror
|
|
// its branch logic to assert the body matches the framing that produced it.
|
|
const std::string body = http_request.ReadBody();
|
|
const auto transfer_encoding = http_request.GetHeader("Transfer-Encoding");
|
|
const auto content_length = http_request.GetHeader("Content-Length");
|
|
if (transfer_encoding && ToLower(*transfer_encoding) == "chunked") {
|
|
// A chunked body is the concatenation of the decoded chunks, bounded by MAX_BODY_SIZE.
|
|
assert(body.size() <= MAX_BODY_SIZE);
|
|
} else if (content_length) {
|
|
// A Content-Length body is exactly that many bytes.
|
|
const auto parsed_length{ToIntegral<uint64_t>(*content_length)};
|
|
assert(parsed_length);
|
|
assert(body.size() == *parsed_length);
|
|
} else {
|
|
// Absent both framing headers there is no body.
|
|
assert(body.empty());
|
|
}
|
|
}
|