Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
file.cpp
Go to the documentation of this file.
1#include <bucket/bucket.hpp>
2
3#include <filesystem>
4#include <fstream>
5#include <iostream>
6#include <iterator>
7#include <string_view>
8
9namespace {
10
11std::filesystem::path safeJoin(const std::filesystem::path& root, std::string_view rawPath) {
12 std::filesystem::path rel(rawPath);
13 if (rel.is_absolute()) rel = rel.relative_path();
14
15 std::filesystem::path clean;
16 for (const auto& part : rel) {
17 if (part == "." || part.empty()) continue;
18 if (part == "..") throw Haio::Cdn::Bucket::Failure(Haio::ErrorCode::InvalidInput, "path traversal is not allowed");
19 // a leading "~" means nothing to the filesystem but everything to a shell, and
20 // a name that reads as somebody's home directory has no business here
21 if (part.native().front() == '~') {
22 throw Haio::Cdn::Bucket::Failure(Haio::ErrorCode::InvalidInput, "\"~\" is not allowed in a path");
23 }
24 clean /= part;
25 }
26 return root / clean;
27}
28
29Haio::Blob readFileBlob(const Haio::Cdn::BucketConfig& bucket, std::string path) {
30 const auto fullPath = safeJoin(bucket.root, path);
31 std::ifstream in(fullPath, std::ios::binary);
32 if (!in) {
33 // the caller learns that it is not there and nothing else. where the bucket
34 // lives, and therefore what else might be near it, is the server's business:
35 // the resolved path goes to the log, which the operator can read and the
36 // caller cannot
37 std::cerr << "not found: " << fullPath.string() << "\n";
39 }
40
41 std::vector<uint8_t> data((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
42 const auto found = Haio::Detect(data);
43 // the blob carries the path that was asked for, not the one on this disk: the
44 // extension is the same either way, and nothing downstream should be able to
45 // repeat where the bucket lives even by accident
46 const auto format = found ? found.format : Haio::formatFromExtension(path);
47 return Haio::Blob{format, found.color, std::string(Haio::contentTypeFor(format)), std::move(path), std::move(data)};
48}
49
50}
51
52namespace Haio::Cdn::Bucket {
53
54Blob fetchFile(const BucketConfig& bucket, std::string path) {
55 return readFileBlob(bucket, std::move(path));
56}
57
58}
Blob fetchFile(const BucketConfig &bucket, std::string path)
Definition file.cpp:54
std::filesystem::path root
Definition haio_cdn.hpp:208
Found Detect(Bytes data)
Format formatFromExtension(std::string_view path)
Definition format.cpp:33
std::string_view contentTypeFor(Format format)
Definition format.cpp:62