diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/src/main.rs b/src/main.rs index 769ed03..86af042 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -10,6 +10,18 @@ use url::form_urlencoded; | |||
10 | use std::collections::HashMap; | 10 | use std::collections::HashMap; |
11 | use std::path::Path; | 11 | use std::path::Path; |
12 | 12 | ||
13 | fn respond_with_shortlink<S: AsRef<str>>(shortlink: S) -> Response<Body> { | ||
14 | Response::builder() | ||
15 | .status(StatusCode::OK) | ||
16 | .header("content-type", "text/html") | ||
17 | .body(Body::from(shortlink.as_ref().to_string())) | ||
18 | .unwrap() | ||
19 | } | ||
20 | |||
21 | fn respond_with_status(s: StatusCode) -> Response<Body> { | ||
22 | Response::builder().status(s).body(Body::empty()).unwrap() | ||
23 | } | ||
24 | |||
13 | fn shorten<S: AsRef<str>>(url: S, conn: &mut Connection) -> Result<String> { | 25 | fn shorten<S: AsRef<str>>(url: S, conn: &mut Connection) -> Result<String> { |
14 | let mut stmt = conn.prepare("select * from urls where link = ?1")?; | 26 | let mut stmt = conn.prepare("select * from urls where link = ?1")?; |
15 | let mut rows = stmt.query(params![url.as_ref().to_string()])?; | 27 | let mut rows = stmt.query(params![url.as_ref().to_string()])?; |
@@ -36,14 +48,22 @@ fn get_link<S: AsRef<str>>(url: S, conn: &mut Connection) -> Result<Option<Strin | |||
36 | } | 48 | } |
37 | } | 49 | } |
38 | 50 | ||
39 | async fn process_multipart(body: Body, boundary: String) -> Result<Response<Body>> { | 51 | async fn process_multipart( |
52 | body: Body, | ||
53 | boundary: String, | ||
54 | conn: &mut Connection, | ||
55 | ) -> Result<Response<Body>> { | ||
40 | let mut m = Multipart::new(body, boundary); | 56 | let mut m = Multipart::new(body, boundary); |
41 | if let Some(field) = m.next_field().await? { | 57 | if let Some(field) = m.next_field().await? { |
42 | let content = field | 58 | if field.name() == Some("shorten") { |
43 | .text() | 59 | let content = field |
44 | .await | 60 | .text() |
45 | .with_context(|| format!("Expected field name"))?; | 61 | .await |
46 | eprintln!("{}", content); | 62 | .with_context(|| format!("Expected field name"))?; |
63 | |||
64 | let shortlink = shorten(content, conn)?; | ||
65 | return Ok(respond_with_shortlink(shortlink)); | ||
66 | } | ||
47 | } | 67 | } |
48 | Ok(Response::builder() | 68 | Ok(Response::builder() |
49 | .status(StatusCode::OK) | 69 | .status(StatusCode::OK) |
@@ -61,7 +81,6 @@ async fn shortner_service(req: Request<Body>) -> Result<Response<Body>> { | |||
61 | .and_then(|ct| ct.to_str().ok()) | 81 | .and_then(|ct| ct.to_str().ok()) |
62 | .and_then(|ct| multer::parse_boundary(ct).ok()); | 82 | .and_then(|ct| multer::parse_boundary(ct).ok()); |
63 | 83 | ||
64 | // Send `BAD_REQUEST` status if the content-type is not multipart/form-data. | ||
65 | if boundary.is_none() { | 84 | if boundary.is_none() { |
66 | let b = hyper::body::to_bytes(req) | 85 | let b = hyper::body::to_bytes(req) |
67 | .await | 86 | .await |
@@ -72,27 +91,14 @@ async fn shortner_service(req: Request<Body>) -> Result<Response<Body>> { | |||
72 | .collect::<HashMap<String, String>>(); | 91 | .collect::<HashMap<String, String>>(); |
73 | 92 | ||
74 | if let Some(n) = params.get("shorten") { | 93 | if let Some(n) = params.get("shorten") { |
75 | let shortlink = shorten(n, &mut conn)?; | 94 | let s = shorten(n, &mut conn)?; |
76 | eprintln!("{}", shortlink); | 95 | return Ok(respond_with_shortlink(s)); |
77 | let res = Response::builder() | ||
78 | .status(StatusCode::OK) | ||
79 | .header("content-type", "text/html") | ||
80 | .body(Body::from(shortlink))?; | ||
81 | return Ok(res); | ||
82 | } else { | 96 | } else { |
83 | eprintln!("hello world"); | 97 | return Ok(respond_with_status(StatusCode::UNPROCESSABLE_ENTITY)); |
84 | let res = Response::builder() | ||
85 | .status(StatusCode::UNPROCESSABLE_ENTITY) | ||
86 | .body(Body::empty())?; | ||
87 | return Ok(res); | ||
88 | } | 98 | } |
89 | } | 99 | } |
90 | 100 | ||
91 | if let Ok(res) = process_multipart(req.into_body(), boundary.unwrap()).await { | 101 | return process_multipart(req.into_body(), boundary.unwrap(), &mut conn).await; |
92 | return Ok(res); | ||
93 | } else { | ||
94 | panic!("nani"); | ||
95 | } | ||
96 | } | 102 | } |
97 | &Method::GET => { | 103 | &Method::GET => { |
98 | let shortlink = req.uri().path().to_string(); | 104 | let shortlink = req.uri().path().to_string(); |
@@ -135,15 +141,14 @@ fn init_db<P: AsRef<Path>>(p: P) -> Result<Connection> { | |||
135 | return Ok(conn); | 141 | return Ok(conn); |
136 | } | 142 | } |
137 | 143 | ||
138 | #[tokio::main] | 144 | fn main() -> Result<()> { |
139 | async fn main() -> Result<()> { | 145 | smol::run(async { |
140 | let addr = ([127, 0, 0, 1], 3000).into(); | 146 | let addr = ([127, 0, 0, 1], 3000).into(); |
141 | 147 | let service = | |
142 | let service = | 148 | make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(shortner_service)) }); |
143 | make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(shortner_service)) }); | 149 | let server = Server::bind(&addr).serve(service); |
144 | 150 | println!("Listening on http://{}", addr); | |
145 | let server = Server::bind(&addr).serve(service); | 151 | server.await.unwrap(); |
146 | println!("Listening on http://{}", addr); | 152 | Ok(()) |
147 | server.await.unwrap(); | 153 | }) |
148 | Ok(()) | ||
149 | } | 154 | } |