moved src/http.rs to src/http/mod.rs
This commit is contained in:
218
src/http.rs
218
src/http.rs
@ -1,218 +0,0 @@
|
||||
mod consts;
|
||||
mod parser;
|
||||
mod handler;
|
||||
|
||||
use std::net::TcpStream;
|
||||
use openssl::ssl::SslStream;
|
||||
use std::io::{Write, Read};
|
||||
use std::fmt::Formatter;
|
||||
|
||||
pub use handler::*;
|
||||
|
||||
static REQUESTS_PER_CONNECTION: u32 = 200;
|
||||
|
||||
pub enum Stream {
|
||||
Tcp(TcpStream),
|
||||
Ssl(SslStream<TcpStream>),
|
||||
}
|
||||
|
||||
pub struct HttpStream {
|
||||
stream: Stream,
|
||||
request_num: u32,
|
||||
}
|
||||
|
||||
pub enum Method {
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
HEAD,
|
||||
TRACE,
|
||||
CONNECT,
|
||||
DELETE,
|
||||
OPTIONS,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl Method {
|
||||
pub fn from_str(v: &str) -> Method {
|
||||
match v {
|
||||
"GET" => Method::GET,
|
||||
"POST" => Method::POST,
|
||||
"PUT" => Method::PUT,
|
||||
"HEAD" => Method::HEAD,
|
||||
"TRACE" => Method::TRACE,
|
||||
"CONNECT" => Method::CONNECT,
|
||||
"DELETE" => Method::DELETE,
|
||||
"OPTIONS" => Method::OPTIONS,
|
||||
_ => Method::Custom(String::from(v)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_str(&self) -> &str {
|
||||
match self {
|
||||
Method::GET => "GET",
|
||||
Method::POST => "POST",
|
||||
Method::PUT => "PUT",
|
||||
Method::HEAD => "HEAD",
|
||||
Method::TRACE => "TRACE",
|
||||
Method::CONNECT => "CONNECT",
|
||||
Method::DELETE => "DELETE",
|
||||
Method::OPTIONS => "OPTIONS",
|
||||
Method::Custom(v) => v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Method {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum StatusClass {
|
||||
Informational,
|
||||
Success,
|
||||
Redirection,
|
||||
ClientError,
|
||||
ServerError,
|
||||
}
|
||||
|
||||
impl StatusClass {
|
||||
pub fn from_code(status_code: u16) -> StatusClass {
|
||||
for (code, class, _msg, _desc) in &consts::HTTP_STATUSES {
|
||||
if *code == status_code {
|
||||
return class.clone();
|
||||
}
|
||||
}
|
||||
match status_code {
|
||||
100..=199 => StatusClass::Informational,
|
||||
200..=299 => StatusClass::Success,
|
||||
300..=399 => StatusClass::Redirection,
|
||||
400..=499 => StatusClass::ClientError,
|
||||
500..=599 => StatusClass::ServerError,
|
||||
_ => panic!("invalid status code")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Status {
|
||||
code: u16,
|
||||
message: String,
|
||||
class: StatusClass,
|
||||
}
|
||||
|
||||
impl Status {
|
||||
pub fn from_code(status_code: u16) -> Status {
|
||||
for (code, class, msg, _desc) in &consts::HTTP_STATUSES {
|
||||
if *code == status_code {
|
||||
return Status {
|
||||
code: status_code,
|
||||
message: msg.to_string(),
|
||||
class: class.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
panic!("invalid status code");
|
||||
}
|
||||
|
||||
pub fn new_custom(status_code: u16, message: &str) -> Status {
|
||||
if status_code < 100 || status_code > 599 {
|
||||
panic!("invalid status code");
|
||||
}
|
||||
Status {
|
||||
code: status_code,
|
||||
message: message.to_string(),
|
||||
class: StatusClass::from_code(status_code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct HeaderField {
|
||||
name: String,
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for HeaderField {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "[{}: {}]", self.name, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Request {
|
||||
version: String,
|
||||
method: Method,
|
||||
uri: String,
|
||||
header_fields: Vec<HeaderField>
|
||||
}
|
||||
|
||||
pub struct Response {
|
||||
version: String,
|
||||
status: Status,
|
||||
header_fields: Vec<HeaderField>
|
||||
}
|
||||
|
||||
impl Response {
|
||||
fn new() -> Response {
|
||||
Response {
|
||||
version: "1.1".to_string(),
|
||||
status: Status::from_code(200),
|
||||
header_fields: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_header(&mut self, name: &str, value: &str) {
|
||||
self.header_fields.push(HeaderField {
|
||||
name: String::from(name),
|
||||
value: String::from(value),
|
||||
});
|
||||
}
|
||||
|
||||
fn send(&self, stream: &mut Stream) -> Result<(), std::io::Error> {
|
||||
let mut header = format!("HTTP/{} {:03} {}\r\n", self.version, self.status.code, self.status.message);
|
||||
for header_field in &self.header_fields {
|
||||
header.push_str(format!("{}: {}\r\n", header_field.name, header_field.value).as_str());
|
||||
}
|
||||
header.push_str("\r\n");
|
||||
stream.write_all(header.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream {
|
||||
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
|
||||
match self {
|
||||
Stream::Tcp(stream) => stream.read(buf),
|
||||
Stream::Ssl(stream) => stream.read(buf),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), std::io::Error> {
|
||||
match self {
|
||||
Stream::Tcp(stream) => stream.read_exact(buf),
|
||||
Stream::Ssl(stream) => stream.read_exact(buf),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peek(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
|
||||
match self {
|
||||
Stream::Tcp(stream) => stream.peek(buf),
|
||||
Stream::Ssl(_stream) => todo!("Not implemented in rust-openssl"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
|
||||
match self {
|
||||
Stream::Tcp(stream) => stream.write(buf),
|
||||
Stream::Ssl(stream) => stream.write(buf),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
|
||||
match self {
|
||||
Stream::Tcp(stream) => stream.write_all(buf),
|
||||
Stream::Ssl(stream) => stream.write_all(buf),
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user