Compare commits
10 Commits
cb2be6774d
...
92075763db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92075763db | ||
|
|
4e3306c5dd | ||
|
|
f47ebb8633 | ||
|
|
3c66a6b6bc | ||
|
|
d1ac420503 | ||
|
|
c5e38f29a1 | ||
|
|
56cca06199 | ||
|
|
4b019c85d1 | ||
|
|
7c58f9db51 | ||
|
|
411efe5276 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ Cargo.lock
|
|||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
keys.txt
|
||||||
|
|
||||||
# Added by cargo
|
# Added by cargo
|
||||||
|
|
||||||
|
|||||||
@ -4,3 +4,6 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
base64 = "0.22.1"
|
||||||
|
rand = "0.8"
|
||||||
|
sqlite = "0.36.1"
|
||||||
|
|||||||
BIN
public/.DS_Store
vendored
Normal file
BIN
public/.DS_Store
vendored
Normal file
Binary file not shown.
35002
public/200.json
35002
public/200.json
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,15 @@
|
|||||||
<!Doctype html>
|
<!Doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Page Not Found | Hermes</title>
|
<title>Page Not Found</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: orange;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>The requested page could not be found.</p>
|
<h1>Page cannot be found</h1>
|
||||||
|
<h3>Sorry, this page cannot be found.</h3>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
2
public/assets/main.js
Normal file
2
public/assets/main.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
let body = document.getElementsByTagName('h1');
|
||||||
|
console.log(body);
|
||||||
4
public/assets/style.css
Normal file
4
public/assets/style.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
body {
|
||||||
|
color: white;
|
||||||
|
background: purple;
|
||||||
|
}
|
||||||
BIN
public/images/6.jpg
Normal file
BIN
public/images/6.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
12
public/index.html
Normal file
12
public/index.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Toolshed</title>
|
||||||
|
<link rel="stylesheet" href="/assets/style.css">
|
||||||
|
<script src="/assets/main.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>This is my toolshed. This web server is built using Rust :)</h1>
|
||||||
|
<img src="/images/6.jpg"/>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
16
public/pages/about.html
Normal file
16
public/pages/about.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!Doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>About</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: purple;
|
||||||
|
padding: 20px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>This is the about page!</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
82
src/connection.rs
Normal file
82
src/connection.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
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("No request line found").to_string();
|
||||||
|
let response: String;
|
||||||
|
// Split the request data on spaces into a vector.
|
||||||
|
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(),
|
||||||
|
};
|
||||||
|
if inc_request.path.is_empty() {
|
||||||
|
response = return_response("404");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
response = return_response(&inc_request.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.write_all(response.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
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/index.html").unwrap();
|
||||||
|
},
|
||||||
|
&_ => {
|
||||||
|
// Need to get the proper response based on the given path.
|
||||||
|
status_line = "HTTP/1.1 200 OK".to_string();
|
||||||
|
contents = router::get_route_data(path_or_code);
|
||||||
|
// status_line = "HTTP/1.1 404 Not Found".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let length = contents.len();
|
||||||
|
format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}")
|
||||||
|
}
|
||||||
92
src/main.rs
92
src/main.rs
@ -1,92 +1,20 @@
|
|||||||
use std::{
|
use std::net::TcpListener;
|
||||||
fs,
|
|
||||||
io::{prelude::*, BufReader},
|
|
||||||
net::{TcpListener, TcpStream},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub mod connection;
|
||||||
struct IncomingRequest {
|
mod router;
|
||||||
req_type: String,
|
|
||||||
path: String
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen on port and return response.
|
// Listen on port and return response.
|
||||||
fn main() {
|
fn main() {
|
||||||
let listener = TcpListener::bind("164.92.85.112:7878").unwrap();
|
let run_local = true;
|
||||||
|
let mut listener = TcpListener::bind("127.0.0.1:6942").unwrap();
|
||||||
|
|
||||||
|
if !run_local {
|
||||||
|
listener = TcpListener::bind("0.0.0.0:6942").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
let stream = stream.unwrap();
|
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_404();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Check that the API key is in fact fact valuid.
|
|
||||||
// Not really checking right now.
|
|
||||||
response = return_200();
|
|
||||||
}
|
|
||||||
// If not present, return 404.
|
|
||||||
// Perhaps move both of those conditions to a new function.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a 404.
|
|
||||||
fn return_404() -> String {
|
|
||||||
let status_line = "HTTP/1.1 404 Not Found";
|
|
||||||
let contents = fs::read_to_string("./public/404.html").unwrap();
|
|
||||||
let length = contents.len();
|
|
||||||
|
|
||||||
let response =
|
|
||||||
format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
|
|
||||||
|
|
||||||
response
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a 200 with the json.
|
|
||||||
fn return_200() -> String {
|
|
||||||
let status_line = "HTTP/1.1 200 OK";
|
|
||||||
let contents = fs::read_to_string("./public/200.json").unwrap();
|
|
||||||
let length = contents.len();
|
|
||||||
|
|
||||||
let response =
|
|
||||||
format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
|
|
||||||
|
|
||||||
response
|
|
||||||
}
|
|
||||||
|
|||||||
32
src/router.rs
Normal file
32
src/router.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
pub fn get_route_data(route: &str) -> String {
|
||||||
|
let route_data: String;
|
||||||
|
match route {
|
||||||
|
"/" => {
|
||||||
|
route_data = fs::read_to_string("./public/index.html").unwrap();
|
||||||
|
},
|
||||||
|
"/about" => {
|
||||||
|
route_data = fs::read_to_string("./public/pages/about.html").unwrap();
|
||||||
|
}
|
||||||
|
&_ => {
|
||||||
|
let mut public_path: String = "./public".to_string();
|
||||||
|
if path_exists(&public_path) {
|
||||||
|
if public_path.contains("images") {
|
||||||
|
route_data = fs::read(public_path).unwrap();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
route_data = fs::read_to_string(public_path).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
route_data = fs::read_to_string("./public/404.html").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
route_data
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path_exists(path: &str) -> bool {
|
||||||
|
fs::metadata(path).is_ok()
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user