cgi2

Crates.iocgi2
lib.rscgi2
version0.7.0
sourcesrc
created_at2023-12-28 19:04:48.115414
updated_at2023-12-28 19:04:48.115414
descriptionCreate CGI programmes
homepage
repositoryhttps://github.com/badboy/rust-cgi
max_upload_size
id1082614
size56,720
Engine Devs (github:amethyst:engine-devs)

documentation

README

= rust-cgi

Easily create CGIfootnote:[Retro!]footnote:[Common Gateway Interface 1.1, RFC 3875] programmesfootnote:[Yes, I'm spelling it programme, the correct way.] in Rust based on link:https://github.com/hyperium/http[`http` types].

image::https://img.shields.io/crates/v/cgi2.svg?style=flat[crates.io released version badge] image::https://img.shields.io/crates/l/cgi2.svg?style=flat[crates.io released licencegpl]

:toc:

= Installation & Usage

Cargo.toml:

[code,toml]

[dependencies] cgi2 = "0.7"

Use the cgi::main macro on your main function, taking in a Request and returning a Response.

[code,rust]

#[cgi::main] fn main(request: cgi::Request) -> cgi::Response { cgi::text_response(200, "Hello World") }

This also works if you return a Result. If your function returns a Result the error is printed to stderr and an HTTP 500 error is returned.

[code,rust]

#[cgi::main] fn main(request: cgi::Request) -> Result<cgi::Response, String> { let greeting = std::fs::read_to_string("greeting.txt").map_err(|_| "Couldn't open file")?;

Ok(cgi::text_response(200, greeting))

}

It will parse & extract the CGI environmental variables, and the HTTP request body to create Request, call your function to create a response, and convert your Response into the correct format and print to stdout. If this programme is not called as CGI (e.g. missing required environmental variables), it will panic.

It is also possible to call the cgi::handle function directly inside your main function:

[code,rust]

fn main() { cgi::handle(|request: cgi::Request| -> cgi::Response { cgi::html_response(200, "

Hello World!

") }) }

== Response Shortcuts

Several shortcuts create shortcuts easily:

cgi:empty_response(status_code):: A HTTP Reponse with no body and that HTTP status code, e.g. return cgi::empty_response(404); to return a link:https://en.wikipedia.org/wiki/HTTP_404[HTTP 404 Not Found]. cgi::html_response(status_code, text):: Converts text to bytes (UTF8) and sends that as the body with that status_code and HTML Content-Type header. cgi::string_response(status_code, text):: Converts text to bytes (UTF8), and sends that as the body with that status_code, e.g. return cgi::string_response(200, "Hello World!"):: returns a simple plain text response. cgi::binary_response(status_code, blob):: Sends blob` with that status code.

== Re-exports

http is re-exported, (as cgi::http).

cgi::Response/Request are http::Response<Vec<u8>>/Request<Vec<u8>>.

= Running locally

Python provides a simple CGI webserver you can use to run your scripts. The binaries must be in a cgi-bin directory, so you'll need to create that directory and copy your binary into it. Given a project named example, run this in your project root directory (i.e. where Cargo.toml is):


mkdir cgi-bin cargo build --example hello_world cp target/debug/examples/hello_world cgi-bin/hello_world python3 -m http.server --cgi

and then open link:http://localhost:8000/cgi-bin/hello_world[].

= See also

== Things using this

== Resources

= Why?

CGI is old, and easy to deploy. Just drop a binary in the right place, and Apache (or whatever) will serve it up. Rust is fast, so for simple things, there should be less downsides to spinning up a custom HTTP server.

= Copyright

Copyright link:https://www.gnu.org/licenses/agpl-3.0.en.html[GNU Affero GPL v3 (or later)]. See the file link:LICENCE[]

Commit count: 59

cargo fmt