Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
fetch.cpp
Go to the documentation of this file.
1#include <bucket/bucket.hpp>
2
3#include <boost/asio/use_awaitable.hpp>
4
5namespace asio = boost::asio;
6
7namespace Haio::Cdn::Bucket {
8
9/**
10 * reads one file out of an archive the bucket holds.
11 *
12 * the archive is fetched the ordinary way and then kept, so a second picture out of
13 * the same zip costs an inflate and no fetch. the same picture twice never arrives
14 * here at all: the response cache answered before the bucket was asked.
15 */
16asio::awaitable<Blob> fetchInsideZip(const BucketConfig& bucket, const ZipPath& path,
17 const SecurityConfig& security, ZipArchives& archives) {
18 const auto key = bucket.name + "/" + path.archive;
19
20 auto archive = archives.find(key);
21 if (!archive) {
22 auto blob = bucket.scheme == "file" ? fetchFile(bucket, path.archive)
23 : bucket.scheme == "s3" ? co_await fetchS3(bucket, path.archive)
24 : co_await fetchHttp(bucket, path.archive);
25
26 auto index = readZipIndex(blob.data);
27 if (!index) throw Failure(index.error().code, index.error().message);
28
29 archive = archives.keep(key, std::move(blob.data), *std::move(index));
30 }
31
32 const auto found = archive->index.entries.find(path.inside);
33 if (found == archive->index.entries.end()) {
34 // both halves came from the request, so repeating them tells the caller
35 // nothing it did not already write
36 throw Failure(ErrorCode::NotFound, "no \"" + path.inside + "\" inside " + path.archive);
37 }
38
39 auto data = readZipEntry(archive->data, found->second, security.maxUnzip);
40 if (!data) throw Failure(data.error().code, data.error().message);
41
42 const auto detected = Haio::Detect(*data);
43 const auto format = detected ? detected.format : Haio::formatFromExtension(path.inside);
44 co_return Blob{format, detected.color, std::string(Haio::contentTypeFor(format)), path.inside, *std::move(data)};
45}
46
47}
std::shared_ptr< const Archive > keep(const std::string &key, std::vector< uint8_t > data, ZipIndex index)
Definition archives.cpp:28
std::shared_ptr< const Archive > find(const std::string &key)
Definition archives.cpp:20
Result< std::vector< uint8_t > > readZipEntry(Bytes data, const ZipEntry &entry, size_t maxSize)
Definition reader.cpp:106
boost::asio::awaitable< Blob > fetchS3(const BucketConfig &bucket, std::string path)
Definition s3.cpp:130
boost::asio::awaitable< Blob > fetchHttp(const BucketConfig &bucket, std::string path)
Definition http.cpp:253
boost::asio::awaitable< Blob > fetchInsideZip(const BucketConfig &bucket, const ZipPath &path, const SecurityConfig &security, ZipArchives &archives)
Definition fetch.cpp:16
Result< ZipIndex > readZipIndex(Bytes data)
Definition reader.cpp:57
Blob fetchFile(const BucketConfig &bucket, std::string path)
Definition file.cpp:54
Found Detect(Bytes data)
Format formatFromExtension(std::string_view path)
Definition format.cpp:33
std::string_view contentTypeFor(Format format)
Definition format.cpp:62
Failure(Haio::ErrorCode why, const std::string &what)
Definition bucket.hpp:30