From c7ccf7ebe2d81b9b2be8424b3c06753f44da2de9 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 19 Sep 2022 15:31:26 +0000 Subject: [PATCH] Update params --- Cargo.lock | 115 ++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- src/error.rs | 2 + src/server/params.rs | 52 ++++++++++++++++++- 4 files changed, 167 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0734bb3..6a3478a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -186,6 +186,16 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + [[package]] name = "bumpalo" version = "3.11.0" @@ -960,9 +970,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "libloading" @@ -1015,6 +1025,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1063,6 +1083,23 @@ dependencies = [ "syn", ] +[[package]] +name = "multipart" +version = "0.18.0" +source = "git+https://github.com/lifegpc/multipart#8275a9008f6d355d3cd433eb9bc4b20f25eec3bd" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand", + "safemem", + "tempfile", + "twoway", +] + [[package]] name = "native-tls" version = "0.2.10" @@ -1358,6 +1395,7 @@ dependencies = [ "lazy_static", "link-cplusplus", "modular-bitfield", + "multipart", "parse-size", "proc_macros", "regex", @@ -1376,6 +1414,12 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -1406,6 +1450,12 @@ dependencies = [ "syn", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.21" @@ -1415,6 +1465,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1567,6 +1647,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + [[package]] name = "schannel" version = "0.1.20" @@ -1933,6 +2019,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "twoway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47" +dependencies = [ + "memchr", + "unchecked-index", +] + [[package]] name = "typenum" version = "1.15.0" @@ -1945,6 +2041,21 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +[[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", +] + [[package]] name = "unicode-bidi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index 8cc26bf..f13c1d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ itertools = "0.10" json = "0.12" lazy_static = "1.4" modular-bitfield = "0.11" +multipart = { features = ["server"], git = 'https://github.com/lifegpc/multipart', optional = true, default-features = false } parse-size = "1" proc_macros = { path = "proc_macros" } regex = "1" @@ -52,7 +53,7 @@ db = ["anyhow", "async-trait", "bytes"] db_all = ["db", "db_sqlite"] db_sqlite = ["rusqlite"] exif = ["bindgen", "c_fixed_string", "cmake", "link-cplusplus", "utf16string"] -server = ["async-trait", "db", "hyper"] +server = ["async-trait", "db", "hyper", "multipart"] ugoira = ["avdict", "bindgen", "cmake", "link-cplusplus"] [profile.release-with-debug] diff --git a/src/error.rs b/src/error.rs index 051b57f..04f5fd8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,6 +21,8 @@ pub enum PixivDownloaderError { DbError(crate::db::PixivDownloaderDbError), #[cfg(feature = "server")] FromUtf8Error(std::string::FromUtf8Error), + #[cfg(feature = "server")] + ToStrError(http::header::ToStrError), } impl From<&str> for PixivDownloaderError { diff --git a/src/server/params.rs b/src/server/params.rs index 057e818..cadea79 100644 --- a/src/server/params.rs +++ b/src/server/params.rs @@ -1,8 +1,12 @@ use super::traits::GetRequestParams; use crate::error::PixivDownloaderError; -use bytes::BytesMut; +use crate::ext::try_err::TryErr; +use crate::gettext; +use bytes::{Buf, BytesMut}; use hyper::{body::HttpBody, Body, Request}; +use multipart::server::{Multipart, ReadEntryResult}; use std::collections::HashMap; +use std::io::Read; pub struct RequestParams { pub params: HashMap>, @@ -31,7 +35,9 @@ impl GetRequestParams for Request { params = urlparse::parse_qs(query); } if let Some(ct) = self.headers().get(hyper::header::CONTENT_TYPE) { - if ct == "application/x-www-form-urlencoded" { + let ct = ct.to_str()?.to_owned(); + let cts = ct.to_lowercase(); + if cts == "application/x-www-form-urlencoded" { let mut body = BytesMut::new(); loop { if let Some(d) = self.body_mut().data().await { @@ -52,6 +58,48 @@ impl GetRequestParams for Request { } } } + } else if cts.starts_with("multipart/form-data") { + let mut body = BytesMut::new(); + loop { + if let Some(d) = self.body_mut().data().await { + body.extend_from_slice(&d?); + } else { + break; + } + } + let mut r = body.reader(); + let boundary = ct + .find("boundary=") + .try_err(gettext("Failed to find boundary."))?; + let boundary = &ct[boundary + 9..]; + let params2 = Multipart::with_body(&mut r, boundary); + let mut entry = params2.into_entry(); + loop { + match entry { + ReadEntryResult::Entry(mut data) => { + if data.is_text() { + let mut s = String::new(); + data.data.read_to_string(&mut s)?; + let name = data.headers.name.to_string(); + match params.get_mut(&name) { + Some(l) => { + l.push(s); + } + None => { + params.insert(name, vec![s]); + } + } + } + entry = data.next_entry(); + } + ReadEntryResult::End(_) => { + break; + } + ReadEntryResult::Error(_, e) => { + return Err(PixivDownloaderError::from(e)); + } + } + } } } Ok(RequestParams { params })