#![warn(clippy::all)]
#![allow(clippy::suspicious_else_formatting)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![warn(missing_docs)]
#![warn(future_incompatible)]
pub mod header;
pub mod method;
pub mod path;
pub mod request;
pub mod response;
pub mod status;
pub mod version;
use
{
crate::
{
request::
{
Request,
},
response::
{
Response,
},
status::
{
Status,
},
},
async_std::
{
io::
{
Error,
},
net::
{
SocketAddr,
TcpListener,
ToSocketAddrs,
},
prelude::*,
sync::
{
Arc,
},
task::
{
spawn,
},
},
std::
{
fmt::
{
Display,
},
},
};
pub struct Configuration
{
pub address: SocketAddr,
pub maxContent: usize,
pub maxHeaderEntries: usize,
pub maxHeaderLength: usize,
pub maxPathLength: usize,
pub maxQueryLength: usize,
}
#[macro_export]
macro_rules! content
{
(
$Type:expr,
$Path:expr
)
=> {
http_async::Content
(
http_async::status::Status::Ok,
$Type,
include_bytes! ( $Path )
.to_vec(),
)
};
}
pub struct Content
{
statusCode: Status,
contentType: &'static str,
contentBody: Vec < u8 >,
}
pub fn Content
(
statusCode: Status,
contentType: &'static str,
contentBody: Vec < u8 >,
)
-> Content
{
Content
{
statusCode,
contentType,
contentBody,
}
}
#[derive(Debug)]
pub struct KeyValuePair
{
pub key: String,
pub value: String,
}
pub async fn server
<
Address,
Data,
Handler,
>
(
address: Address,
this: Arc < Data >,
handler: Arc < Handler >,
)
-> Result
<
(),
Error,
>
where
Address: ToSocketAddrs + Display + Send + Sync + Clone + 'static,
Data: Send + Sync + 'static,
Handler: Send + Sync + 'static +
Fn
(
Request,
Arc < Data >,
)
-> Response,
{
let socket
= TcpListener::bind ( &address )
.await
.expect ( "Failed to bind" );
println!
(
"Waiting for connections on {}",
address,
);
loop
{
let this = this.clone ( );
let handler = handler.clone ( );
let address = address.clone ( );
let
(
mut tcpStream,
client
)
= socket
.accept()
.await
.unwrap();
spawn
(
async move
{
let mut counter = 0;
loop
{
match Request()
.parse
(
&mut tcpStream,
).await
{
Ok ( request )
=> match match tcpStream
.write
(
handler
(
request,
this.clone(),
)
.into_vector ( )
.as_slice ( )
)
.await
{
Ok ( _ )
=> tcpStream
.flush().await,
Err ( error )
=> Err ( error ),
}
{
Ok ( _ )
=> println!
(
"Success! {} -> {} #{}",
address,
client,
counter,
),
Err ( error )
=> {
eprintln!
(
"Send Fail: {}",
error,
);
break;
},
},
Err ( error )
=> {
eprintln!
(
"Input Fail: {}",
error,
);
break;
}
}
counter += 1;
}
}
);
}
}