Haio
0.2.X
Homebrew Asset IO/CDN
Toggle main menu visibility
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
9
namespace
{
10
11
std::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
29
Haio::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"
;
38
throw
Haio::Cdn::Bucket::Failure
(
Haio::ErrorCode::NotFound
,
"not found"
);
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
52
namespace
Haio::Cdn::Bucket
{
53
54
Blob
fetchFile
(
const
BucketConfig
& bucket, std::string path) {
55
return
readFileBlob(bucket, std::move(path));
56
}
57
58
}
bucket.hpp
Haio::Cdn::Bucket
Definition
haio_cdn.hpp:281
Haio::Cdn::Bucket::fetchFile
Blob fetchFile(const BucketConfig &bucket, std::string path)
Definition
file.cpp:54
Haio::Cdn::BucketConfig::root
std::filesystem::path root
Definition
haio_cdn.hpp:208
Haio::Cdn::BucketConfig
Definition
haio_cdn.hpp:201
Haio::Detect
Found Detect(Bytes data)
Definition
haio_registry.hpp:84
Haio::formatFromExtension
Format formatFromExtension(std::string_view path)
Definition
format.cpp:33
Haio::contentTypeFor
std::string_view contentTypeFor(Format format)
Definition
format.cpp:62
Haio::ErrorCode::NotFound
@ NotFound
Definition
haio_codec.hpp:20
Haio::ErrorCode::InvalidInput
@ InvalidInput
Definition
haio_codec.hpp:18
Haio::Blob
Definition
haio_codec.hpp:122
Haio::Cdn::Bucket::Failure
Definition
bucket.hpp:28
library
frontend
cdn
bucket
storage
file.cpp
Generated by
1.18.0