Add in file serving!
parent
95e27073f4
commit
ade6c0ad67
|
@ -0,0 +1 @@
|
|||
DATABASE_URL=postgres://ephemeral:ephemeral@localhost/ephemeral
|
|
@ -1,2 +1,3 @@
|
|||
/target
|
||||
files.db
|
||||
files.db
|
||||
/files/
|
|
@ -37,17 +37,6 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
|
@ -314,6 +303,36 @@ dependencies = [
|
|||
"syn 1.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01e2adfd0a7a81070ed7beec0c62636458926326c16fedb77796d41e447b282d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"diesel_derives",
|
||||
"itoa",
|
||||
"libsqlite3-sys",
|
||||
"mysqlclient-sys",
|
||||
"percent-encoding 2.2.0",
|
||||
"pq-sys",
|
||||
"r2d2",
|
||||
"url 2.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_derives"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a7ab9d7967e6a1a247ea38aedf88ab808b4ac0c159576bc71866ab8f9f9250"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.44",
|
||||
"quote 1.0.21",
|
||||
"syn 1.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.5"
|
||||
|
@ -325,6 +344,35 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenvy"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9155c8f4dc55c7470ae9da3f63c6785245093b3f6aeb0f5bf2e968efbba314"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
|
@ -344,25 +392,17 @@ dependencies = [
|
|||
name = "ephemeral"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"diesel",
|
||||
"dotenvy",
|
||||
"nanoid",
|
||||
"r2d2",
|
||||
"rocket 0.5.0-rc.2",
|
||||
"rocket-multipart-form-data",
|
||||
"rocket_contrib",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
|
@ -404,6 +444,15 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
dependencies = [
|
||||
"percent-encoding 2.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent"
|
||||
version = "0.4.0"
|
||||
|
@ -578,18 +627,6 @@ name = "hashbrown"
|
|||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
|
@ -668,7 +705,7 @@ dependencies = [
|
|||
"traitobject",
|
||||
"typeable",
|
||||
"unicase",
|
||||
"url",
|
||||
"url 1.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -706,6 +743,16 @@ dependencies = [
|
|||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
|
@ -816,7 +863,6 @@ version = "0.25.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f0455f2c1bc9a7caa792907026e469c1d91761fb0ea37cbb16427c77280cf35"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
@ -975,6 +1021,25 @@ dependencies = [
|
|||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mysqlclient-sys"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f61b381528ba293005c42a409dd73d034508e273bf90481f17ec2e964a6e969b"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanoid"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.37"
|
||||
|
@ -1151,6 +1216,39 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "pq-sys"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b845d6d8ec554f972a2c5298aad68953fd64e7441e846075450b44656a016d1"
|
||||
dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.44",
|
||||
"quote 1.0.21",
|
||||
"syn 1.0.100",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.44",
|
||||
"quote 1.0.21",
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
|
@ -1200,6 +1298,17 @@ dependencies = [
|
|||
"proc-macro2 1.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
|
||||
dependencies = [
|
||||
"log 0.4.17",
|
||||
"parking_lot",
|
||||
"scheduled-thread-pool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
|
@ -1239,6 +1348,17 @@ dependencies = [
|
|||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast"
|
||||
version = "1.0.9"
|
||||
|
@ -1340,6 +1460,7 @@ dependencies = [
|
|||
"rocket_codegen 0.5.0-rc.2",
|
||||
"rocket_http 0.5.0-rc.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"state 0.5.3",
|
||||
"tempfile",
|
||||
"time 0.3.14",
|
||||
|
@ -1351,6 +1472,18 @@ dependencies = [
|
|||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket-multipart-form-data"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a4b5ad1a62bfa8a250204c41cf02c94cf9ef135a680669cdb39dbbeb8b0132e"
|
||||
dependencies = [
|
||||
"mime 0.3.16",
|
||||
"multer",
|
||||
"rocket 0.5.0-rc.2",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket_codegen"
|
||||
version = "0.4.11"
|
||||
|
@ -1439,20 +1572,6 @@ dependencies = [
|
|||
"uncased",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
"libsqlite3-sys",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.9"
|
||||
|
@ -1480,6 +1599,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scheduled-thread-pool"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
|
@ -1649,6 +1777,26 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.44",
|
||||
"quote 1.0.21",
|
||||
"syn 1.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.4"
|
||||
|
@ -1945,11 +2093,22 @@ version = "1.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"idna 0.1.5",
|
||||
"matches",
|
||||
"percent-encoding 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna 0.3.0",
|
||||
"percent-encoding 2.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -7,8 +7,12 @@ 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"
|
||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||
rocket_contrib = "0.4.11"
|
||||
rusqlite = { version = "0.28.0", features = ["bundled"] }
|
||||
diesel = { version = "2.0.0", features = ["postgres", "sqlite", "mysql", "r2d2"] }
|
||||
dotenvy = "0.15"
|
||||
serde = "1.0.145"
|
||||
serde_json = "1.0.85"
|
||||
r2d2 = "0.8.10"
|
||||
rocket-multipart-form-data = "0.10.3"
|
||||
nanoid = "0.4.0"
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# For documentation on how to configure this file,
|
||||
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||
|
||||
[print_schema]
|
||||
file = "src/schema.rs"
|
||||
|
||||
[migrations_directory]
|
||||
dir = "migrations"
|
|
@ -23,6 +23,10 @@ Returns 401 if the server requires a key to upload files.
|
|||
|
||||
GET - Returns the webpage, so be careful.
|
||||
|
||||
## File Serving - `/<file>.[ext]`
|
||||
|
||||
GET - Retrieves the file with the given ID, performing syntax highlighting and rendering a template if matching known plain-text file. (otherwise just plaintext, OR rendered by browser)
|
||||
|
||||
## File information - `/edit/<key>`
|
||||
|
||||
Returns information about the file with the corresponding key.
|
||||
|
@ -34,7 +38,7 @@ Returns information about the file with the corresponding key.
|
|||
|
||||
If the key is invalid returns a 404, same with all children API Endpoints
|
||||
|
||||
## File Deletion - `/edit/<key>/delete` (also `/delete/<key>` for backwards compatibility.)
|
||||
## File Deletion - `/edit/<key>` (also `/delete/<key>` for backwards compatibility.)
|
||||
|
||||
Accepts GET and DELETE - as long as it has the keys.
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ Database should store everything in 1 db, multiple 2 or 3, because easy.
|
|||
### files table
|
||||
|
||||
- **file** as text - contains the filename
|
||||
- **filetype** as text - contains the file extension.
|
||||
- **expiry** as int - contains unix time of when the file will be deleted - AS COMPUTED BY ENGINE MODE. (this is kept as is, never changed after initial upload)
|
||||
- **expiry_override** - _can_ contain unixtime of when the file will actaully be deleted, if it's set, this is used for overriding files.
|
||||
- **views** - counts up for each view to the file.
|
||||
|
@ -14,6 +15,7 @@ Database should store everything in 1 db, multiple 2 or 3, because easy.
|
|||
- **adminkey** - key for deletion and setting expiry_override
|
||||
- **accessed** - last time the file was accessed
|
||||
- **filesize** - size of the file, in kb or something idk
|
||||
- **ip** - IP Address of the uploader, for legal and statistics purposes!
|
||||
|
||||
### qrscan table
|
||||
|
||||
|
@ -24,3 +26,10 @@ Database should store everything in 1 db, multiple 2 or 3, because easy.
|
|||
### stats table
|
||||
|
||||
Hopefully we can move away from having a separate stats table, and use metrics generated from the files table instead.
|
||||
|
||||
## PostgreSQL installation
|
||||
|
||||
1. `psql -U <admin>`
|
||||
2. `CREATE DATABASE ephemeral;`
|
||||
3. `CREATE USER ephemeral WITH ENCRYPTED PASSWORD 'yourpass';`
|
||||
4. `GRANT ALL PRIVILEGES ON DATABASE ephemeral TO ephemeral;`
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
|
@ -0,0 +1,36 @@
|
|||
-- This file was automatically created by Diesel to setup helper functions
|
||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||
-- changes will be added to existing projects as new migrations.
|
||||
|
||||
|
||||
|
||||
|
||||
-- Sets up a trigger for the given table to automatically set a column called
|
||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||
-- in the modified columns)
|
||||
--
|
||||
-- # Example
|
||||
--
|
||||
-- ```sql
|
||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||
--
|
||||
-- SELECT diesel_manage_updated_at('users');
|
||||
-- ```
|
||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||
BEGIN
|
||||
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF (
|
||||
NEW IS DISTINCT FROM OLD AND
|
||||
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||
) THEN
|
||||
NEW.updated_at := current_timestamp;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
|
@ -0,0 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE files;
|
|
@ -0,0 +1,13 @@
|
|||
-- Your SQL goes here
|
||||
CREATE TABLE files (
|
||||
file TEXT PRIMARY KEY,
|
||||
filetype TEXT,
|
||||
expiry INT NOT NULL,
|
||||
expiry_override INT,
|
||||
views INT NOT NULL,
|
||||
is_deleted INT NOT NULL, -- Treated as a bool
|
||||
adminkey TEXT NOT NULL,
|
||||
accessed INT NOT NULL,
|
||||
filesize INT NOT NULL,
|
||||
ip TEXT NOT NULL -- IP Addr that uploaded the file.
|
||||
);
|
28
src/db.rs
28
src/db.rs
|
@ -1,28 +1,2 @@
|
|||
// Ephemeral Database Library
|
||||
// only for DB Stuff, should probably change this to SQLite or change libraries or something hey
|
||||
|
||||
pub fn create_files_db() {
|
||||
// Initalise DB (this is bad, it'll crash entire program if db is bork'd)
|
||||
let db_connection = rusqlite::Connection::open("files.db").unwrap();
|
||||
|
||||
// Create Table if it doesn't already exist.
|
||||
db_connection.execute(
|
||||
"create table if not exists files (
|
||||
file text primary key,
|
||||
expiry int,
|
||||
expiry_override int,
|
||||
views int,
|
||||
isDeleted BOOLEAN NOT NULL CHECK (
|
||||
isDeleted IN (0, 1)
|
||||
),
|
||||
adminkey text,
|
||||
accessed int,
|
||||
filesize int
|
||||
);",
|
||||
rusqlite::NO_PARAMS,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// using Diesel.rs for Postgres, SQLite and MySQL! (Postgres is primary focus)
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// 'Logic' of the web server
|
||||
use std::borrow::Cow;
|
||||
use std::fs::File;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use nanoid::nanoid;
|
||||
|
||||
// Generate a random name for the uploaded file.
|
||||
|
||||
pub struct FileName<'a>(Cow<'a, str>);
|
||||
|
||||
impl FileName<'_> {
|
||||
// Uses https://github.com/nikolay-govorov/nanoid to generate a 6 (default) character long filename.
|
||||
// Uses the characters A-Z, a-z, 0-9, and _- (VERY urlsafe :) )
|
||||
// Code shamelessly stolen from https://rocket.rs/v0.5-rc/guide/pastebin-tutorial
|
||||
pub async fn generate_filename(size: usize) -> FileName<'static> {
|
||||
|
||||
// This is how nanoid's documentation says to do it.
|
||||
let filename = nanoid!(size);
|
||||
FileName(Cow::Owned(filename))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
use rocket::request::FromParam;
|
||||
|
||||
// Returns an instance of `FileName` if the path segment is a valid file.
|
||||
// Otherwise returns the invalid filename as the `Err` value.
|
||||
// Since the ONLY files that are inside the ./files/ directory, this is more
|
||||
// than enough to protect against path disclosure attacks.
|
||||
|
||||
impl<'a> FromParam<'a> for FileName<'a> {
|
||||
type Error = &'a str;
|
||||
|
||||
fn from_param(param: &'a str) -> Result<Self, Self::Error> {
|
||||
param.chars().all(|c| c.is_ascii_alphanumeric())
|
||||
.then(|| FileName(param.into()))
|
||||
.ok_or(param)
|
||||
}
|
||||
}
|
80
src/main.rs
80
src/main.rs
|
@ -1,15 +1,49 @@
|
|||
#[macro_use] extern crate rocket;
|
||||
|
||||
use rocket::{fs::{FileServer, relative}};
|
||||
use std::path::{PathBuf, Path};
|
||||
use rocket::{fs::{FileServer, relative, NamedFile}, Data, http::ContentType};
|
||||
use rocket::tokio::fs::File;
|
||||
use rocket::request::FromParam;
|
||||
|
||||
// For cleaner thread
|
||||
use rocket::tokio::time::{sleep, Duration};
|
||||
|
||||
// Load Modules Locally
|
||||
// mod conf
|
||||
mod db;
|
||||
mod lib;
|
||||
use lib::FileName;
|
||||
|
||||
// Setup config stuffs
|
||||
|
||||
|
||||
// Main Root page
|
||||
#[get("/")]
|
||||
fn index() -> &'static str {
|
||||
"Hello, world!"
|
||||
async fn index() -> &'static str {
|
||||
"
|
||||
USAGE
|
||||
|
||||
POST /
|
||||
|
||||
accepts raw data in the body of the request and responds with a URL of
|
||||
a page containing the body's content
|
||||
|
||||
GET /<filename>.[ext]
|
||||
|
||||
retrieves the content for the paste with id `<id>` (Code Highlighting running on supported .[ext]'s)
|
||||
"
|
||||
}
|
||||
|
||||
// Processing Upload files
|
||||
|
||||
|
||||
// Serving Files
|
||||
#[get("/<file>")]
|
||||
async fn serve_file(file: &str) -> Option<File> {
|
||||
// upload_dir is ./files/
|
||||
let upload_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/", "files");
|
||||
let filename = Path::new(upload_dir).join(file);
|
||||
File::open(&filename).await.ok()
|
||||
}
|
||||
|
||||
// About Page
|
||||
|
@ -23,19 +57,39 @@ fn faq() -> &'static str {
|
|||
"1. You're on your own until I can get templating working. ;)"
|
||||
}
|
||||
|
||||
// Favicon
|
||||
// #[get("/favicon.ico")]
|
||||
// fn favicon() -> content::Custom<&'static [u8]> {
|
||||
// content::Custom(ContentType::Icon, FAVICON.into())
|
||||
// }
|
||||
|
||||
|
||||
#[launch]
|
||||
fn rocket() -> _ {
|
||||
// Create DB if it doesn't exist already.
|
||||
db::create_files_db();
|
||||
// db::create_files_db();
|
||||
|
||||
rocket::build()
|
||||
.mount("/", routes![index, about, faq])
|
||||
.mount("/", routes![index, about, faq, serve_file])
|
||||
.mount("/", FileServer::from(relative!("static")))
|
||||
}
|
||||
}
|
||||
|
||||
fn cleaner_thread() {
|
||||
// Need to figure out the best way to get this to run every x seconds.
|
||||
// Potentially a extra thread, JUST with a counter?
|
||||
// ONLY RUNS if config says so!
|
||||
|
||||
// This thread reads the engine mode from the config, and runs the function for the right mode.
|
||||
|
||||
// This is a good example from rockets code.
|
||||
// async fn delay(seconds: u64) -> String {
|
||||
// sleep(Duration::from_secs(seconds)).await;
|
||||
// format!("Waited for {} seconds", seconds)
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
fn deletion_engine_1() {
|
||||
// Loops through all files in db that aren't already deleted
|
||||
// calls delete_file() on any files where last access is longer than expiry ago.
|
||||
}
|
||||
|
||||
fn deletion_engine_2() {
|
||||
// Loops through all files in db that aren't already deleted
|
||||
// calls delete_file() on any files that match the 0x0 math stuff
|
||||
}
|
||||
|
||||
// More engine modes later!
|
|
@ -0,0 +1,15 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
files (file) {
|
||||
file -> Text,
|
||||
expiry -> Int4,
|
||||
expiry_override -> Int4,
|
||||
views -> Int4,
|
||||
is_deleted -> Int4,
|
||||
adminkey -> Text,
|
||||
accessed -> Int4,
|
||||
filesize -> Int4,
|
||||
ip -> Text,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue