学习Rust编程——hyper服务器端API构建一个短网址服务

发布一下 0 0
[dependencies]hyper = "0.12"serde_json = "1.0.96"futures = "0.1.31"lazy_static = "1.4.0"rust-crypto = "0.2.36"pretty_env_logger = "0.5"log = "0.4"
// hyperurl/src/index.rspub static INDEX_PAGE: &str = r##"<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <meta http-equiv="X-UA-Compatible" content="ie=edge">    <title>hyperurl - A url shortener in Rust</title>    <style> body { text-align: center;} </style></head><body><h3>hyperurl - A url shortening service</h3>    <p>To shorten a url, make a post request using curl as:</p>    <p><code>curl --data "https://creativcoder.github.io" http://localhost:3002/shorten</code></p>    <p>You will get a reply as:</p>    <p>{    "127.0.0.1:3002/992a7": "https://creativcoder.github.io"    }</p>    <p>Put the shortened url (127.0.0.1:3002/992a7) in the browser to get redirected to the original website.</p>    <p>Made with ❤ with hyper in Rust</p></body></html>"##;
// hyperurl/src/service.rsuse std::sync::RwLock;use std::collections::HashMap;use std::sync::{Arc};use std::str;use hyper::Request;use hyper::{Body, Response};use hyper::rt::{Future, Stream};use hyper::Method;use hyper::StatusCode;use lazy_static::lazy_static;use log::info;use crate::shortener::shorten_url;use futures::future;use crate::index::INDEX_PAGE;use crate::LISTEN_ADDR;type UrlDb = Arc<RwLock<HashMap<String, String>>>;type BoxFut = Box<dyn Future<Item = Response<Body>, Error = hyper::Error> + Send>;lazy_static! {    static ref SHORT_URLS: UrlDb = Arc::new(RwLock::new(HashMap::new()));}pub(crate) fn url_service(req: Request<Body>) -> BoxFut {        match (req.method(), req.uri().path()) {        (&Method::GET, "/") => {            let reply = Response::new(Body::from(format!("{}",INDEX_PAGE)));            Box::new(future::ok(reply))        }        (&Method::GET, _) => {            let url_db = SHORT_URLS.read().unwrap();            let uri = req.uri().to_string();            let short_url = format!("{}{}", LISTEN_ADDR, uri);            let long_url = url_db.get(&short_url);            println!("LONG URL {:?}",long_url);            let reply = match long_url {                Some(url) => {                    info!("Redirecting from {} to {}", short_url, url);                    Response::builder().status(StatusCode::TEMPORARY_REDIRECT)                    .header("Location", url.to_string()).body(Body::empty()).unwrap()                }                None => {                    Response::builder()                    .status(StatusCode::NOT_FOUND)                    .body(Body::from(format!("Bad URI: {:?}", uri))).unwrap()                }            };            Box::new(future::ok(reply))        }        (&Method::POST, "/shorten") => {            info!("Received request from : {:?}", req.headers());            let reply = req.into_body().concat2().map(move |chunk| {                let c = chunk.iter().cloned().collect::<Vec<u8>>();                let url_to_shorten = str::from_utf8(&c).unwrap();                let short_url = shorten_url(url_to_shorten);                let reply = Response::new(Body::from(format!("{}", &short_url)));                SHORT_URLS.write().unwrap().insert(short_url, url_to_shorten.to_string());                reply            });            Box::new(reply)        }        (_, _) => {            let no_route = Response::new(Body::from("No route handler for this path"));            Box::new(future::ok(no_route))        }    }}
// hyperurl/src/shortener.rsuse crypto::digest::Digest;use crypto::sha2::Sha256;use crate::LISTEN_ADDR;pub(crate) fn shorten_url(url: &str) -> String {    let mut sha = Sha256::new();    sha.input_str(url);    let mut s = sha.result_str();    s.truncate(5);    format!("{}/{}", LISTEN_ADDR, s)}
// hyperurl/src/main.rsuse log::{info, error};use std::env;use hyper::Server;use hyper::service::service_fn;use hyper::rt::{self, Future};mod shortener;mod service;mod index;use crate::service::url_service;const LISTEN_ADDR: &str = "127.0.0.1:3002";fn main() {    env::set_var("RUST_LOG","hyperurl=info");    pretty_env_logger::init();    let addr = LISTEN_ADDR.parse().unwrap();    let server = Server::bind(&addr)        .serve(|| service_fn(url_service))        .map_err(|e| error!("server error: {}", e));    info!("hyperurl is listening at {}", addr);    rt::run(server);}

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/210722.html