M Cargo.lock => Cargo.lock +1 -1
@@ 649,7 649,7 @@ dependencies = [
[[package]]
name = "tokio-scgi"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)",
M Cargo.toml => Cargo.toml +2 -2
@@ 1,6 1,6 @@
[package]
name = "tokio-scgi"
-version = "0.1.0"
+version = "0.2.0"
authors = ["Nick Parker <nick@nickbp.com>"]
license = "MIT"
edition = "2018"
@@ 9,9 9,9 @@ description = "Tokio codec for building and parsing SCGI requests"
repository = "https://github.com/nickbp/tokio-scgi"
[dependencies]
+bytes = "0.4.12"
tokio = "=0.2.0-alpha.1"
tokio-codec = "=0.2.0-alpha.1"
-bytes = "0.4.12"
[dev-dependencies]
proptest = "0.9.4"
M examples/client.rs => examples/client.rs +12 -5
@@ 50,7 50,9 @@ async fn main() -> Result<(), Error> {
/// Runs the client: Sends a request and prints the responses via the provided UDS or TCP connection.
async fn run_client<C>(conn: &mut C) -> Result<(), Error>
-where C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::fmt::Debug {
+where
+ C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::fmt::Debug,
+{
let (mut tx_scgi, mut rx_scgi) = Framed::new(conn, SCGICodec::new()).split();
// Send request
@@ 64,14 66,14 @@ where C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::
// Shouldn't happen for response data, but this is how it would work...
println!("Response data is incomplete, resuming read");
rx_scgi = new_rx;
- },
+ }
(Some(Err(e)), _new_rx) => {
// RX error: return error and abort
return Err(Error::new(
ErrorKind::Other,
format!("Error when waiting for response: {}", e),
));
- },
+ }
(Some(Ok(response)), new_rx) => {
// Got SCGI response: if empty, treat as end of response.
if response.len() == 0 {
@@ 81,9 83,14 @@ where C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::
rx_scgi = new_rx;
match String::from_utf8(response.to_vec()) {
Ok(s) => println!("Got {} bytes:\n{}", response.len(), s),
- Err(e) => println!("{} byte response is not UTF8 ({}):\n{:?}", response.len(), e, response)
+ Err(e) => println!(
+ "{} byte response is not UTF8 ({}):\n{:?}",
+ response.len(),
+ e,
+ response
+ ),
}
- },
+ }
}
}
}
M examples/server.rs => examples/server.rs +23 -12
@@ 40,8 40,12 @@ async fn main() -> Result<(), std::io::Error> {
let (conn, _addr) = bind.accept().await?;
tokio::spawn(async move {
match serve(conn).await {
- Err(e) =>{ println!("Error serving UDS session: {:?}", e); }
- Ok(()) => { println!("Served UDS request"); }
+ Err(e) => {
+ println!("Error serving UDS session: {:?}", e);
+ }
+ Ok(()) => {
+ println!("Served UDS request");
+ }
};
});
}
@@ 52,8 56,12 @@ async fn main() -> Result<(), std::io::Error> {
let (conn, addr) = bind.accept().await?;
tokio::spawn(async move {
match serve(conn).await {
- Err(e) => { println!("Error when serving TCP session from {:?}: {:?}", addr, e); }
- Ok(()) => { println!("Served TCP request from {:?}", addr); }
+ Err(e) => {
+ println!("Error when serving TCP session from {:?}: {:?}", addr, e);
+ }
+ Ok(()) => {
+ println!("Served TCP request from {:?}", addr);
+ }
};
});
}
@@ 117,7 125,9 @@ macro_rules! http_response {
}
async fn serve<C>(conn: C) -> Result<(), Error>
-where C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::fmt::Debug {
+where
+ C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::fmt::Debug,
+{
let mut handler = SampleHandler::new();
let (mut tx_scgi, mut rx_scgi) = Framed::new(conn, SCGICodec::new()).split();
@@ 127,31 137,32 @@ where C: AsyncRead + AsyncWrite + std::marker::Send + std::marker::Unpin + std::
// SCGI request not ready: loop for more rx data
println!("Request read returned None, resuming read");
rx_scgi = new_rx;
- },
+ }
(Some(Err(e)), _new_rx) => {
// RX error: return error and abort
return Err(Error::new(
ErrorKind::Other,
format!("Error when waiting for request: {}", e),
));
- },
- (Some(Ok(request)), new_rx) =>
+ }
+ (Some(Ok(request)), new_rx) => {
// Got SCGI request: pass to handler
match handler.handle(request) {
Ok(Some(r)) => {
// Response ready: send and exit
return tx_scgi.send(r).await;
- },
+ }
Ok(None) => {
// Response not ready: loop for more rx data
println!("Request data is incomplete, resuming read");
rx_scgi = new_rx;
- },
+ }
Err(e) => {
// Handler error: respond with formatted error message
return tx_scgi.send(handle_error(e)).await;
}
- },
+ }
+ }
}
}
}
@@ 281,7 292,7 @@ fn build_response(headers: &Vec<(String, String)>, body: &BytesMut) -> Vec<u8> {
// Printable content with minimal effort at avoiding HTML injection:
Ok(s) => format!("{}", s.replace('<', "<").replace('>', ">")),
// Not printable content, fall back to printing as list of dec codes:
- Err(_e) => format!("{:?}", body.to_vec())
+ Err(_e) => format!("{:?}", body.to_vec()),
};
let content = format!(
"<html><head><title>scgi-sample-server</title></head><body>