diff options
-rw-r--r-- | src/main.rs | 11 | ||||
-rw-r--r-- | src/service.rs | 50 |
2 files changed, 36 insertions, 25 deletions
diff --git a/src/main.rs b/src/main.rs index 6b48957..c9819d0 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -4,15 +4,22 @@ use hyper::Server; | |||
4 | use log::trace; | 4 | use log::trace; |
5 | 5 | ||
6 | mod db; | 6 | mod db; |
7 | use db::init_db; | ||
7 | mod service; | 8 | mod service; |
8 | use service::shortner_service; | 9 | use service::shortner_service; |
9 | 10 | ||
11 | use std::sync::{Arc, Mutex}; | ||
12 | |||
10 | fn main() -> Result<()> { | 13 | fn main() -> Result<()> { |
11 | pretty_env_logger::init(); | 14 | pretty_env_logger::init(); |
12 | smol::run(async { | 15 | smol::run(async { |
13 | let addr = ([127, 0, 0, 1], 3000).into(); | 16 | let addr = ([127, 0, 0, 1], 3000).into(); |
14 | let service = | 17 | let service = make_service_fn(move |_| async { |
15 | make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(shortner_service)) }); | 18 | Ok::<_, hyper::Error>(service_fn(move |req| { |
19 | let db_conn = init_db("./urls.db_3").unwrap(); | ||
20 | shortner_service(req, db_conn) | ||
21 | })) | ||
22 | }); | ||
16 | let server = Server::bind(&addr).serve(service); | 23 | let server = Server::bind(&addr).serve(service); |
17 | trace!("Listening on http://{}", addr); | 24 | trace!("Listening on http://{}", addr); |
18 | server.await.unwrap(); | 25 | server.await.unwrap(); |
diff --git a/src/service.rs b/src/service.rs index 5883b40..41aa048 100644 --- a/src/service.rs +++ b/src/service.rs | |||
@@ -1,15 +1,14 @@ | |||
1 | use anyhow::{Context, Result}; | 1 | use anyhow::{Context, Result}; |
2 | use hyper::header::CONTENT_TYPE; | 2 | use hyper::header::CONTENT_TYPE; |
3 | use hyper::{Body, Method, Request, Response, StatusCode}; | 3 | use hyper::{Body, Method, Request, Response, StatusCode}; |
4 | use log::{debug, error, info, trace}; | 4 | use log::{error, info, trace}; |
5 | use multer::Multipart; | 5 | use multer::Multipart; |
6 | use nanoid::nanoid; | 6 | use nanoid::nanoid; |
7 | use rusqlite::{params, Connection}; | 7 | use rusqlite::{params, Connection}; |
8 | use url::form_urlencoded; | 8 | use url::form_urlencoded; |
9 | 9 | ||
10 | use std::collections::HashMap; | 10 | use std::collections::HashMap; |
11 | 11 | use std::sync::{Arc, Mutex}; | |
12 | use crate::db::init_db; | ||
13 | 12 | ||
14 | fn respond_with_shortlink<S: AsRef<str>>(shortlink: S) -> Response<Body> { | 13 | fn respond_with_shortlink<S: AsRef<str>>(shortlink: S) -> Response<Body> { |
15 | info!("Successfully generated shortlink"); | 14 | info!("Successfully generated shortlink"); |
@@ -39,7 +38,7 @@ fn shorten<S: AsRef<str>>(url: S, conn: &mut Connection) -> Result<String> { | |||
39 | } | 38 | } |
40 | } | 39 | } |
41 | 40 | ||
42 | fn get_link<S: AsRef<str>>(url: S, conn: &mut Connection) -> Result<Option<String>> { | 41 | fn get_link<S: AsRef<str>>(url: S, conn: &Connection) -> Result<Option<String>> { |
43 | let url = url.as_ref(); | 42 | let url = url.as_ref(); |
44 | let mut stmt = conn.prepare("select * from urls where shortlink = ?1")?; | 43 | let mut stmt = conn.prepare("select * from urls where shortlink = ?1")?; |
45 | let mut rows = stmt.query(params![url.to_string()])?; | 44 | let mut rows = stmt.query(params![url.to_string()])?; |
@@ -72,9 +71,29 @@ async fn process_multipart( | |||
72 | Ok(respond_with_status(StatusCode::UNPROCESSABLE_ENTITY)) | 71 | Ok(respond_with_status(StatusCode::UNPROCESSABLE_ENTITY)) |
73 | } | 72 | } |
74 | 73 | ||
75 | pub async fn shortner_service(req: Request<Body>) -> Result<Response<Body>> { | 74 | async fn process_form(req: Request<Body>, conn: &mut Connection) -> Result<Response<Body>> { |
76 | let mut conn = init_db("./urls.db_3").unwrap(); | 75 | let b = hyper::body::to_bytes(req) |
76 | .await | ||
77 | .with_context(|| format!("Failed to stream request body!"))?; | ||
78 | |||
79 | let params = form_urlencoded::parse(b.as_ref()) | ||
80 | .into_owned() | ||
81 | .collect::<HashMap<String, String>>(); | ||
77 | 82 | ||
83 | if let Some(n) = params.get("shorten") { | ||
84 | trace!("POST: {}", &n); | ||
85 | let s = shorten(n, conn)?; | ||
86 | return Ok(respond_with_shortlink(s)); | ||
87 | } else { | ||
88 | error!("Invalid form"); | ||
89 | return Ok(respond_with_status(StatusCode::UNPROCESSABLE_ENTITY)); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | pub async fn shortner_service( | ||
94 | req: Request<Body>, | ||
95 | mut conn: Arc<Mutex<Connection>>, | ||
96 | ) -> Result<Response<Body>> { | ||
78 | match req.method() { | 97 | match req.method() { |
79 | &Method::POST => { | 98 | &Method::POST => { |
80 | let boundary = req | 99 | let boundary = req |
@@ -84,22 +103,7 @@ pub async fn shortner_service(req: Request<Body>) -> Result<Response<Body>> { | |||
84 | .and_then(|ct| multer::parse_boundary(ct).ok()); | 103 | .and_then(|ct| multer::parse_boundary(ct).ok()); |
85 | 104 | ||
86 | if boundary.is_none() { | 105 | if boundary.is_none() { |
87 | let b = hyper::body::to_bytes(req) | 106 | return process_form(req, &mut conn).await; |
88 | .await | ||
89 | .with_context(|| format!("Failed to stream request body!"))?; | ||
90 | |||
91 | let params = form_urlencoded::parse(b.as_ref()) | ||
92 | .into_owned() | ||
93 | .collect::<HashMap<String, String>>(); | ||
94 | |||
95 | if let Some(n) = params.get("shorten") { | ||
96 | trace!("POST: {}", &n); | ||
97 | let s = shorten(n, &mut conn)?; | ||
98 | return Ok(respond_with_shortlink(s)); | ||
99 | } else { | ||
100 | error!("Invalid form"); | ||
101 | return Ok(respond_with_status(StatusCode::UNPROCESSABLE_ENTITY)); | ||
102 | } | ||
103 | } | 107 | } |
104 | 108 | ||
105 | trace!("Attempting to parse multipart request"); | 109 | trace!("Attempting to parse multipart request"); |
@@ -108,7 +112,7 @@ pub async fn shortner_service(req: Request<Body>) -> Result<Response<Body>> { | |||
108 | &Method::GET => { | 112 | &Method::GET => { |
109 | trace!("GET: {}", req.uri()); | 113 | trace!("GET: {}", req.uri()); |
110 | let shortlink = req.uri().path().to_string(); | 114 | let shortlink = req.uri().path().to_string(); |
111 | let link = get_link(&shortlink[1..], &mut conn); | 115 | let link = get_link(&shortlink[1..], &conn); |
112 | if let Some(l) = link.unwrap() { | 116 | if let Some(l) = link.unwrap() { |
113 | trace!("Found in database, redirecting ..."); | 117 | trace!("Found in database, redirecting ..."); |
114 | Ok(Response::builder() | 118 | Ok(Response::builder() |