curl-fuzzer C++ reference
Loading...
Searching...
No Matches
http_transport_mock_server.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al.
3 *
4 * SPDX-License-Identifier: curl
5 */
6
9
11
12#include <curl/curl.h>
13
14#include <algorithm>
15#include <cstddef>
16#include <memory>
17
18namespace proto_fuzzer {
19
20namespace {
21
22constexpr char kProxyUrl[] = "http://127.0.0.1:8080";
23constexpr char kAbstractUnixSocket[] = "curl-fuzzer-http-origin";
24constexpr char kHaproxyClientIp[] = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
25
26} // namespace
27
31HttpTransportMockServer::HttpTransportMockServer(curl::fuzzer::proto::HttpTransportMode mode, bool haproxy_protocol)
32 : mode_(mode), haproxy_protocol_(haproxy_protocol && mode == curl::fuzzer::proto::HTTP_TRANSPORT_CONNECT_PROXY) {}
33
40 client_transcript_.clear();
41
42 switch (mode_) {
43 case curl::fuzzer::proto::HTTP_TRANSPORT_FORWARD_PROXY:
44 case curl::fuzzer::proto::HTTP_TRANSPORT_CONNECT_PROXY:
45 // The baseline CONNECT_TO entry belongs to direct origins. A numeric
46 // proxy avoids DNS, while OPENSOCKETFUNCTION replaces its socket with
47 // the in-process peer before any network I/O can occur.
48 (void)curl_easy_setopt(easy, CURLOPT_CONNECT_TO, nullptr);
49 (void)curl_easy_setopt(easy, CURLOPT_PROXY, kProxyUrl);
50 (void)curl_easy_setopt(easy, CURLOPT_PROXYTYPE, static_cast<long>(CURLPROXY_HTTP));
51 (void)curl_easy_setopt(easy, CURLOPT_NOPROXY, "");
52 (void)curl_easy_setopt(easy, CURLOPT_HTTPPROXYTUNNEL,
53 mode_ == curl::fuzzer::proto::HTTP_TRANSPORT_CONNECT_PROXY ? 1L : 0L);
54 // The dedicated HAProxy pressure seed uses its bounded request headers
55 // to fill the CONNECT socket before curl inserts the HAProxy filter.
56 // Other proxy scenarios retain libcurl's safer separate-header default.
57 (void)curl_easy_setopt(easy, CURLOPT_HEADEROPT, haproxy_protocol_ ? CURLHEADER_UNIFIED : CURLHEADER_SEPARATE);
58 (void)curl_easy_setopt(easy, CURLOPT_HAPROXY_CLIENT_IP, haproxy_protocol_ ? kHaproxyClientIp : nullptr);
59 (void)curl_easy_setopt(easy, CURLOPT_HAPROXYPROTOCOL, haproxy_protocol_ ? 1L : 0L);
60 break;
61
62 case curl::fuzzer::proto::HTTP_TRANSPORT_UNIX_SOCKET:
63 // Abstract namespace sockets create no filesystem entry. The callback
64 // still substitutes a preconnected socketpair, but curl constructs its
65 // production Unix peer, resolver result, and socket filter first.
66 (void)curl_easy_setopt(easy, CURLOPT_CONNECT_TO, nullptr);
67 (void)curl_easy_setopt(easy, CURLOPT_ABSTRACT_UNIX_SOCKET, kAbstractUnixSocket);
68 break;
69
70 case curl::fuzzer::proto::HTTP_TRANSPORT_DIRECT:
71 default:
72 break;
73 }
74}
75
77const std::string& HttpTransportMockServer::client_transcript() const { return client_transcript_; }
78
81std::unique_ptr<MockConnection> HttpTransportMockServer::CreateConnection() {
82 auto connection = std::make_unique<MockConnection>();
83 connection->SetIncomingDataObserver(this);
84 return connection;
85}
86
91
95void HttpTransportMockServer::ObserveIncomingData(const unsigned char* data, std::size_t size) {
96 if (data == nullptr || size == 0 || client_transcript_.size() >= kMaxTranscriptBytes) {
97 return;
98 }
99 const std::size_t remaining = kMaxTranscriptBytes - client_transcript_.size();
100 client_transcript_.append(reinterpret_cast<const char*>(data), std::min(size, remaining));
101}
102
105#if defined(PROTO_FUZZER_OBSERVE_STATE)
107 const volatile std::size_t transport_observation = client_transcript().size();
108 (void)transport_observation;
109#endif
110}
111
112} // namespace proto_fuzzer
std::unique_ptr< MockConnection > CreateConnection() override
Create one socketpair and attach the transcript observer.
bool SupportsRepeatedPollsetProbe() const override
The request-aware peer drains every bounded perform turn, so repeated zero-timeout poll probes cannot...
void ObserveState() override
Retain protocol outcomes in coverage and introspector builds.
void ObserveIncomingData(const unsigned char *data, std::size_t size) override
Retain a bounded raw transcript for strict request-shape tests.
HttpTransportMockServer(curl::fuzzer::proto::HttpTransportMode mode, bool haproxy_protocol)
Construct an idle transport peer for one policy-normalized mode.
void Install(CURL *easy) override
Install socket callbacks followed by the fixed routing options.
virtual void Install(CURL *easy)
Install the common OPENSOCKETFUNCTION / OPENSOCKETDATA / SOCKOPTFUNCTION callbacks on 'easy'.
virtual void ObserveState()
Default no-op for peers without protocol-specific observations.
Bounded HTTP proxy and Unix-domain transports for deep scenarios.