diff --git a/src/api/config.rs b/src/api/config.rs index dd7dccf2..d390ed0a 100644 --- a/src/api/config.rs +++ b/src/api/config.rs @@ -21,10 +21,9 @@ impl ApiConfig { } } - pub fn find_method(&self, components: &[&str], method: Method) -> Option<&'static ApiMethod> { + pub fn find_method(&self, components: &[&str], method: Method, uri_param: &mut HashMap) -> Option<&'static ApiMethod> { - if let Some(info) = self.router.find_route(components) { - println!("FOUND INFO"); + if let Some(info) = self.router.find_route(components, uri_param) { let opt_api_method = match method { Method::GET => &info.get, Method::PUT => &info.put, diff --git a/src/api/router.rs b/src/api/router.rs index 2af43141..ef0263bb 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -67,7 +67,7 @@ impl Router { self } - pub fn find_route(&self, components: &[&str]) -> Option<&Router> { + pub fn find_route(&self, components: &[&str], uri_param: &mut HashMap) -> Option<&Router> { if components.len() == 0 { return Some(self); }; @@ -78,12 +78,13 @@ impl Router { SubRoute::Hash(ref dirmap) => { if let Some(ref router) = dirmap.get(dir) { println!("FOUND SUBDIR {}", dir); - return router.find_route(rest); + return router.find_route(rest, uri_param); } } SubRoute::MatchAll { ref router, ref param_name } => { println!("URI PARAM {} = {}", param_name, dir); // fixme: store somewhere - return router.find_route(rest); + uri_param.insert(param_name.clone(), dir.into()); + return router.find_route(rest, uri_param); }, } diff --git a/src/api/server.rs b/src/api/server.rs index c8162995..3c61b4ac 100644 --- a/src/api/server.rs +++ b/src/api/server.rs @@ -5,9 +5,11 @@ use crate::api::config::*; use std::fmt; use std::path::{PathBuf}; use std::sync::Arc; +use std::collections::HashMap; use failure::*; -use serde_json::{json, Value}; +use serde_json::{Value}; +use url::form_urlencoded; use futures::future::{self, Either}; //use tokio::prelude::*; @@ -109,6 +111,7 @@ fn get_request_parameters_async( info: &'static ApiMethod, parts: Parts, req_body: Body, + uri_param: HashMap, ) -> Box + Send> { let resp = req_body @@ -126,23 +129,27 @@ fn get_request_parameters_async( println!("GOT BODY {:?}", bytes); - let mut test_required = true; - - let mut params = json!({}); + let mut param_list: Vec<(String, String)> = vec![]; if bytes.len() > 0 { - params = parse_query_string(&bytes, &info.parameters, true)?; - test_required = false; + for (k, v) in form_urlencoded::parse(bytes.as_bytes()).into_owned() { + param_list.push((k, v)); + } + } if let Some(query_str) = parts.uri.query() { - let query_params = parse_query_string(query_str, &info.parameters, test_required)?; - - for (k, v) in query_params.as_object().unwrap() { - params[k] = v.clone(); // fixme: why clone()?? + for (k, v) in form_urlencoded::parse(query_str.as_bytes()).into_owned() { + param_list.push((k, v)); } } + for (k, v) in uri_param { + param_list.push((k.clone(), v.clone())); + } + + let params = parse_parameter_strings(¶m_list, &info.parameters, true)?; + println!("GOT PARAMS {}", params); Ok(params) }); @@ -154,9 +161,10 @@ fn handle_sync_api_request( info: &'static ApiMethod, parts: Parts, req_body: Body, + uri_param: HashMap, ) -> BoxFut { - let params = get_request_parameters_async(info, parts, req_body); + let params = get_request_parameters_async(info, parts, req_body, uri_param); let resp = params .and_then(move |params| { @@ -278,9 +286,11 @@ pub fn handle_request(api: Arc, req: Request) -> BoxFut { return Box::new(future::err(http_err!(BAD_REQUEST, format!("Unsupported output format '{}'.", format)))) } - if let Some(api_method) = api.find_method(&components[2..], method) { + let mut uri_param = HashMap::new(); + + if let Some(api_method) = api.find_method(&components[2..], method, &mut uri_param) { // fixme: handle auth - return handle_sync_api_request(api_method, parts, body); + return handle_sync_api_request(api_method, parts, body, uri_param); } } } else { @@ -292,4 +302,3 @@ pub fn handle_request(api: Arc, req: Request) -> BoxFut { Box::new(future::err(http_err!(NOT_FOUND, "Path not found.".to_string()))) } -