curl-fuzzer C++ reference
Loading...
Searching...
No Matches
ipfs_url.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 <string_view>
13
14namespace proto_fuzzer {
15
16namespace {
17
18// libcurl has no ipfs:// handler: curl's command-line tool rewrites those
19// schemes onto an HTTP gateway before configuring its easy handle. The runner
20// mirrors that rewrite against a fixed loopback authority; CONNECT_TO and
21// OPENSOCKET still confine the resulting HTTP GET to the in-process
22// MockServer, so no gateway process, DNS lookup, or external port is involved.
23constexpr char kIpfsGatewayBaseUrl[] = "http://127.0.1.127:8080";
24
30std::string RemoveDotSegments(std::string_view path) {
31 std::string input(path);
32 std::string output;
33 while (!input.empty()) {
34 if (input.rfind("../", 0) == 0) {
35 input.erase(0, 3);
36 } else if (input.rfind("./", 0) == 0) {
37 input.erase(0, 2);
38 } else if (input.rfind("/./", 0) == 0) {
39 input.replace(0, 3, "/");
40 } else if (input == "/.") {
41 input = "/";
42 } else if (input.rfind("/../", 0) == 0) {
43 input.replace(0, 4, "/");
44 const std::size_t slash = output.rfind('/');
45 output.erase(slash == std::string::npos ? 0 : slash);
46 } else if (input == "/..") {
47 input = "/";
48 const std::size_t slash = output.rfind('/');
49 output.erase(slash == std::string::npos ? 0 : slash);
50 } else if (input == "." || input == "..") {
51 input.clear();
52 } else {
53 const std::size_t segment_start = (input[0] == '/') ? 1 : 0;
54 const std::size_t segment_end = input.find('/', segment_start);
55 if (segment_end == std::string::npos) {
56 output += input;
57 input.clear();
58 } else {
59 output += input.substr(0, segment_end);
60 input.erase(0, segment_end);
61 }
62 }
63 }
64 return output;
65}
66
72std::string NormalizeIpfsHostPath(std::string_view host_path) {
73 const std::size_t suffix_start = host_path.find_first_of("/?#");
74 if (suffix_start == std::string_view::npos) {
75 return std::string(host_path);
76 }
77 const std::string_view identifier = host_path.substr(0, suffix_start);
78 const std::string_view suffix = host_path.substr(suffix_start);
79 const std::size_t path_end = suffix.find_first_of("?#");
80 const std::string_view path = (path_end == std::string_view::npos) ? suffix : suffix.substr(0, path_end);
81 const std::string_view query_fragment =
82 (path_end == std::string_view::npos) ? std::string_view() : suffix.substr(path_end);
83 std::string result(identifier);
84 result += RemoveDotSegments(path);
85 result += query_fragment;
86 return result;
87}
88
89} // namespace
90
99std::string BuildIpfsGatewayUrl(curl::fuzzer::proto::Scheme scheme, const std::string& host_path) {
100 const char* prefix = scheme == curl::fuzzer::proto::SCHEME_IPNS ? "ipns" : "ipfs";
101 return std::string(kIpfsGatewayBaseUrl) + "/" + prefix + "/" + NormalizeIpfsHostPath(host_path);
102}
103
104} // namespace proto_fuzzer
std::string BuildIpfsGatewayUrl(curl::fuzzer::proto::Scheme scheme, const std::string &host_path)
Build the IPFS/IPNS gateway URL for the given scheme and pinned host_path.
Definition ipfs_url.cc:99
IPFS/IPNS gateway URL construction shared by the scenario runner and its transcript-level tests.