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

[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.rs

pub static INDEX_PAGE: &str = r##"



    
    
    
    hyperurl - A url shortener in Rust
    


hyperurl - A url shortening service

To shorten a url, make a post request using curl as:

curl --data "https://creativcoder.github.io" http://localhost:3002/shorten

You will get a reply as:

{ "127.0.0.1:3002/992a7": "https://creativcoder.github.io" }

Put the shortened url (127.0.0.1:3002/992a7) in the browser to get redirected to the original website.

Made with with hyper in Rust

"##;
// hyperurl/src/service.rs

use 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>>;
type BoxFut = Box, Error = hyper::Error> + Send>;

lazy_static! {
    static ref SHORT_URLS: UrlDb = Arc::new(RwLock::new(HashMap::new()));
}

pub(crate) fn url_service(req: Request) -> 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::>();
                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.rs

use 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.rs

use 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);
}
展开阅读全文

页面更新:2024-02-22

标签:服务器端   网址

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top