parent
598ab36b44
commit
5a992dde48
12 changed files with 202 additions and 77 deletions
|
@ -5,6 +5,8 @@ on:
|
|||
- "**/*.sh"
|
||||
- "**/*.sh.in"
|
||||
- "**/*.yml"
|
||||
- "contrib/**"
|
||||
- "oci/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
|
32
Cargo.lock
generated
32
Cargo.lock
generated
|
@ -271,9 +271,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
|||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.5.3"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210"
|
||||
checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
|
@ -354,7 +354,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
|
@ -372,9 +372,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.8"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3054fea8a20d8ff3968d5b22cc27501d2b08dc4decdb31b184323f00c5ef23bb"
|
||||
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
@ -463,7 +463,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -534,7 +534,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -909,9 +909,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.156"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
|
@ -1311,7 +1311,7 @@ checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1374,9 +1374,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.74"
|
||||
version = "2.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
|
||||
checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1438,7 +1438,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1556,7 +1556,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -1590,7 +1590,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -1825,7 +1825,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.74",
|
||||
"syn 2.0.75",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -63,7 +63,7 @@ RUN apk add --no-cache --virtual .build-deps shadow \
|
|||
&& chmod -R g+w /var/cache/nginx /etc/nginx /var/log/nginx
|
||||
|
||||
COPY --chown=nginx:root oci/rootfs/http/etc/nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY --chown=nginx:root oci/rootfs/http/usr/share/nginx/html/* /usr/share/nginx/html
|
||||
COPY --chown=nginx:root oci/rootfs/http/usr/share/nginx /usr/share/nginx
|
||||
|
||||
USER $PUID
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ if [[ $1 == "--tag-all" ]]; then
|
|||
fi
|
||||
|
||||
build_args=(
|
||||
'--pull=always'
|
||||
--file="${project_root}/oci/Containerfile.${BUILD_TYPE}"
|
||||
--label=org.opencontainers.image.title="tcpasters-${BUILD_TYPE}"
|
||||
--label=org.opencontainers.image.authors="Thorsten Schubert <tschubert@bafh.org>"
|
||||
|
|
|
@ -99,6 +99,9 @@ http {
|
|||
add_header Expect-CT "enforce, max-age=63072000" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
error_page 403 /403.html;
|
||||
error_page 404 /404.html;
|
||||
|
||||
if ($http_user_agent ~* (google|archive|bing|yahoo|yandex|teoma|trident|baidu) ) {
|
||||
return 403;
|
||||
}
|
||||
|
@ -108,65 +111,70 @@ http {
|
|||
|
||||
# $request_uri is url encoded
|
||||
if ($uri ~* "^\/([\w\d\-_.]{1,16}\.?)\/([\w\d\.]{1,16})(?:\/([^\/&?#]+))?\/?$)" {
|
||||
set $file_fragment $1;
|
||||
set $path_fragment $2;
|
||||
set $dl_fragment $3;
|
||||
rewrite "^/([^\/]*)/([^\/]{1,16})(?:/.*)?$" /$1 last;
|
||||
}
|
||||
set $file_fragment $1;
|
||||
set $path_fragment $2;
|
||||
set $dl_fragment $3;
|
||||
rewrite "^/([^\/]*)/([^\/]{1,16})(?:/.*)?$" /$1 last;
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "User-agent: *\nDisallow: /\n";
|
||||
location ~ "^/40(3|4).html$" {
|
||||
internal;
|
||||
root /usr/share/nginx/error_pages;
|
||||
add_header Content-Security-Policy "default-src 'none'; style-src-elem 'unsafe-inline'; img-src 'self'; frame-ancestors 'none'; block-all-mixed-content" always;
|
||||
}
|
||||
|
||||
}
|
||||
location = /robots.txt {
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "User-agent: *\nDisallow: /\n";
|
||||
}
|
||||
|
||||
location = / {}
|
||||
location = / {}
|
||||
|
||||
location = /index.html {}
|
||||
location = /index.html {}
|
||||
|
||||
location ~ ^/.var/.*$ {
|
||||
return 403;
|
||||
}
|
||||
location ~ ^/.var/.*$ {
|
||||
return 403;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /var/lib/pasted;
|
||||
location / {
|
||||
root /var/lib/pasted;
|
||||
|
||||
etag off;
|
||||
expires 1h;
|
||||
disable_symlinks on;
|
||||
autoindex off;
|
||||
etag off;
|
||||
expires 1h;
|
||||
disable_symlinks on;
|
||||
autoindex off;
|
||||
|
||||
default_type 'text/plain';
|
||||
default_type 'text/plain';
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
types {
|
||||
text/plain md markdown;
|
||||
text/plain css js xml;
|
||||
text/plain sh bash zsh fish;
|
||||
text/plain awk sed;
|
||||
text/plain yaml yml;
|
||||
text/plain pl py lua rb;
|
||||
text/plain nim hs;
|
||||
text/plain java kt;
|
||||
text/plain c cpp cxx h hpp hxx;
|
||||
text/plain go mod sum;
|
||||
text/plain patch txt;
|
||||
}
|
||||
include /etc/nginx/mime.types;
|
||||
types {
|
||||
text/plain md markdown;
|
||||
text/plain css js xml;
|
||||
text/plain sh bash zsh fish;
|
||||
text/plain awk sed;
|
||||
text/plain yaml yml;
|
||||
text/plain pl py lua rb;
|
||||
text/plain nim hs;
|
||||
text/plain java kt;
|
||||
text/plain c cpp cxx h hpp hxx;
|
||||
text/plain go mod sum;
|
||||
text/plain patch txt;
|
||||
}
|
||||
|
||||
set $mtype $map_mime;
|
||||
if ($mtype) {
|
||||
more_set_headers "Content-Type: $mtype";
|
||||
}
|
||||
set $mtype $map_mime;
|
||||
if ($mtype) {
|
||||
more_set_headers "Content-Type: $mtype";
|
||||
}
|
||||
|
||||
if ($path_fragment ~ '^(bin|dat)$') {
|
||||
add_header Content-Disposition "attachment; filename=$file_fragment";
|
||||
}
|
||||
if ($path_fragment ~ '^(bin|dat)$') {
|
||||
add_header Content-Disposition "attachment; filename=$file_fragment";
|
||||
}
|
||||
|
||||
if ($map_dl_fragment) {
|
||||
more_set_headers "Content-Type: application/octet-stream";
|
||||
add_header Content-Disposition "attachment; filename=$file_name";
|
||||
}
|
||||
}
|
||||
if ($map_dl_fragment) {
|
||||
more_set_headers "Content-Type: application/octet-stream";
|
||||
add_header Content-Disposition "attachment; filename=$file_name";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
50
oci/rootfs/http/usr/share/nginx/error_pages/403.html
Normal file
50
oci/rootfs/http/usr/share/nginx/error_pages/403.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>403 - Forbidden</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background-color: #f0f0f0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
color: #d9534f;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
}
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>403</h1>
|
||||
<p>Access Forbidden</p>
|
||||
<p>You don't have permission to access this resource.</p>
|
||||
<p><a href="/">Return to homepage</a></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
49
oci/rootfs/http/usr/share/nginx/error_pages/404.html
Normal file
49
oci/rootfs/http/usr/share/nginx/error_pages/404.html
Normal file
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>404 - Paste Not Found</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background-color: #f0f0f0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
color: #333;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
}
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>404</h1>
|
||||
<p>Oops! The paste you're looking for doesn't exist.</p>
|
||||
<p>Let's get you back on track. <a href="/">Return to homepage</a></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
ffi::OsStr,
|
||||
fs::{self, DirEntry},
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
@ -32,10 +31,14 @@ fn main() {
|
|||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.expect("System time anomaly");
|
||||
|
||||
let excluded: HashSet<&OsStr> = cfg.exclude.iter().map(AsRef::as_ref).collect();
|
||||
let excluded = cfg
|
||||
.exclude
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
let mut do_expire = |dir: &DirEntry| {
|
||||
let path = dir.path();
|
||||
let mut do_expire = |entry: &DirEntry| {
|
||||
let path = entry.path();
|
||||
let file = path.display();
|
||||
let mut deleted = false;
|
||||
|
||||
|
@ -44,9 +47,9 @@ fn main() {
|
|||
return Ok(deleted);
|
||||
}
|
||||
|
||||
match xattr::get(&path, &cfg.xattr_sunset) {
|
||||
match &xattr::get(&path, &cfg.xattr_sunset) {
|
||||
Ok(Some(x)) => {
|
||||
let timestamp = String::from_utf8_lossy(&x);
|
||||
let timestamp = String::from_utf8_lossy(x);
|
||||
let epoch = match timestamp.parse::<u64>() {
|
||||
Err(ref e) => {
|
||||
warn!("{file}: Unable to parse xattr value for: {e}, skipping");
|
||||
|
@ -66,7 +69,7 @@ fn main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
Err(ref e) => {
|
||||
Err(e) => {
|
||||
warn!("Error: {file} - {e}");
|
||||
}
|
||||
Ok(None) => {
|
||||
|
|
|
@ -17,7 +17,7 @@ use odht::{Config, HashTableOwned as HTO};
|
|||
use tcpaste::{
|
||||
admin::filter::{
|
||||
config::{Admin, Commands},
|
||||
csum::{Blake3, FileSum, PREFIX_LEN},
|
||||
csum::{Blake3, FileSum, LOAD_FACTOR, PREFIX_LEN},
|
||||
hex,
|
||||
},
|
||||
DynResult,
|
||||
|
@ -36,7 +36,7 @@ fn main() -> DynResult<()> {
|
|||
let serialized = fs::read(db)?;
|
||||
HTO::<Blake3>::from_raw_bytes(&serialized[..])?
|
||||
} else {
|
||||
HTO::<Blake3>::with_capacity(20, 95)
|
||||
HTO::<Blake3>::with_capacity(20, LOAD_FACTOR)
|
||||
};
|
||||
|
||||
let mut modified = Modified::No;
|
||||
|
@ -46,11 +46,13 @@ fn main() -> DynResult<()> {
|
|||
add(&mut table, buf);
|
||||
modified = Modified::Yes;
|
||||
}
|
||||
|
||||
Commands::Del { hashes } => {
|
||||
let buf = hashes.iter().filter_map(hex::string_to_byte_array);
|
||||
table = del(&table, buf);
|
||||
modified = Modified::Yes;
|
||||
}
|
||||
|
||||
Commands::File { hashlist } => {
|
||||
if let Some(path) = hashlist {
|
||||
let file = BufReader::new(File::open(path)?);
|
||||
|
@ -69,6 +71,7 @@ fn main() -> DynResult<()> {
|
|||
modified = Modified::Yes;
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Sample { samples } => {
|
||||
let hashes: Vec<_> = samples
|
||||
.iter()
|
||||
|
@ -85,14 +88,17 @@ fn main() -> DynResult<()> {
|
|||
modified = Modified::Yes;
|
||||
}
|
||||
}
|
||||
|
||||
Commands::List => {
|
||||
table.iter().for_each(|(buf, _)| {
|
||||
println!("{}", hex::byte_array_to_string(&buf));
|
||||
});
|
||||
}
|
||||
|
||||
Commands::Entries => {
|
||||
println!("{}", table.len());
|
||||
}
|
||||
|
||||
Commands::Query { hash } => {
|
||||
// At this point hash is already verified to have the proper format by clap,
|
||||
// but check anyways.
|
||||
|
@ -154,5 +160,8 @@ where
|
|||
}
|
||||
|
||||
// Return a new HashTable without the items
|
||||
HTO::<Blake3>::from_iterator(table.iter().filter(|(k, _)| !lookup.contains(&k[..])), 95)
|
||||
HTO::<Blake3>::from_iterator(
|
||||
table.iter().filter(|(k, _)| !lookup.contains(&k[..])),
|
||||
LOAD_FACTOR,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use odht::{Config, UnHashFn};
|
|||
use crate::str_from_hex_bytes;
|
||||
|
||||
pub const PREFIX_LEN: usize = BLOCK_LEN / 2;
|
||||
pub const LOAD_FACTOR: u8 = 75;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
pub struct Blake3;
|
||||
|
@ -217,8 +218,10 @@ mod tests {
|
|||
macro_rules! odht_serialize {
|
||||
($serialized:ident, $hashes:expr, $value:expr) => {
|
||||
let count = $hashes.len();
|
||||
let mut builder =
|
||||
HashTableOwned::<Blake3>::with_capacity((count as f32 * 1.25) as usize, 95);
|
||||
let mut builder = HashTableOwned::<Blake3>::with_capacity(
|
||||
(count as f32 * 1.25) as usize,
|
||||
LOAD_FACTOR,
|
||||
);
|
||||
|
||||
for hash in $hashes {
|
||||
builder.insert(
|
||||
|
|
|
@ -319,7 +319,7 @@ async fn handle_connection(cfg: &'static ServerConfig, mut client: Connection) {
|
|||
|
||||
#[must_use]
|
||||
pub fn json_response(status: bool, msg: &str, id: Option<&str>) -> Vec<u8> {
|
||||
let status = if status { "success" } else { "false" };
|
||||
let status = if status { "success" } else { "failure" };
|
||||
let json = id.map_or_else(
|
||||
|| {
|
||||
json!({
|
||||
|
|
Loading…
Reference in a new issue