+ Adding proper file upload support
! Requirements for variable message fetching not yet met ! /message/get?id=<id> needs a way of passing back file contents ! The file upload is sketchy at best and not necessarily guaranteed to sync the database with the file system
This commit is contained in:
parent
92dc4d888f
commit
d02084a22c
52
json-api/Cargo.lock
generated
52
json-api/Cargo.lock
generated
@ -354,6 +354,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"mysql_async",
|
||||
"serde",
|
||||
"tokio 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -584,7 +585,7 @@ dependencies = [
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
"tokio-util 0.3.1",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
@ -656,7 +657,7 @@ dependencies = [
|
||||
"itoa",
|
||||
"pin-project 1.0.5",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
@ -724,7 +725,7 @@ dependencies = [
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
"tokio-test",
|
||||
]
|
||||
|
||||
@ -783,9 +784,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.90"
|
||||
version = "0.2.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
|
||||
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
@ -871,7 +872,7 @@ checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mio",
|
||||
"miow 0.3.6",
|
||||
"miow 0.3.7",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
@ -900,11 +901,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
|
||||
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||
dependencies = [
|
||||
"socket2",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
@ -928,7 +928,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
"tokio-tls",
|
||||
"tokio-util 0.2.0",
|
||||
"twox-hash",
|
||||
@ -1449,18 +1449,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.124"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.124"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1541,9 +1541,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "standback"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "decebb311175fdaf1bf8a14583716e93163c566db2ead1c1d608c3e1e4313cb8"
|
||||
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
@ -1770,6 +1770,18 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes 1.0.1",
|
||||
"memchr",
|
||||
"pin-project-lite 0.2.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "0.2.6"
|
||||
@ -1789,7 +1801,7 @@ checksum = "ed0049c119b6d505c4447f5c64873636c7af6c75ab0d45fd9f618d82acb8016d"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"futures-core",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1799,7 +1811,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1813,7 +1825,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite 0.1.12",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1827,7 +1839,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite 0.1.12",
|
||||
"tokio",
|
||||
"tokio 0.2.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -10,4 +10,4 @@ edition = "2018"
|
||||
mysql_async = "0.23.1"
|
||||
|
||||
serde = { version = "1.0.117", features = [ "derive" ] }
|
||||
|
||||
tokio = { version = "1", features = ["fs", "io-util"] }
|
||||
|
@ -1,8 +1,14 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use mysql_async::{params, Pool};
|
||||
use tokio::fs;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
use mysql_async::params;
|
||||
use mysql_async::{Pool, Conn};
|
||||
use mysql_async::prelude::Queryable;
|
||||
use mysql_async::error::Error as SqlError;
|
||||
use mysql_async::QueryResult;
|
||||
use mysql_async::BinaryProtocol;
|
||||
|
||||
|
||||
use crate::{Response, sql_err};
|
||||
@ -13,27 +19,7 @@ const MAX_MESSAGES: u64 = 1000;
|
||||
|
||||
|
||||
impl Message {
|
||||
pub async fn send(p: &Pool, content: &str, content_type: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
||||
//! @returns on_sucess -> empty
|
||||
//! @returns on_failure Err(SqlErr)
|
||||
|
||||
let conn = p.get_conn().await?;
|
||||
let q = "INSERT INTO messages
|
||||
(time, content, content_type, author_id, channel_id)
|
||||
VALUES (:time, :content, :ctype, :author, :channel)";
|
||||
|
||||
let now: i64 = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("System time `NOW` failed")
|
||||
.as_millis() as i64;
|
||||
|
||||
let res = conn.prep_exec(q, params!{
|
||||
"time" => now,
|
||||
"content" => content,
|
||||
"ctype" => content_type,
|
||||
"author" => uid,
|
||||
"channel" => cid
|
||||
}).await;
|
||||
fn send_verify_error(res: Result<QueryResult<Conn, BinaryProtocol>, SqlError> ) -> Result<Response<Self>, SqlError> {
|
||||
if let Err(e) = res {
|
||||
return match e {
|
||||
SqlError::Server(err) => {
|
||||
@ -52,6 +38,76 @@ impl Message {
|
||||
else {
|
||||
return Ok(Response::Empty);
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send(p: &Pool, content: &str, content_type: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
||||
//! @returns on_sucess -> empty
|
||||
//! @returns on_failure Err(SqlErr)
|
||||
|
||||
let conn = p.get_conn().await?;
|
||||
let q = "INSERT INTO messages
|
||||
(time, content, content_type, author_id, channel_id)
|
||||
VALUES (:time, :content, :ctype, :author, :channel)";
|
||||
|
||||
let now: i64 = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("System time `NOW` failed")
|
||||
.as_millis() as i64;
|
||||
|
||||
match content_type {
|
||||
"text/plain" => {
|
||||
if content.len() > 4_000 {
|
||||
Ok(Response::RestrictedInput("Large text not allowed".into()))
|
||||
} else {
|
||||
let res = conn.prep_exec(q, params!{
|
||||
"time" => now,
|
||||
"content" => content,
|
||||
"ctype" => content_type,
|
||||
"author" => uid,
|
||||
"channel" => cid
|
||||
}).await;
|
||||
Self::send_verify_error(res)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
if content.len() > 10_000_000 {
|
||||
Ok(Response::RestrictedInput("Large data not allowed".into()))
|
||||
} else {
|
||||
let extension = match content_type {
|
||||
"image/png" => "png",
|
||||
"image/jpeg" | "image/jpg" => "jpg",
|
||||
"application/webm" => "webm",
|
||||
"application/mp4" => "mp4",
|
||||
"application/mp3" => "mp3",
|
||||
_ => panic!("Bad file type sent to db layer {}", content_type)
|
||||
};
|
||||
let content_ref = format!("{cid}-{time}.{ext}", cid=cid, time=now, ext=extension);
|
||||
|
||||
let res = conn.prep_exec(q, params!{
|
||||
"time" => now,
|
||||
"content" => &content_ref, // store a ref to a file instead of the actual payload
|
||||
"ctype" => content_type,
|
||||
"author" => uid,
|
||||
"channel" => cid
|
||||
}).await;
|
||||
if let Ok(ret) = Self::send_verify_error(res) {
|
||||
// now save the data to disk
|
||||
match fs::File::create(content_ref).await {
|
||||
Ok(mut file) => {
|
||||
file.write_all(content.as_bytes()).await.expect("Failed to write, but the ref is saved");
|
||||
Ok(ret)
|
||||
},
|
||||
Err(_) => {
|
||||
Ok(Response::Other("Saved ref but couldn't save file data".into()))
|
||||
},
|
||||
}
|
||||
} else {
|
||||
Ok(Response::Success)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user