Skip to content

Instantly share code, notes, and snippets.

@gkbrk
Created October 26, 2015 13:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save gkbrk/40aa741ad744b46449bf to your computer and use it in GitHub Desktop.
Save gkbrk/40aa741ad744b46449bf to your computer and use it in GitHub Desktop.
[package]
name = "urlshortener"
version = "0.1.0"
authors = ["Gökberk Yaltıraklı <webdosusb@gmail.com>"]
[dependencies]
nickel = "*"
hyper = "*"
rand = "0.3.11"
[dependencies.url]
git = "https://github.com/servo/rust-url"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Rust URL Shortener</title>
<link rel="stylesheet" href="static/style.css">
</head>
<body>
<h2>Rust URL Shortener</h2>
<h3>{{result}}</h3>
<form action="/shorten" method="POST">
<input type="text" name="url" style="width: 35em;" />
<input type="submit" value="Shorten!" />
</form>
<br><p>{{url_count}} URLs shortened</p>
</body>
</html>
#[macro_use] extern crate nickel;
extern crate hyper;
extern crate url;
extern crate rand;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::io::Read;
use rand::Rng;
use nickel::{Nickel, HttpRouter, Mount, StaticFilesHandler};
use nickel::status::StatusCode;
use hyper::header::Location;
use hyper::Url;
use url::form_urlencoded;
fn main() {
let server_url = "http://url.gkbrk.com";
let mut server = Nickel::new();
let short_urls = Arc::new(Mutex::new(HashMap::new()));
short_urls.lock().unwrap().insert("rust".to_string(), "https://www.rust-lang.org".to_string());
let short_urls_clone = short_urls.clone();
server.get("/", middleware! {|_, response|
let mut data = HashMap::new();
let short_urls = short_urls_clone.lock().unwrap();
data.insert("url_count", short_urls.len().to_string());
return response.render("templates/index.tpl", &data);
});
let short_urls_clone = short_urls.clone();
server.post("/shorten", middleware! {|request, response|
let mut data = HashMap::new();
let mut short_urls = short_urls_clone.lock().unwrap();
data.insert("url_count", short_urls.len().to_string());
let mut post_data = String::new();
request.origin.read_to_string(&mut post_data).unwrap();
let form = parse_form(post_data.as_bytes());
let url = form.get("url").unwrap_or(&"".to_string()).to_string();
if url != "" {
if Url::parse(&url).is_ok() { //Check if the URL is valid.
//shorten url
let mut key = generate_random_string(8);
while short_urls.contains_key(&key) { //Make sure key doesn't exist
key = generate_random_string(8);
}
short_urls.insert(key.clone(), url);
data.insert("result", format!("Here is your short URL: {}/{}", server_url, &key));
}else {
data.insert("result", "Invalid URL".to_string());
}
}else {
data.insert("result", "You need to enter a URL.".to_string());
}
return response.render("templates/index.tpl", &data);
});
let short_urls_clone = short_urls.clone();
server.get("/:shortkey", middleware! {|request, mut response|
let short_urls = short_urls_clone.lock().unwrap();
let shortkey = request.param("shortkey").unwrap();
if short_urls.contains_key(shortkey) {
let url = short_urls.get(shortkey).unwrap();
response.set(StatusCode::TemporaryRedirect);
response.set(Location(url.clone()));
return response.send("");
}else {
return response.send("Short URL not found");
}
});
//Serve static_files/ from /static/
server.utilize(Mount::new("/static/", StaticFilesHandler::new("static_files/")));
server.listen("127.0.0.1:1111");
}
fn generate_random_string(size: usize) -> String {
return rand::thread_rng().gen_ascii_chars().take(size).collect();
}
fn parse_form(form_data: &[u8]) -> HashMap<String, String> {
let mut hashmap = HashMap::new();
let parsed_form = form_urlencoded::parse(form_data);
for (key, value) in parsed_form {
hashmap.insert(key, value);
}
return hashmap;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment