Skip to content

Commit

Permalink
Fixes #39
Browse files Browse the repository at this point in the history
Made some requestors.
PoolRequestor now retries.
Tweaks necessary.
  • Loading branch information
John-LittleBearLabs committed Nov 20, 2023
1 parent a9677d8 commit af17ba2
Show file tree
Hide file tree
Showing 85 changed files with 15,676 additions and 556 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ __pycache__
CMakeLists.txt.user
CMakeUserPresets.json
*.orig
.*.swp
1 change: 1 addition & 0 deletions cmake/conanfile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
abseil/20220623.1
boost/1.81.0
gtest/1.13.0
nlohmann_json/3.11.2
openssl/1.1.1t
protobuf/3.21.4
[options]
Expand Down
30 changes: 28 additions & 2 deletions cmake/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,10 @@ def electron_version(self, branch='main'):
self.up_rels['electron-main'] = toks[i]
return toks[i]


def unavailable(self):
avail = list(map(as_int, self.available()))
version_set = {}
fuzz = 114
fuzz = 59877
def check(version, version_set, s):
i = as_int(version)
by = (fuzz,0)
Expand Down Expand Up @@ -182,6 +181,25 @@ def check(version, version_set, s):
result.sort(reverse=True)
return map(lambda x: x[1:], result)

def out_of_date(self, p):
with open(f'{self.pdir}/{p}.patch') as f:
lines = f.readlines()
fl = Patcher.file_lines(lines, 'chrome/browser/flag-metadata.json')
return '+ "name": "enable-ipfs",\n' in fl

@staticmethod
def file_lines(lines: list[str], path):
start = f'diff --git a/{path} b/{path}\n'
if not start in lines:
# print('Did not find',start,'in',lines)
return []
i = lines.index(start) + 1
#print(start,'found at',i)
for j in range(i, i + 9999):
if len(lines) == j or lines[j].startswith('diff --git'):
return lines[i:j]
return []


if __name__ == '__main__':
if argv[1] == 'apply':
Expand All @@ -200,5 +218,13 @@ def check(version, version_set, s):
rels = p.release_versions(chan, os)
for rel in rels:
print(chan, os, rel)
elif argv[1] == 'old':
pr = Patcher('/mnt/big/lbl/code/chromium/src', 'git', 'Debug')
if len(argv) > 2:
for p in argv[2:]:
print(p, pr.out_of_date(p))
else:
for p in pr.available():
print(p, pr.out_of_date(p))
else:
Patcher(*argv[1:]).create_patch_file()
7 changes: 7 additions & 0 deletions cmake/setup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,11 @@ function(with_vocab target)
OpenSSL::Crypto
)
endif()
find_package(nlohmann_json)
if(nlohmann_json_FOUND)
target_link_libraries(${target}
PUBLIC
nlohmann_json::nlohmann_json
)
endif()
endfunction()
83 changes: 83 additions & 0 deletions component/block_http_request.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "block_http_request.h"

#include <services/network/public/cpp/resource_request.h>
#include <services/network/public/cpp/simple_url_loader.h>
#include <services/network/public/mojom/url_response_head.mojom.h>

using Self = ipfs::BlockHttpRequest;

namespace {
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("ipfs_gateway_request", R"(
semantics {
sender: "IPFS component"
description:
"Sends a request to an IPFS gateway."
trigger:
"Processing of an ipfs:// or ipns:// URL."
data: "None"
destination: WEBSITE
}
policy {
cookies_allowed: NO
setting: "EnableIpfs"
}
)");
}

Self::BlockHttpRequest(ipfs::HttpRequestDescription req_inf,
HttpCompleteCallback cb)
: inf_{req_inf}, callback_{cb} {}
Self::~BlockHttpRequest() noexcept {}

void Self::send(raw_ptr<network::mojom::URLLoaderFactory> loader_factory) {
auto req = std::make_unique<network::ResourceRequest>();
req->url = GURL{inf_.url};
req->priority = net::HIGHEST; // TODO
if (!inf_.accept.empty()) {
VLOG(2) << inf_.url << " has Accept header " << inf_.accept;
req->headers.SetHeader("Accept", inf_.accept);
}
using L = network::SimpleURLLoader;
loader_ = L::Create(std::move(req), kTrafficAnnotation, FROM_HERE);
loader_->SetTimeoutDuration(base::Seconds(inf_.timeout_seconds));
loader_->SetAllowHttpErrorResults(true);
auto bound = base::BindOnce(&Self::OnResponse, base::Unretained(this),
shared_from_this());
DCHECK(loader_factory);
loader_->DownloadToString(loader_factory, std::move(bound),
gw::BLOCK_RESPONSE_BUFFER_SIZE);
}
void Self::OnResponse(std::shared_ptr<Self>,
std::unique_ptr<std::string> body) {
DCHECK(loader_);
int status = loader_->NetError() ? 500 : 200;
ContextApi::HeaderAccess header_accessor = [](auto) { return std::string{}; };
auto sz = body ? body->size() : 0UL;
VLOG(1) << "Handling HTTP response body of size " << sz << " with NetErr "
<< loader_->NetError() << " for " << inf_.url;
auto const* head = loader_->ResponseInfo();
if (head) {
DCHECK(head->headers);
auto status_line = head->headers->GetStatusLine();
auto sp = status_line.find(' ');
if (sp < status_line.size()) {
VLOG(1) << "HTTP response status='" << status_line << "'.";
status = std::atoi(status_line.c_str() + sp + 1);
} else {
LOG(WARNING) << "Status line malformed.";
}
header_accessor = [head](std::string_view k) {
std::string val;
head->headers->EnumerateHeader(nullptr, k, &val);
return val;
};
} else {
LOG(WARNING) << "No response header info?";
}
if (body) {
callback_(status, *body, header_accessor);
} else {
callback_(status, "", header_accessor);
}
}
38 changes: 38 additions & 0 deletions component/block_http_request.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef IPFS_BLOCK_HTTP_REQUEST_H_
#define IPFS_BLOCK_HTTP_REQUEST_H_

#include <ipfs_client/gw/gateway_request.h>

#include <ipfs_client/context_api.h>

namespace network {
struct ResourceRequest;
class SimpleURLLoader;
} // namespace network
namespace network::mojom {
class URLLoaderFactory;
}

namespace ipfs {
class BlockHttpRequest : public std::enable_shared_from_this<BlockHttpRequest> {
// TODO ween oneself off of SimpleURLLoader
// std::array<char, gw::BLOCK_RESPONSE_BUFFER_SIZE> buffer_;
std::unique_ptr<network::SimpleURLLoader> loader_;

public:
using HttpCompleteCallback = ipfs::ContextApi::HttpCompleteCallback;
BlockHttpRequest(ipfs::HttpRequestDescription, HttpCompleteCallback);
~BlockHttpRequest() noexcept;

void send(raw_ptr<network::mojom::URLLoaderFactory>);

private:
ipfs::HttpRequestDescription const inf_;
HttpCompleteCallback callback_;

void OnResponse(std::shared_ptr<BlockHttpRequest>,
std::unique_ptr<std::string> body);
};
} // namespace ipfs

#endif // IPFS_BLOCK_HTTP_REQUEST_H_
2 changes: 1 addition & 1 deletion component/cache_requestor.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "cache_requestor.h"

#include "gateway_requests.h"
#include "chromium_ipfs_context.h"
#include "inter_request_state.h"

#include <base/timer/timer.h>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
#include "gateway_requests.h"
#include "chromium_ipfs_context.h"

#include "block_http_request.h"
#include "crypto_api.h"
#include "inter_request_state.h"
#include "ipns_cbor.h"

#include <services/network/public/cpp/simple_url_loader.h>
#include "base/strings/escape.h"
#include "net/base/mime_sniffer.h"
#include "net/base/mime_util.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "url/gurl.h"

#include <ipfs_client/dag_block.h>
#include <ipfs_client/ipfs_request.h>
#include <ipfs_client/ipns_record.h>

#include <libp2p/multi/content_identifier_codec.hpp>
#include <libp2p/peer/peer_id.hpp>

#include <base/logging.h>

using Self = ipfs::GatewayRequests;
using Self = ipfs::ChromiumIpfsContext;

constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("ipfs_gateway_request", R"(
Expand Down Expand Up @@ -207,17 +209,10 @@ bool Self::ProcessResponse(BusyGateway& gw,
auto duration = (end_time - start_time).InMillisecondsRoundedUp();
if (cid.value().content_type ==
libp2p::multi::MulticodecType::Code::LIBP2P_KEY) {
auto as_peer = libp2p::peer::PeerId::fromHash(cid.value().content_address);
if (!as_peer.has_value()) {
LOG(INFO) << cid_str
<< " has the codec of being a libp2p key, like one would "
"expect of a Peer ID, but it does not parse as a Peer ID.";
return false;
}
auto* bytes = reinterpret_cast<Byte const*>(body->data());
auto record =
ValidateIpnsRecord({bytes, body->size()}, as_peer.value(),
crypto_api::VerifySignature, ParseCborIpns);
// auto record = ValidateIpnsRecord({bytes, body->size()},
// as_peer.value(), crypto_api::VerifySignature, ParseCborIpns);
auto record = ValidateIpnsRecord({bytes, body->size()}, cid.value(), *this);
if (!record.has_value()) {
LOG(ERROR) << "IPNS record failed to validate! From: " << gw.url();
return false;
Expand Down Expand Up @@ -247,7 +242,9 @@ bool Self::ProcessResponse(BusyGateway& gw,
auto& orc = state_->orchestrator();
orc.add_node(cid_str, ipld::DagNode::fromBlock(block));
if (gw.srcreq) {
orc.build_response(gw.srcreq->dependent);
if (gw.srcreq->dependent->ready_after()) {
orc.build_response(gw.srcreq->dependent);
}
} else {
LOG(ERROR) << "This BusyGateway with response has no top-level "
"IpfsRequest associated with it "
Expand Down Expand Up @@ -291,13 +288,14 @@ std::string Self::MimeType(std::string extension,
} else {
result.clear();
}
if (net::SniffMimeType({content.data(), content.size()}, GURL{url}, result,
auto head_size = std::min(content.size(), 999'999UL);
if (net::SniffMimeType({content.data(), head_size}, GURL{url}, result,
net::ForceSniffFileUrlsForHtml::kDisabled, &result)) {
VLOG(1) << "Got " << result << " from content of " << url;
}
if (result.empty() || result == "application/octet-stream") {
// C'mon, man
net::SniffMimeTypeFromLocalData({content.data(), content.size()}, &result);
net::SniffMimeTypeFromLocalData({content.data(), head_size}, &result);
LOG(INFO) << "Falling all the way back to content type " << result;
}
return result;
Expand All @@ -319,14 +317,49 @@ void Self::RequestByCid(std::string cid,
prio, {});
sched_.IssueRequests(me);
}
void Self::SendDnsTextRequest(std::string host,
DnsTextResultsCallback res,
DnsTextCompleteCallback don) {
if (dns_reqs_.find(host) != dns_reqs_.end()) {
LOG(ERROR) << "Requested resolution of DNSLink host " << host
<< " multiple times.";
}
auto don_wrap = [don, this, host]() {
don();
LOG(INFO) << "Finished resolving " << host << " via DNSLink";
dns_reqs_.erase(host);
};
dns_reqs_[host] = std::make_unique<DnsTxtRequest>(host, res, don_wrap,
network_context_.get());
}
void Self::SendHttpRequest(HttpRequestDescription req_inf,
HttpCompleteCallback cb) const {
DCHECK(loader_factory_);
auto ptr = std::make_shared<BlockHttpRequest>(req_inf, cb);
ptr->send(loader_factory_);
}
auto Self::deserialize_cbor(ByteView bytes) const -> IpnsCborEntry {
return ParseCborIpns(bytes);
}
bool Self::verify_key_signature(SigningKeyType t,
ByteView signature,
ByteView data,
ByteView key_bytes) const {
return crypto_api::VerifySignature(static_cast<ipns::KeyType>(t), signature,
data, key_bytes);
}

Self::GatewayRequests(InterRequestState& state)
: state_{state},
Self::ChromiumIpfsContext(
InterRequestState& state,
raw_ptr<network::mojom::NetworkContext> network_context)
: network_context_{network_context},
state_{state},
sched_([this]() { return state_->gateways().GenerateList(); }) {}
Self::~GatewayRequests() {
Self::~ChromiumIpfsContext() {
LOG(WARNING) << "API dtor - are all URIs loaded?";
}

Self::GatewayUrlLoader::GatewayUrlLoader(BusyGateway&& bg)
: GatewayRequest(std::move(bg)) {}
Self::GatewayUrlLoader::~GatewayUrlLoader() noexcept {}

Loading

0 comments on commit af17ba2

Please sign in to comment.