Merge pull request #7 from calcu1on/issue-6
Initial start of the route handling for DAM assets.
This commit is contained in:
commit
4e3306c5dd
@ -6,3 +6,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
base64 = "0.22.1"
|
||||
rand = "0.8"
|
||||
sqlite = "0.36.1"
|
||||
|
||||
15
public/404.html
Normal file
15
public/404.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!Doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Page Not Found</title>
|
||||
<style>
|
||||
body {
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Page cannot be found</h1>
|
||||
<h3>Sorry, this page cannot be found.</h3>
|
||||
</body>
|
||||
</html>
|
||||
117
src/connection.rs
Normal file
117
src/connection.rs
Normal file
@ -0,0 +1,117 @@
|
||||
use std::{
|
||||
fs,
|
||||
io::{prelude::*, BufReader},
|
||||
net::TcpStream,
|
||||
};
|
||||
|
||||
use crate::router;
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct IncomingRequest {
|
||||
req_type: String,
|
||||
path: String
|
||||
// headers: Vec<String>
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
pub fn handle_connection(mut stream: TcpStream) {
|
||||
// Create a new buffer reader with the stream data.
|
||||
let buf_reader = BufReader::new(&stream);
|
||||
// Store each line in a vector.
|
||||
let http_request: Vec<_> = buf_reader
|
||||
.lines()
|
||||
.map(|result| result.unwrap())
|
||||
.take_while(|line| !line.is_empty())
|
||||
.collect();
|
||||
// Get the first line of the stream which contains request data.
|
||||
let request_line: String = http_request.first().expect("Not a string").to_string();
|
||||
// Split the request data on spaces into a vector.
|
||||
let req_vec: Vec<&str> = request_line.split(" ").collect();
|
||||
println!("{:?}", http_request);
|
||||
let inc_request = IncomingRequest {
|
||||
req_type: req_vec[0].to_string(),
|
||||
path: req_vec[1].to_string(),
|
||||
};
|
||||
// Retrieve the api key from the request.
|
||||
let api_key: String = get_header(http_request, "x-api-key");
|
||||
let mut response = String::new();
|
||||
// If not a GET request, or missing API key, throw 404.
|
||||
if inc_request.req_type != "GET" || api_key.is_empty() {
|
||||
response = return_response("404");
|
||||
}
|
||||
else {
|
||||
// Get allowed api key from text file.
|
||||
let mut keyfile: Vec<String> = fs::read_to_string("./keys.txt").into_iter().collect();
|
||||
// Get the first item, for now. @todo make this more dynamic.
|
||||
keyfile[0].pop().expect("Keyfile not found").to_string();
|
||||
if api_key == keyfile[0] {
|
||||
// Here we need to look up the route by path.
|
||||
if inc_request.path.is_empty() {
|
||||
response = return_response("404");
|
||||
}
|
||||
else {
|
||||
response = return_response(&inc_request.path);
|
||||
}
|
||||
// response = return_response("200");
|
||||
} else {
|
||||
response = return_response("404");
|
||||
}
|
||||
}
|
||||
stream.write_all(response.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn get_api_key(headers: Vec<String>) -> String {
|
||||
let mut api_key = String::new();
|
||||
for header in headers {
|
||||
// split header, strip whitespace, check if exists.
|
||||
let split_header: Vec<&str> = header.split(":").collect();
|
||||
let header_key: String = split_header.first().expect("Nothing here").to_string();
|
||||
if header_key == "x-api-key" {
|
||||
api_key = split_header[1].to_string();
|
||||
}
|
||||
}
|
||||
api_key
|
||||
}
|
||||
|
||||
fn get_header(headers: Vec<String>, needle: &str) -> String {
|
||||
let mut value = String::new();
|
||||
for header in headers {
|
||||
let split_header: Vec<&str> = header.split(":").collect();
|
||||
let header_key: String = split_header.first().expect("Nothing here").to_string();
|
||||
if header_key == needle {
|
||||
value = split_header[1].to_string();
|
||||
}
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
fn return_response(path_or_code: &str) -> String {
|
||||
let status_line: String;
|
||||
let contents: String;
|
||||
|
||||
match path_or_code {
|
||||
"404" => {
|
||||
status_line = "HTTP/1.1 404 Not Found".to_string();
|
||||
contents = fs::read_to_string("./public/404.html").unwrap();
|
||||
},
|
||||
"200" => {
|
||||
status_line = "HTTP/1.1 200 OK".to_string();
|
||||
contents = fs::read_to_string("./public/200.json").unwrap();
|
||||
},
|
||||
&_ => {
|
||||
// Need to get the proper response based on the given path.
|
||||
let has_route = router::route_exists(path_or_code);
|
||||
if has_route {
|
||||
status_line = "HTTP/1.1 200 OK".to_string();
|
||||
contents = router::get_route_data(path_or_code);
|
||||
}
|
||||
else {
|
||||
status_line = "HTTP/1.1 404 Not Found".to_string();
|
||||
contents = fs::read_to_string("./public/404.html").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let length = contents.len();
|
||||
format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}")
|
||||
}
|
||||
89
src/main.rs
89
src/main.rs
@ -1,14 +1,7 @@
|
||||
use std::{
|
||||
fs,
|
||||
io::{prelude::*, BufReader},
|
||||
net::{TcpListener, TcpStream},
|
||||
};
|
||||
use std::net::TcpListener;
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct IncomingRequest {
|
||||
req_type: String,
|
||||
path: String
|
||||
}
|
||||
pub mod connection;
|
||||
mod router;
|
||||
|
||||
// Listen on port and return response.
|
||||
fn main() {
|
||||
@ -21,81 +14,7 @@ fn main() {
|
||||
|
||||
for stream in listener.incoming() {
|
||||
let stream = stream.unwrap();
|
||||
handle_connection(stream);
|
||||
connection::handle_connection(stream);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
fn handle_connection(mut stream: TcpStream) {
|
||||
let buf_reader = BufReader::new(&stream);
|
||||
let http_request: Vec<_> = buf_reader
|
||||
.lines()
|
||||
.map(|result| result.unwrap())
|
||||
.take_while(|line| !line.is_empty())
|
||||
.collect();
|
||||
|
||||
let request_line: String = http_request.first().expect("Not a string").to_string();
|
||||
let req_vec: Vec<&str> = request_line.split(" ").collect();
|
||||
let inc_request = IncomingRequest {
|
||||
req_type: req_vec[0].to_string(),
|
||||
path: req_vec[1].to_string(),
|
||||
};
|
||||
let api_key: String = get_api_key(http_request);
|
||||
let mut response = String::new();
|
||||
// If not a GET request, or missing API key, throw 404.
|
||||
if inc_request.req_type != "GET" || api_key.is_empty() {
|
||||
response = return_response("404");
|
||||
}
|
||||
else {
|
||||
let mut keyfile: Vec<String> = fs::read_to_string("./keys.txt").into_iter().collect();
|
||||
keyfile[0].pop().expect("Not a string").to_string();
|
||||
if api_key == keyfile[0] {
|
||||
response = return_response("200");
|
||||
} else {
|
||||
response = return_response("404");
|
||||
}
|
||||
}
|
||||
stream.write_all(response.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
// get the apy key from the headers.
|
||||
fn get_api_key(headers: Vec<String>) -> String {
|
||||
let mut api_key = String::new();
|
||||
|
||||
for header in headers {
|
||||
// split header, strip whitespace, check if exists.
|
||||
let split_header: Vec<&str> = header.split(":").collect();
|
||||
let header_key: String = split_header.first().expect("Nothing here").to_string();
|
||||
if header_key == "x-api-key" {
|
||||
api_key = split_header[1].to_string();
|
||||
}
|
||||
}
|
||||
|
||||
api_key
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
fn return_response(code: &str) -> String {
|
||||
let mut response = String::new();
|
||||
match code {
|
||||
"404" => {
|
||||
let status_line = "HTTP/1.1 404 Not Found";
|
||||
let contents = fs::read_to_string("./public/404.json").unwrap();
|
||||
let length = contents.len();
|
||||
|
||||
response =
|
||||
format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
|
||||
},
|
||||
"200" => {
|
||||
let status_line = "HTTP/1.1 200 OK";
|
||||
let contents = fs::read_to_string("./public/200.json").unwrap();
|
||||
let length = contents.len();
|
||||
|
||||
response =
|
||||
format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
|
||||
},
|
||||
&_ => todo!()
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
38
src/router.rs
Normal file
38
src/router.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn get_route_data(route: &str) -> String {
|
||||
let route_data: String;
|
||||
match route {
|
||||
"/fetch" => {
|
||||
route_data = fetch_asset();
|
||||
}
|
||||
&_ => todo!(),
|
||||
}
|
||||
route_data
|
||||
}
|
||||
|
||||
pub fn route_exists(route: &str) -> bool {
|
||||
let existing_routes = get_routes();
|
||||
if existing_routes.contains_key(route) {
|
||||
true
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn get_routes() -> HashMap<String, String> {
|
||||
let mut routes = HashMap::new();
|
||||
routes.insert("/fetch".to_string(), "fetch_asset".to_string());
|
||||
routes
|
||||
}
|
||||
|
||||
fn fetch_asset() -> String {
|
||||
let asset = r#"{
|
||||
"title": "this is a title",
|
||||
"id": 2,
|
||||
"url": "https://www.espn.com
|
||||
}"#;
|
||||
|
||||
asset.to_string()
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user