1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! A library for writing FastCGI application servers.
//! It mostly implements the [FastCGI](https://www.mit.edu/~yandros/doc/specs/fcgi-spec.html#S4)
//! spec, but [deviates](crate#deviations-from-the-spec) where it makes sense to do so.
//!
//! Using this crate is straightforward:
//!
//! ```
//! use vintage::{Response, ServerConfig};
//!
//! let config = ServerConfig::new()
//! .on_get(["/about"], |_req, _params| {
//! Response::html("<h1>Hello World</h1>")
//! });
//!
//! let handle = vintage::start(config, "localhost:0").unwrap();
//!
//! // This would block the current thread until the server thread exits
//! // handle.join()
//!
//! // Gracefull shutdown
//! handle.stop();
//! ```
//!
//! # Terminology
//!
//! - CGI: A specification HTTP web servers can follow to execute a program in response to HTTP requests.
//! For example, you would configure your web server (e.g. Apache) to execute a certain bash script when a request came in.
//! The bash script would get access to request metadata via environment variables.
//! - FastCGI: A successor to CGI (Common Gateway Interface). Unlike CGI, programs are not executed every time a request comes in.
//! Instead, a FastCGI application is started and listens on a socket, and the HTTP web server communicates HTTP request metadata via that socket.
//! The FastCGI spec is a definition of the binary protocol used to communicate on that socket.
//! - FastCGI client: The program that initiates a FastCGI connection.
//! In most cases, this is the HTTP web server; it receives an HTTP request from a browser, and forwards that request to the FastCGI server.
//! - FastCGI server/application server: A program that listens on a socket, and responds to requests from a FastCGI client.
//!
//! # Deviations from the spec
//!
//! The FastCGI spec was created by a company called [Open Market](https://en.wikipedia.org/wiki/Open_Market).
//! One of their products was a web server, and it was the first commercial web server receive FastCGI support.
//! As a consequence, their FastCGI specification includes details only relevant to their
//! web server implementation.
//! Since their web server is no more, we disregard these parts of the spec.
//! Additionally, the passage of time has made some other parts of the specification obsolete.
//!
//! Notably:
//! - I ignore the part about what file descriptors are open when the FastCGI server begins (Section 2.2)
//! - I ignore the special processing of the magic `FCGI_WEB_SERVER_ADDRS` environment variable (Section 3.2)
//! - `FCGI_UNKNOWN_TYPE` is sent for any unknown record type, instead of just unknown management
//! record types (Section 4.2).
//! - Only the Responder role is implemented. Two reasons:
//! - Authorizer & Filter roles are not implemented by any current FastCGI-capable servers (or clients).
//! - I checked the source code of Nginx, Caddy and Php-fpm (arguabley the most popular fastcgi client).
//! - Authorizer & Filter are not relevant anymore.
//! - Authorization is usually part of the application.
//! - The Filter is too niche to be useful. It assumes your request path has an extension.
//! The spec is actually light on details regarding its use.
//! OpenMarket's archived
//! [manual](https://fastcgi-archives.github.io/fcgi2/doc/fastcgi-prog-guide/ch1intro.htm)
//! has more info.
//! - Writing a "stderr" record is not supported. As far as I can tell, it's pretty useless.
//! At best, what you send in that record gets printed in the logs of the FastCGI _client_.
//! At worst, it gets ignored.
pub use ;
pub use ServerConfig;
pub use ;
use io;
use ToSocketAddrs;
/// Starts a FastCGI server with the given config at `address` and returns a handle to it.
///
/// Binding to port `0` will request that the OS assign an available port.
///
/// If `address` yields multiple addresses, only the first one is considered.
///
/// This function does not block because the FastCGI server is created on a separate thread.