1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Cargo.nix linguist-detectable=false
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/target
|
||||||
|
result
|
||||||
|
result-bin
|
||||||
|
*~
|
||||||
|
\#*#
|
1535
Cargo.lock
generated
Normal file
1535
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "simpler-filehost"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rocket = "0.5.0-rc.2"
|
||||||
|
rand = "0.8.5"
|
188
flake.lock
generated
Normal file
188
flake.lock
generated
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"cargo2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1655189312,
|
||||||
|
"narHash": "sha256-gpJ57OgIebUpO+7F00VltxSEy6dz2x6HeJ5BcRM8rDA=",
|
||||||
|
"owner": "cargo2nix",
|
||||||
|
"repo": "cargo2nix",
|
||||||
|
"rev": "c149357cc3d17f2849c73eb7a09d07a307cdcfe8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cargo2nix",
|
||||||
|
"repo": "cargo2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1650374568,
|
||||||
|
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1653893745,
|
||||||
|
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1659877975,
|
||||||
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1654275867,
|
||||||
|
"narHash": "sha256-pt14ZE4jVPGvfB2NynGsl34pgXfOqum5YJNpDK4+b9E=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "7a20c208aacf4964c19186dcad51f89165dc7ed0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "release-22.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667085444,
|
||||||
|
"narHash": "sha256-1SAlbifAAb+u8n52DUk6mB5oWv95o0qwRMHOMH3bS5g=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "15093c384e8a099930d966232c79359b14adcb5a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "release-22.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1665296151,
|
||||||
|
"narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "14ccaaedd95a488dd7ae142757884d8e125b3363",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"cargo2nix": "cargo2nix",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"rust-overlay": "rust-overlay_2",
|
||||||
|
"utils": "utils"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": [
|
||||||
|
"cargo2nix",
|
||||||
|
"flake-utils"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"cargo2nix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1653878966,
|
||||||
|
"narHash": "sha256-T51Gck/vrJZi1m+uTbhEFTRgZmE59sydVONadADv358=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "8526d618af012a923ca116be9603e818b502a8db",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay_2": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": "nixpkgs_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667011705,
|
||||||
|
"narHash": "sha256-ohupiBVlXCkdQpvG79akjCILZEb+7DetDVepljR0pNI=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "34d76c0a001d81a0fac342698ce7926da37b8ea5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1667077288,
|
||||||
|
"narHash": "sha256-bdC8sFNDpT0HK74u9fUkpbf1MEzVYJ+ka7NXCdgBoaA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "6ee9ebb6b1ee695d2cacc4faa053a7b9baa76817",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
51
flake.nix
Normal file
51
flake.nix
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
description = "Simpler Filehost";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = github:nixos/nixpkgs/release-22.05;
|
||||||
|
cargo2nix.url = github:cargo2nix/cargo2nix;
|
||||||
|
utils.url = github:numtide/flake-utils;
|
||||||
|
rust-overlay.url = github:oxalica/rust-overlay;
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, utils, cargo2nix, rust-overlay }:
|
||||||
|
utils.lib.eachDefaultSystem
|
||||||
|
(system:
|
||||||
|
let
|
||||||
|
overlays = [
|
||||||
|
cargo2nix.overlays.default
|
||||||
|
rust-overlay.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system overlays;
|
||||||
|
};
|
||||||
|
|
||||||
|
toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain;
|
||||||
|
|
||||||
|
rustPkgs = pkgs.rustBuilder.makePackageSet {
|
||||||
|
packageFun = import ./Cargo.nix;
|
||||||
|
rustToolchain = toolchain;
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
devShell = rustPkgs.workspaceShell {
|
||||||
|
packages = [ pkgs.rust-analyzer ];
|
||||||
|
};
|
||||||
|
|
||||||
|
packages = rec {
|
||||||
|
simpler-filehost = (rustPkgs.workspace.simpler-filehost { }).bin;
|
||||||
|
default = simpler-filehost;
|
||||||
|
image =
|
||||||
|
pkgs.dockerTools.buildImage {
|
||||||
|
name = "simpler-filehost-image";
|
||||||
|
config = {
|
||||||
|
Cmd = [ "${simpler-filehost}/bin/simpler-filehost" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
defaultPackage = packages.default;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
3
rust-toolchain
Normal file
3
rust-toolchain
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly-2022-10-29"
|
||||||
|
components = [ "rustfmt", "clippy", "rust-src" ]
|
104
src/main.rs
Normal file
104
src/main.rs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#![feature(proc_macro_hygiene, decl_macro)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rocket;
|
||||||
|
|
||||||
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
|
use rand::thread_rng;
|
||||||
|
use rocket::{form::Form, fs::NamedFile, fs::TempFile, http::Status, response::status, Config};
|
||||||
|
use std::{env, fs};
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
struct Upload<'r> {
|
||||||
|
file: TempFile<'r>,
|
||||||
|
#[field(default = "")]
|
||||||
|
key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/", data = "<upload>")]
|
||||||
|
async fn post_file(mut upload: Form<Upload<'_>>) -> status::Custom<String> {
|
||||||
|
if env_use_key() && env_key() != upload.key {
|
||||||
|
return status::Custom(
|
||||||
|
Status::BadRequest,
|
||||||
|
"key not found in the header".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(name) = upload.file.name() {
|
||||||
|
let extension = upload
|
||||||
|
.file
|
||||||
|
.content_type()
|
||||||
|
.unwrap()
|
||||||
|
.extension()
|
||||||
|
.unwrap_or("file".into());
|
||||||
|
|
||||||
|
let new_name = format!(
|
||||||
|
"{}-{}.{}",
|
||||||
|
Alphanumeric.sample_string(&mut thread_rng(), 4),
|
||||||
|
name,
|
||||||
|
extension
|
||||||
|
);
|
||||||
|
|
||||||
|
let uploaded = upload
|
||||||
|
.file
|
||||||
|
.copy_to(format!("{}/{}", env_root_dir(), new_name))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if let Err(error) = uploaded {
|
||||||
|
println!("Error while copying from temp file: {:?}", error);
|
||||||
|
return status::Custom(
|
||||||
|
Status::InternalServerError,
|
||||||
|
"Some stupid internal error occurred".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status::Custom(Status::Ok, format!("{}/{}", env_user_url(), new_name));
|
||||||
|
} else {
|
||||||
|
return status::Custom(Status::BadRequest, "File name invalid".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/<filename>", format = "text/html")]
|
||||||
|
async fn get_file(filename: String) -> Option<NamedFile> {
|
||||||
|
NamedFile::open(format!("{}/{}", env_root_dir(), filename))
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
fn index() -> String {
|
||||||
|
format!(
|
||||||
|
"Use curl to upload:\n\
|
||||||
|
curl -F file=@\"[file]\\n\" {url}\n\
|
||||||
|
If key is enabled then a header \"key\" might be required in which case it would be\n\
|
||||||
|
curl -F file=@\"[file]\" --header \"key: [key]\" {url}",
|
||||||
|
url = env_user_url()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env_root_dir() -> String {
|
||||||
|
env::var("ROOT_DIR").unwrap_or("/var/files".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env_use_key() -> bool {
|
||||||
|
env::var("USE_KEY")
|
||||||
|
.unwrap_or("false".to_string())
|
||||||
|
.parse::<bool>()
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env_key() -> String {
|
||||||
|
env::var("KEY").expect("KEY not set in the environment")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env_user_url() -> String {
|
||||||
|
let default_config = Config::default();
|
||||||
|
|
||||||
|
env::var("USER_URL").unwrap_or(format!("http://localhost:{}", default_config.port))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
|
fs::create_dir_all(env_root_dir()).unwrap();
|
||||||
|
rocket::build().mount("/", routes![post_file, get_file, index])
|
||||||
|
}
|
Reference in New Issue
Block a user