+ 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 = [
|
dependencies = [
|
||||||
"mysql_async",
|
"mysql_async",
|
||||||
"serde",
|
"serde",
|
||||||
|
"tokio 1.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -584,7 +585,7 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
"tokio-util 0.3.1",
|
"tokio-util 0.3.1",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-futures",
|
"tracing-futures",
|
||||||
@ -656,7 +657,7 @@ dependencies = [
|
|||||||
"itoa",
|
"itoa",
|
||||||
"pin-project 1.0.5",
|
"pin-project 1.0.5",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
"want",
|
"want",
|
||||||
@ -724,7 +725,7 @@ dependencies = [
|
|||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -783,9 +784,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.90"
|
version = "0.2.91"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
|
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-sys"
|
name = "libz-sys"
|
||||||
@ -871,7 +872,7 @@ checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio",
|
||||||
"miow 0.3.6",
|
"miow 0.3.7",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -900,11 +901,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miow"
|
name = "miow"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
|
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"socket2",
|
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -928,7 +928,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
"tokio-tls",
|
"tokio-tls",
|
||||||
"tokio-util 0.2.0",
|
"tokio-util 0.2.0",
|
||||||
"twox-hash",
|
"twox-hash",
|
||||||
@ -1449,18 +1449,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.124"
|
version = "1.0.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
|
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.124"
|
version = "1.0.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
|
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1541,9 +1541,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "standback"
|
name = "standback"
|
||||||
version = "0.2.16"
|
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 = "decebb311175fdaf1bf8a14583716e93163c566db2ead1c1d608c3e1e4313cb8"
|
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@ -1770,6 +1770,18 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"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]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
@ -1789,7 +1801,7 @@ checksum = "ed0049c119b6d505c4447f5c64873636c7af6c75ab0d45fd9f618d82acb8016d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.5.6",
|
"bytes 0.5.6",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1799,7 +1811,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343"
|
checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1813,7 +1825,7 @@ dependencies = [
|
|||||||
"futures-sink",
|
"futures-sink",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite 0.1.12",
|
"pin-project-lite 0.1.12",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1827,7 +1839,7 @@ dependencies = [
|
|||||||
"futures-sink",
|
"futures-sink",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite 0.1.12",
|
"pin-project-lite 0.1.12",
|
||||||
"tokio",
|
"tokio 0.2.25",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -10,4 +10,4 @@ edition = "2018"
|
|||||||
mysql_async = "0.23.1"
|
mysql_async = "0.23.1"
|
||||||
|
|
||||||
serde = { version = "1.0.117", features = [ "derive" ] }
|
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 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::prelude::Queryable;
|
||||||
use mysql_async::error::Error as SqlError;
|
use mysql_async::error::Error as SqlError;
|
||||||
|
use mysql_async::QueryResult;
|
||||||
|
use mysql_async::BinaryProtocol;
|
||||||
|
|
||||||
|
|
||||||
use crate::{Response, sql_err};
|
use crate::{Response, sql_err};
|
||||||
@ -13,27 +19,7 @@ const MAX_MESSAGES: u64 = 1000;
|
|||||||
|
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
pub async fn send(p: &Pool, content: &str, content_type: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
fn send_verify_error(res: Result<QueryResult<Conn, BinaryProtocol>, SqlError> ) -> 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;
|
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return match e {
|
return match e {
|
||||||
SqlError::Server(err) => {
|
SqlError::Server(err) => {
|
||||||
@ -52,6 +38,76 @@ impl Message {
|
|||||||
else {
|
else {
|
||||||
return Ok(Response::Empty);
|
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