diff --git a/src/error.rs b/src/error.rs index 7476a3a..051b57f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -19,6 +19,8 @@ pub enum PixivDownloaderError { AVDict(crate::avdict::AVDictError), #[cfg(feature = "db")] DbError(crate::db::PixivDownloaderDbError), + #[cfg(feature = "server")] + FromUtf8Error(std::string::FromUtf8Error), } impl From<&str> for PixivDownloaderError { diff --git a/src/server/auth/user.rs b/src/server/auth/user.rs index 12c519b..34661d3 100644 --- a/src/server/auth/user.rs +++ b/src/server/auth/user.rs @@ -1,4 +1,5 @@ use super::super::preclude::*; +use crate::ext::json::ToJson2; #[derive(Clone, Debug)] /// Action to perform on a user. @@ -21,6 +22,21 @@ impl AuthUserContext { is_restful, } } + + async fn handle(&self, mut req: Request) -> JSONResult { + let root_user = self.ctx.db.get_user(0).await?; + let params = req.get_params().await?; + if root_user.is_some() { + // # TODO auth + } + match &self.action { + Some(act) => {} + None => { + panic!("No action specified for AuthUserContext."); + } + } + Ok(json::object! {}) + } } #[async_trait] @@ -53,13 +69,7 @@ impl ResponseJsonFor for AuthUserContext { ); builder }; - match &self.action { - Some(act) => {} - None => { - panic!("No action specified for AuthUserContext."); - } - } - Ok(builder.body(json::object! {})?) + Ok(builder.body(self.handle(req).await.to_json2())?) } } diff --git a/src/server/mod.rs b/src/server/mod.rs index c87feab..5c8b67e 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -3,6 +3,8 @@ pub mod auth; pub mod context; /// CORS Handle pub mod cors; +/// Get params from request +pub mod params; /// Predefined includes pub mod preclude; /// Base result type for JSON response diff --git a/src/server/params.rs b/src/server/params.rs new file mode 100644 index 0000000..057e818 --- /dev/null +++ b/src/server/params.rs @@ -0,0 +1,59 @@ +use super::traits::GetRequestParams; +use crate::error::PixivDownloaderError; +use bytes::BytesMut; +use hyper::{body::HttpBody, Body, Request}; +use std::collections::HashMap; + +pub struct RequestParams { + pub params: HashMap>, +} + +impl RequestParams { + pub fn get + ?Sized>(&self, name: &S) -> Option<&str> { + match self.params.get(name.as_ref()) { + Some(v) => { + if v.len() > 0 { + Some(&v[0]) + } else { + None + } + } + None => None, + } + } +} + +#[async_trait] +impl GetRequestParams for Request { + async fn get_params(&mut self) -> Result { + let mut params = HashMap::new(); + if let Some(query) = self.uri().query() { + params = urlparse::parse_qs(query); + } + if let Some(ct) = self.headers().get(hyper::header::CONTENT_TYPE) { + if ct == "application/x-www-form-urlencoded" { + let mut body = BytesMut::new(); + loop { + if let Some(d) = self.body_mut().data().await { + body.extend_from_slice(&d?); + } else { + break; + } + } + let body = String::from_utf8(body.to_vec())?; + let params2 = urlparse::parse_qs(&body); + for (k, v) in params2 { + match params.get_mut(&k) { + Some(l) => { + l.extend(v); + } + None => { + params.insert(k, v); + } + } + } + } + } + Ok(RequestParams { params }) + } +} diff --git a/src/server/preclude.rs b/src/server/preclude.rs index 412c468..9d62e15 100644 --- a/src/server/preclude.rs +++ b/src/server/preclude.rs @@ -1,7 +1,7 @@ pub use super::context::ServerContext; pub use super::result::JSONResult; pub use super::route::ResponseForType; -pub use super::traits::{MatchRoute, ResponseFor, ResponseJsonFor}; +pub use super::traits::{GetRequestParams, MatchRoute, ResponseFor, ResponseJsonFor}; pub use crate::error::PixivDownloaderError; pub use hyper::Body; pub use hyper::Method; diff --git a/src/server/result.rs b/src/server/result.rs index 684a7d0..30c6804 100644 --- a/src/server/result.rs +++ b/src/server/result.rs @@ -1,6 +1,6 @@ -use json::JsonValue; - use crate::ext::json::ToJson2; +use crate::gettext; +use json::JsonValue; #[derive(Clone, Debug)] /// Error information of a request @@ -33,6 +33,26 @@ impl From<(i32, String, Option)> for JSONError { } } +impl From for JSONError { + fn from(e: crate::db::PixivDownloaderDbError) -> Self { + Self { + code: -1001, + msg: format!("{} {}", gettext("Failed to operate the database:"), e), + debug_msg: Some(format!("{:?}", e).to_json2()), + } + } +} + +impl From for JSONError { + fn from(e: crate::error::PixivDownloaderError) -> Self { + Self { + code: -500, + msg: format!("{}", e), + debug_msg: Some(format!("{:?}", e).to_json2()), + } + } +} + pub type JSONResult = Result; impl ToJson2 for JSONResult { diff --git a/src/server/traits.rs b/src/server/traits.rs index ac5fb6c..0df9fbf 100644 --- a/src/server/traits.rs +++ b/src/server/traits.rs @@ -1,4 +1,5 @@ use super::context::ServerContext; +use super::params::RequestParams; use crate::error::PixivDownloaderError; use hyper::Body; use hyper::Request; @@ -27,6 +28,13 @@ pub trait ResponseJsonFor { ) -> Result, PixivDownloaderError>; } +#[async_trait] +/// Get params from request +pub trait GetRequestParams { + /// Get params from request + async fn get_params(&mut self) -> Result; +} + #[async_trait] impl ResponseFor for U where