// extern
use anyhow::{Context, Result};
use hyper::header::{HeaderValue, CONTENT_TYPE};
use hyper::{Body, Method, Request, Response, StatusCode};
use log::{error, info, trace};
use multer::Multipart;
use nanoid::nanoid;
use rusqlite::{params, Connection};
use url::form_urlencoded;
// std
use std::collections::HashMap;
fn get_host(req: &Request
) -> Option {
let host = req.headers().get("host").map(|h| h.clone())?;
return Some(host);
}
fn welcome(req: Request) -> Response {
let _h = get_host(&req);
let host = _h.as_ref().map(|h| h.as_bytes()).unwrap_or(b"");
let text = format!(
"
This URL shortening service is powered by isostatic.
github.com/nerdypepper/isostatic
To shorten urls:
curl -F'shorten=https://shorten.some/long/url' {}\n",
String::from_utf8_lossy(host)
);
return Response::builder()
.header("content-type", "text/plain")
.body(Body::from(text))
.unwrap();
}
fn respond_with_shortlink>(shortlink: S, host: &[u8]) -> Response {
let url = [b"https://", host, b"/", shortlink.as_ref(), b"\n"].concat();
info!("Successfully generated shortlink");
Response::builder()
.status(StatusCode::OK)
.header("content-type", "text/html")
.body(Body::from(url))
.unwrap()
}
fn respond_with_status(s: StatusCode) -> Response {
Response::builder().status(s).body(Body::empty()).unwrap()
}
fn shorten>(url: S, conn: &mut Connection) -> Result {
let mut stmt = conn.prepare("select * from urls where link = ?1")?;
let mut rows = stmt.query(params![url.as_ref().to_string()])?;
if let Some(row) = rows.next()? {
return Ok(row.get(1)?);
} else {
let new_id = nanoid!(4);
conn.execute(
"insert into urls (link, shortlink) values (?1, ?2)",
params![url.as_ref().to_string(), new_id],
)?;
return Ok(new_id);
}
}
fn get_link>(url: S, conn: &Connection) -> Result