curl-fuzzer C++ reference
Loading...
Searching...
No Matches
gopher_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 <cstdlib>
13#include <string>
14
15namespace proto_fuzzer {
16
17namespace {
18
21class ScopedEnvironmentOverride {
22 public:
23 ScopedEnvironmentOverride(const char* name, const char* value) : name_(name) {
24 const char* previous = std::getenv(name);
25 if (previous != nullptr) {
26 had_previous_ = true;
27 previous_ = previous;
28 }
29 active_ = setenv(name, value, 1) == 0;
30 }
31
32 ~ScopedEnvironmentOverride() {
33 if (!active_) {
34 return;
35 }
36 if (had_previous_) {
37 (void)setenv(name_.c_str(), previous_.c_str(), 1);
38 } else {
39 (void)unsetenv(name_.c_str());
40 }
41 }
42
43 ScopedEnvironmentOverride(const ScopedEnvironmentOverride&) = delete;
44 ScopedEnvironmentOverride& operator=(const ScopedEnvironmentOverride&) = delete;
45
46 private:
47 std::string name_;
48 std::string previous_;
49 bool had_previous_ = false;
50 bool active_ = false;
51};
52
53constexpr int kTimeoutProbeBufferBytes = 2048;
54constexpr long kTimeoutProbeMilliseconds = 5;
55
56} // namespace
57
60GopherMockServer::GopherMockServer(curl::fuzzer::proto::GopherProbeMode mode) : mode_(mode) {}
61
62GopherMockServer::~GopherMockServer() = default;
63
68std::unique_ptr<MockConnection> GopherMockServer::CreateConnection() {
69 std::unique_ptr<MockConnection> connection = MockServer::CreateConnection();
70 if (mode_ != curl::fuzzer::proto::GOPHER_PROBE_SEND_TIMEOUT) {
71 return connection;
72 }
73 if (connection == nullptr || !connection->ok()) {
74 return nullptr;
75 }
76 connection->ApplyBackpressure(kTimeoutProbeBufferBytes, 0);
77 if (!connection->FillClientSendBuffer()) {
78 return nullptr;
79 }
80 return connection;
81}
82
88void GopherMockServer::RunLoop(CURLM* multi, CURL* easy, const curl::fuzzer::proto::Scenario& scenario) {
89 if (mode_ == curl::fuzzer::proto::GOPHER_PROBE_PARTIAL_WRITE_NO_TIMEOUT) {
90 (void)curl_easy_setopt(easy, CURLOPT_TIMEOUT_MS, 0L);
91 ScopedEnvironmentOverride partial_writes("CURL_DBG_SOCK_WPARTIAL", "50");
92 MockServer::RunLoop(multi, easy, scenario);
93 return;
94 }
95 if (mode_ == curl::fuzzer::proto::GOPHER_PROBE_SEND_TIMEOUT) {
96 (void)curl_easy_setopt(easy, CURLOPT_TIMEOUT_MS, kTimeoutProbeMilliseconds);
97 }
98 MockServer::RunLoop(multi, easy, scenario);
99}
100
101} // namespace proto_fuzzer
GopherMockServer(curl::fuzzer::proto::GopherProbeMode mode)
Construct a closed Gopher probe peer.
void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
Apply the two fixed timing policies immediately before curl's first perform.
std::unique_ptr< MockConnection > CreateConnection() override
Build an ordinary socketpair, then saturate the client-to-server direction for the timeout probe befo...
void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
Seed the mock from the scenario, then drive the perform loop until curl is done or a deterministic op...
virtual std::unique_ptr< MockConnection > CreateConnection()
Construct the transport used for one HTTP exchange.
Bounded transport probes for curl's synchronous Gopher selector.