Expand description
§fastcgi-client-rs
Runtime-agnostic Fastcgi client implemented for Rust.
The client is built on the futures-io
AsyncRead / AsyncWrite traits and contains no task spawning, timers or
socket creation, so it works with any async runtime, and even with no runtime at
all.
§Installation
No cargo feature is required:
cargo add fastcgi-clientAny stream implementing the futures-io traits works out of the box, for
example smol or
async-net:
cargo add smolTokio defines its own I/O traits, so its streams need a compatibility wrapper.
Enable the optional tokio feature to get convenience constructors that do the
wrapping for you:
cargo add fastcgi-client --features tokio
cargo add tokio --features fullWithout the tokio feature you can still use Tokio by bridging the stream
yourself with tokio-util:
use fastcgi_client::Client;
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncReadCompatExt;
#[tokio::main]
async fn main() {
let stream = TcpStream::connect(("127.0.0.1", 9000)).await.unwrap();
let _client = Client::new(stream.compat());
}§Examples
Short connection mode:
use fastcgi_client::{io, Client, Params, Request};
use std::env;
smol::block_on(async {
let script_filename = env::current_dir()
.unwrap()
.join("tests")
.join("php")
.join("index.php");
let script_filename = script_filename.to_str().unwrap();
let script_name = "/index.php";
// Connect to php-fpm default listening address.
let stream = smol::net::TcpStream::connect(("127.0.0.1", 9000))
.await
.unwrap();
let client = Client::new(stream);
// Fastcgi params, please reference to nginx-php-fpm config.
let params = Params::default()
.request_method("GET")
.script_name(script_name)
.script_filename(script_filename)
.request_uri(script_name)
.document_uri(script_name)
.remote_addr("127.0.0.1")
.remote_port(12345)
.server_addr("127.0.0.1")
.server_port(80)
.server_name("jmjoy-pc")
.content_type("")
.content_length(0);
// Fetch fastcgi server(php-fpm) response.
let output = client
.execute_once(Request::new(params, io::empty()))
.await
.unwrap();
// "Content-type: text/html; charset=UTF-8\r\n\r\nhello"
let stdout = String::from_utf8(output.stdout.unwrap()).unwrap();
assert!(stdout.contains("Content-type: text/html; charset=UTF-8"));
assert!(stdout.contains("hello"));
assert_eq!(output.stderr, None);
});Keep alive mode:
use fastcgi_client::{io, Client, Params, Request};
smol::block_on(async {
// Connect to php-fpm default listening address.
let stream = smol::net::TcpStream::connect(("127.0.0.1", 9000))
.await
.unwrap();
let mut client = Client::new_keep_alive(stream);
// Fastcgi params, please reference to nginx-php-fpm config.
let params = Params::default();
for _ in 0..3 {
// Fetch fastcgi server(php-fpm) response.
let output = client
.execute(Request::new(params.clone(), io::empty()))
.await
.unwrap();
// "Content-type: text/html; charset=UTF-8\r\n\r\nhello"
let stdout = String::from_utf8(output.stdout.unwrap()).unwrap();
assert!(stdout.contains("Content-type: text/html; charset=UTF-8"));
assert!(stdout.contains("hello"));
assert_eq!(output.stderr, None);
}
});With the tokio feature, Client::new_tokio and Client::new_keep_alive_tokio
accept Tokio streams directly:
use fastcgi_client::{io, Client, Params, Request};
use tokio::net::TcpStream;
#[tokio::main]
async fn main() {
// Short connection mode.
let stream = TcpStream::connect(("127.0.0.1", 9000)).await.unwrap();
let client = Client::new_tokio(stream);
let output = client
.execute_once(Request::new(Params::default(), io::empty()))
.await
.unwrap();
assert!(String::from_utf8(output.stdout.unwrap()).unwrap().contains("hello"));
// Keep alive mode.
let stream = TcpStream::connect(("127.0.0.1", 9000)).await.unwrap();
let mut client = Client::new_keep_alive_tokio(stream);
for _ in 0..3 {
let output = client
.execute(Request::new(Params::default(), io::empty()))
.await
.unwrap();
assert!(String::from_utf8(output.stdout.unwrap()).unwrap().contains("hello"));
}
}Runnable versions of every flow, including response streaming and an Axum
HTTP-to-FastCGI proxy, live under
examples/.
§Optional HTTP conversions
Enable the http feature if you want to convert between this crate’s FastCGI
types and the http crate.
fastcgi-client = { version = "0.12", features = ["http"] }The conversion boundary is intentionally split in two:
Request<'a, I>can convert intohttp::Request<I>without buffering the body.http::Request<I>can convert back into FastCGI metadata, but CGI-only params such asSCRIPT_FILENAMEmust be supplied explicitly through extraParams.Responsecan be parsed intohttp::Response<Vec<u8>>;stderrremains available only on the original FastCGI response.
§License
Re-exports§
pub use crate::client::Client;pub use crate::params::Params;pub use crate::request::Request;pub use crate::response::Response;
Modules§
- client
- FastCGI client implementation for async communication with FastCGI servers.
- conn
- Connection mode markers for
Client. - io
- Runtime-neutral async I/O facade used by the FastCGI client.
- params
- FastCGI parameters builder and container.
- request
- FastCGI request structure and builders.
- response
- FastCGI response types and streaming support.
Enums§
- Client
Error - Error types that can occur during FastCGI communication.
- Http
Conversion Error http - Error types that can occur while converting between FastCGI and HTTP types.
Traits§
- Stream
Ext - Re Export StreamExt for .next support
An extension trait for
Streams that provides a variety of convenient combinator functions.
Type Aliases§
- Client
Result - Result type alias for FastCGI client operations.
- Http
Conversion Result http - Result type alias for HTTP/FastCGI conversion operations.