mirror of
https://github.com/amigan/rustypaste-pretty.git
synced 2025-01-31 04:52:37 -05:00
feat(server): support file upload and serving
This commit is contained in:
parent
df0d22dcb3
commit
1413335519
10 changed files with 679 additions and 45 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -1 +1,8 @@
|
||||||
/target
|
# Compiled files and executables
|
||||||
|
/target/
|
||||||
|
|
||||||
|
# Backup files generated by rustfmt
|
||||||
|
**/*.rs.bk
|
||||||
|
|
||||||
|
# Default upload directory
|
||||||
|
/upload/
|
||||||
|
|
414
Cargo.lock
generated
414
Cargo.lock
generated
|
@ -37,6 +37,26 @@ dependencies = [
|
||||||
"trust-dns-resolver",
|
"trust-dns-resolver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-files"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c51e8a9146c12fce92a6e4c24b8c4d9b05268130bfd8d61bc587e822c32ce689"
|
||||||
|
dependencies = [
|
||||||
|
"actix-service",
|
||||||
|
"actix-web",
|
||||||
|
"bitflags",
|
||||||
|
"bytes 0.5.6",
|
||||||
|
"derive_more",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"percent-encoding",
|
||||||
|
"v_htmlescape",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
@ -74,9 +94,9 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project 1.0.7",
|
"pin-project 1.0.7",
|
||||||
"rand",
|
"rand 0.7.3",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
|
@ -94,6 +114,24 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-multipart"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "774bfeb11b54bf9c857a005b8ab893293da4eaff79261a66a9200dab7f5ab6e3"
|
||||||
|
dependencies = [
|
||||||
|
"actix-service",
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"bytes 0.5.6",
|
||||||
|
"derive_more",
|
||||||
|
"futures-util",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"twoway",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-router"
|
name = "actix-router"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
@ -104,7 +142,7 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -243,7 +281,7 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"pin-project 1.0.7",
|
"pin-project 1.0.7",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
@ -278,6 +316,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.50"
|
version = "0.1.50"
|
||||||
|
@ -324,8 +368,8 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand",
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
]
|
]
|
||||||
|
@ -377,12 +421,31 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "buf-min"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa17aa1cf56bdd6bb30518767d00e58019d326f3f05d8c3e0730b549d332ea83"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 0.5.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.7.0"
|
version = "3.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-unit"
|
||||||
|
version = "4.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "063197e6eb4b775b64160dedde7a0986bb2836cce140e9492e9e96f28e18bcd8"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.126",
|
||||||
|
"utf8-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
|
@ -428,6 +491,33 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.33.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "config"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"nom 5.1.2",
|
||||||
|
"rust-ini",
|
||||||
|
"serde 1.0.126",
|
||||||
|
"serde-hjson",
|
||||||
|
"serde_json",
|
||||||
|
"toml",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
|
@ -448,7 +538,7 @@ checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"time",
|
"time",
|
||||||
"version_check",
|
"version_check 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -685,7 +775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"version_check",
|
"version_check 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -696,7 +786,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"libc",
|
||||||
|
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -828,6 +929,15 @@ dependencies = [
|
||||||
"winreg",
|
"winreg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
@ -856,6 +966,19 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lexical-core"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"ryu",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.98"
|
version = "0.2.98"
|
||||||
|
@ -919,6 +1042,16 @@ version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -982,6 +1115,45 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "4.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"version_check 0.1.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "5.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||||
|
dependencies = [
|
||||||
|
"lexical-core",
|
||||||
|
"memchr",
|
||||||
|
"version_check 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.1.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits 0.2.14",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -996,9 +1168,16 @@ dependencies = [
|
||||||
name = "oops"
|
name = "oops"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"actix-files",
|
||||||
|
"actix-multipart",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
"byte-unit",
|
||||||
|
"config",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
|
"petname",
|
||||||
|
"serde 1.0.126",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1047,6 +1226,17 @@ dependencies = [
|
||||||
"ucd-trie",
|
"ucd-trie",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "petname"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9ed8e1c7b7cdd47819f76bbec141b4d4b59bb8ffd26c372cc236c90cd90becc"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"itertools",
|
||||||
|
"rand 0.8.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "0.4.28"
|
version = "0.4.28"
|
||||||
|
@ -1153,11 +1343,23 @@ version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.1.16",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.2.2",
|
||||||
"rand_core",
|
"rand_core 0.5.1",
|
||||||
"rand_hc",
|
"rand_hc 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.3.1",
|
||||||
|
"rand_core 0.6.3",
|
||||||
|
"rand_hc 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1167,7 +1369,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1176,7 +1388,16 @@ version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.1.16",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1185,7 +1406,16 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1224,6 +1454,12 @@ dependencies = [
|
||||||
"quick-error",
|
"quick-error",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-ini"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -1287,6 +1523,12 @@ dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.126"
|
version = "1.0.126"
|
||||||
|
@ -1296,6 +1538,18 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-hjson"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"num-traits 0.1.43",
|
||||||
|
"regex",
|
||||||
|
"serde 0.8.23",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.126"
|
version = "1.0.126"
|
||||||
|
@ -1315,7 +1569,7 @@ checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1327,7 +1581,7 @@ dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1387,9 +1641,15 @@ version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"version_check",
|
"version_check 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stdweb"
|
name = "stdweb"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -1412,7 +1672,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
@ -1426,7 +1686,7 @@ dependencies = [
|
||||||
"base-x",
|
"base-x",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
"serde 1.0.126",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha1",
|
"sha1",
|
||||||
|
@ -1459,6 +1719,15 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.26"
|
version = "1.0.26"
|
||||||
|
@ -1499,7 +1768,7 @@ dependencies = [
|
||||||
"standback",
|
"standback",
|
||||||
"stdweb",
|
"stdweb",
|
||||||
"time-macros",
|
"time-macros",
|
||||||
"version_check",
|
"version_check 0.9.3",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1575,6 +1844,15 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.126",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.26"
|
version = "0.1.26"
|
||||||
|
@ -1619,7 +1897,7 @@ dependencies = [
|
||||||
"idna",
|
"idna",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand 0.7.3",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -1645,6 +1923,16 @@ dependencies = [
|
||||||
"trust-dns-proto",
|
"trust-dns-proto",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "twoway"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"unchecked-index",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -1657,6 +1945,21 @@ version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unchecked-index"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||||
|
dependencies = [
|
||||||
|
"version_check 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -1681,6 +1984,12 @@ version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -1699,6 +2008,50 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-width"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "v_escape"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3e0ab5fab1db278a9413d2ea794cb66f471f898c5b020c3c394f6447625d9d4"
|
||||||
|
dependencies = [
|
||||||
|
"buf-min",
|
||||||
|
"v_escape_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "v_escape_derive"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c860ad1273f4eee7006cee05db20c9e60e5d24cba024a32e1094aa8e574f3668"
|
||||||
|
dependencies = [
|
||||||
|
"nom 4.2.3",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "v_htmlescape"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f9a8af610ad6f7fc9989c9d2590d9764bc61f294884e9ee93baa58795174572"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"v_escape",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
@ -1711,6 +2064,12 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.74"
|
version = "0.2.74"
|
||||||
|
@ -1832,3 +2191,12 @@ dependencies = [
|
||||||
"winapi 0.2.8",
|
"winapi 0.2.8",
|
||||||
"winapi-build",
|
"winapi-build",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -2,13 +2,23 @@
|
||||||
name = "oops"
|
name = "oops"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Orhun's obscure pastebin server"
|
description = "An obscure pastebin server"
|
||||||
authors = ["Orhun Parmaksız <orhunparmaksiz@gmail.com>"]
|
authors = ["Orhun Parmaksız <orhunparmaksiz@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "3.3.2"
|
actix-web = "3.3.2"
|
||||||
|
actix-multipart = "0.3.0"
|
||||||
|
actix-files = "0.5.0"
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
|
serde = "1.0.126"
|
||||||
|
futures-util = "0.3.15"
|
||||||
|
config = "0.11.0"
|
||||||
|
petname = "1.1.0"
|
||||||
|
|
||||||
|
[dependencies.byte-unit]
|
||||||
|
version = "4.0.12"
|
||||||
|
features = ["serde"]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 0
|
opt-level = 0
|
||||||
|
|
10
config.toml
Normal file
10
config.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[server]
|
||||||
|
address="127.0.0.1:8000"
|
||||||
|
#workers=4
|
||||||
|
max_content_length="10MB"
|
||||||
|
upload_path="./upload"
|
||||||
|
#auth_token="" # OOPS_SERVER__AUTH_TOKEN=
|
||||||
|
|
||||||
|
[paste]
|
||||||
|
pet_names = true
|
||||||
|
default_extension = "txt"
|
47
src/config.rs
Normal file
47
src/config.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use byte_unit::Byte;
|
||||||
|
use config::{self, ConfigError};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// Configuration values.
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
/// Server configuration.
|
||||||
|
pub server: ServerConfig,
|
||||||
|
/// Paste configuration.
|
||||||
|
pub paste: PasteConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Server configuration.
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct ServerConfig {
|
||||||
|
/// The socket address to bind.
|
||||||
|
pub address: String,
|
||||||
|
/// Number of workers to start.
|
||||||
|
pub workers: Option<usize>,
|
||||||
|
/// Maximum content length.
|
||||||
|
pub max_content_length: Byte,
|
||||||
|
/// Storage path.
|
||||||
|
pub upload_path: PathBuf,
|
||||||
|
/// Authentication token.
|
||||||
|
pub auth_token: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Paste configuration.
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct PasteConfig {
|
||||||
|
/// Use pet names instead of original file names.
|
||||||
|
pub pet_names: bool,
|
||||||
|
/// Default file extension.
|
||||||
|
pub default_extension: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
/// Parses the config file and returns the values.
|
||||||
|
pub fn parse(file_name: &str) -> Result<Config, ConfigError> {
|
||||||
|
let mut config = config::Config::default();
|
||||||
|
config
|
||||||
|
.merge(config::File::with_name(file_name))?
|
||||||
|
.merge(config::Environment::with_prefix(env!("CARGO_PKG_NAME")).separator("__"))?;
|
||||||
|
config.try_into()
|
||||||
|
}
|
||||||
|
}
|
39
src/file.rs
Normal file
39
src/file.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
use crate::config::Config;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Result as IoResult, Write};
|
||||||
|
|
||||||
|
/// Writes the bytes to a file in upload directory.
|
||||||
|
///
|
||||||
|
/// - If `file_name` does not have an extension, it is replaced with [`default_extension`].
|
||||||
|
/// - If `file_name` is "-", it is replaced with "stdin".
|
||||||
|
/// - If [`pet_names`] is `true`, `file_name` is replaced with a pet name.
|
||||||
|
///
|
||||||
|
/// [`default_extension`]: crate::config::PasteConfig::default_extension
|
||||||
|
/// [`pet_names`]: crate::config::PasteConfig::pet_names
|
||||||
|
pub fn save(mut file_name: &str, bytes: &[u8], config: &Config) -> IoResult<String> {
|
||||||
|
if file_name == "-" {
|
||||||
|
file_name = "stdin";
|
||||||
|
}
|
||||||
|
let mut path = config.server.upload_path.join(file_name);
|
||||||
|
match path.clone().extension() {
|
||||||
|
Some(extension) => {
|
||||||
|
if config.paste.pet_names {
|
||||||
|
path.set_file_name(petname::petname(2, "-"));
|
||||||
|
path.set_extension(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if config.paste.pet_names {
|
||||||
|
path.set_file_name(petname::petname(2, "-"));
|
||||||
|
}
|
||||||
|
path.set_extension(&config.paste.default_extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut buffer = File::create(&path)?;
|
||||||
|
buffer.write_all(bytes)?;
|
||||||
|
Ok(path
|
||||||
|
.file_name()
|
||||||
|
.map(|v| v.to_string_lossy())
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string())
|
||||||
|
}
|
49
src/header.rs
Normal file
49
src/header.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use actix_web::http::header::{
|
||||||
|
ContentDisposition as ActixContentDisposition, DispositionParam, DispositionType,
|
||||||
|
};
|
||||||
|
use actix_web::{error, Error as ActixError};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
/// Wrapper for Actix content disposition header.
|
||||||
|
///
|
||||||
|
/// Aims to parse the file data from multipart body.
|
||||||
|
///
|
||||||
|
/// e.g. `Content-Disposition: form-data; name="field_name"; filename="filename.jpg"`
|
||||||
|
pub struct ContentDisposition {
|
||||||
|
inner: ActixContentDisposition,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Option<ActixContentDisposition>> for ContentDisposition {
|
||||||
|
type Error = ActixError;
|
||||||
|
fn try_from(content_disposition: Option<ActixContentDisposition>) -> Result<Self, Self::Error> {
|
||||||
|
match content_disposition {
|
||||||
|
Some(inner) => Ok(Self { inner }),
|
||||||
|
None => Err(error::ErrorUnprocessableEntity(
|
||||||
|
"content disposition does not exist",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContentDisposition {
|
||||||
|
/// Checks if the content disposition is a form data
|
||||||
|
/// and has the field `field_name`.
|
||||||
|
pub fn has_form_field(&self, field_name: &str) -> bool {
|
||||||
|
self.inner.disposition == DispositionType::FormData
|
||||||
|
&& self
|
||||||
|
.inner
|
||||||
|
.parameters
|
||||||
|
.contains(&DispositionParam::Name(field_name.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parses the file name from parameters if it exists.
|
||||||
|
pub fn get_file_name(&self) -> Result<&str, ActixError> {
|
||||||
|
self.inner
|
||||||
|
.parameters
|
||||||
|
.iter()
|
||||||
|
.find(|param| param.is_filename())
|
||||||
|
.map(|param| param.as_filename())
|
||||||
|
.flatten()
|
||||||
|
.ok_or_else(|| error::ErrorUnprocessableEntity("file data not present"))
|
||||||
|
}
|
||||||
|
}
|
14
src/lib.rs
Normal file
14
src/lib.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//! oops is a file upload/pastebin service.
|
||||||
|
#![warn(missing_docs, clippy::unwrap_used)]
|
||||||
|
|
||||||
|
/// Configuration file parser.
|
||||||
|
pub mod config;
|
||||||
|
|
||||||
|
/// Server routes.
|
||||||
|
pub mod server;
|
||||||
|
|
||||||
|
/// File handler.
|
||||||
|
pub mod file;
|
||||||
|
|
||||||
|
/// HTTP headers.
|
||||||
|
pub mod header;
|
40
src/main.rs
40
src/main.rs
|
@ -1,25 +1,25 @@
|
||||||
#[macro_use] extern crate log;
|
|
||||||
use actix_web::middleware::Logger;
|
use actix_web::middleware::Logger;
|
||||||
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
|
use actix_web::{App, HttpServer};
|
||||||
|
use oops::config::Config;
|
||||||
async fn index() -> impl Responder {
|
use oops::server;
|
||||||
HttpResponse::Ok().body("Hello world!")
|
use std::fs;
|
||||||
}
|
use std::io::Result as IoResult;
|
||||||
|
|
||||||
fn config(cfg: &mut web::ServiceConfig) {
|
|
||||||
cfg.service(
|
|
||||||
web::resource("/")
|
|
||||||
.route(web::get().to(index))
|
|
||||||
.route(web::head().to(|| HttpResponse::MethodNotAllowed())),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> IoResult<()> {
|
||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
HttpServer::new(|| App::new().wrap(Logger::default()).configure(config))
|
let config = Config::parse("config").expect("failed to parse config");
|
||||||
.bind("127.0.0.1:8000")?
|
let server_config = config.server.clone();
|
||||||
.workers(4)
|
fs::create_dir_all(server_config.upload_path)?;
|
||||||
.run()
|
let mut http_server = HttpServer::new(move || {
|
||||||
.await
|
App::new()
|
||||||
|
.data(config.clone())
|
||||||
|
.wrap(Logger::default())
|
||||||
|
.configure(server::configure_routes)
|
||||||
|
})
|
||||||
|
.bind(server_config.address)?;
|
||||||
|
if let Some(workers) = server_config.workers {
|
||||||
|
http_server = http_server.workers(workers);
|
||||||
|
}
|
||||||
|
http_server.run().await
|
||||||
}
|
}
|
||||||
|
|
90
src/server.rs
Normal file
90
src/server.rs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::file;
|
||||||
|
use crate::header::ContentDisposition;
|
||||||
|
use actix_files::NamedFile;
|
||||||
|
use actix_multipart::Multipart;
|
||||||
|
use actix_web::http::header::AUTHORIZATION;
|
||||||
|
use actix_web::{error, get, post, web, Error, HttpRequest, HttpResponse, Responder};
|
||||||
|
use byte_unit::Byte;
|
||||||
|
use futures_util::stream::StreamExt;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
/// Shows the landing page.
|
||||||
|
#[get("/")]
|
||||||
|
async fn index() -> impl Responder {
|
||||||
|
HttpResponse::Ok().body("oops!")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serves a file from the upload directory.
|
||||||
|
#[get("/{file}")]
|
||||||
|
async fn serve(
|
||||||
|
request: HttpRequest,
|
||||||
|
path: web::Path<String>,
|
||||||
|
config: web::Data<Config>,
|
||||||
|
) -> Result<HttpResponse, Error> {
|
||||||
|
let path = config.server.upload_path.join(&*path);
|
||||||
|
let file = NamedFile::open(&path)?
|
||||||
|
.disable_content_disposition()
|
||||||
|
.prefer_utf8(true);
|
||||||
|
let response = file.into_response(&request)?;
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles file upload by processing `multipart/form-data`.
|
||||||
|
#[post("/")]
|
||||||
|
async fn upload(
|
||||||
|
request: HttpRequest,
|
||||||
|
mut payload: Multipart,
|
||||||
|
config: web::Data<Config>,
|
||||||
|
) -> Result<HttpResponse, Error> {
|
||||||
|
if let Some(token) = &config.server.auth_token {
|
||||||
|
if request
|
||||||
|
.headers()
|
||||||
|
.get(AUTHORIZATION)
|
||||||
|
.map(|v| v.to_str().unwrap_or_default())
|
||||||
|
.map(|v| v.split_whitespace().last().unwrap_or_default())
|
||||||
|
!= Some(token)
|
||||||
|
{
|
||||||
|
return Err(error::ErrorUnauthorized("unauthorized"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut urls: Vec<String> = Vec::new();
|
||||||
|
while let Some(item) = payload.next().await {
|
||||||
|
let mut field = item?;
|
||||||
|
let content = ContentDisposition::try_from(field.content_disposition())?;
|
||||||
|
if content.has_form_field("file") {
|
||||||
|
let mut bytes = Vec::<u8>::new();
|
||||||
|
while let Some(chunk) = field.next().await {
|
||||||
|
bytes.append(&mut chunk?.to_vec());
|
||||||
|
}
|
||||||
|
if bytes.len() as u128 > config.server.max_content_length.get_bytes() {
|
||||||
|
return Err(error::ErrorPayloadTooLarge("upload limit exceeded"));
|
||||||
|
}
|
||||||
|
let file_name = &file::save(content.get_file_name()?, &bytes, &config)?;
|
||||||
|
let connection = request.connection_info();
|
||||||
|
log::info!(
|
||||||
|
"{} ({}) is uploaded from {}",
|
||||||
|
file_name,
|
||||||
|
Byte::from_bytes(bytes.len() as u128).get_appropriate_unit(false),
|
||||||
|
connection.remote_addr().unwrap_or("unknown host")
|
||||||
|
);
|
||||||
|
urls.push(format!(
|
||||||
|
"{}://{}/{}\n",
|
||||||
|
connection.scheme(),
|
||||||
|
connection.host(),
|
||||||
|
file_name
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return Err(error::ErrorUnprocessableEntity("invalid form parameters"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(HttpResponse::Ok().body(urls.join("")))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the server routes.
|
||||||
|
pub fn configure_routes(cfg: &mut web::ServiceConfig) {
|
||||||
|
cfg.service(index)
|
||||||
|
.service(serve)
|
||||||
|
.service(upload)
|
||||||
|
.route("", web::head().to(HttpResponse::MethodNotAllowed));
|
||||||
|
}
|
Loading…
Reference in a new issue