···
1
-
(** Core FastCGI types and constants.
3
-
This module defines the fundamental types used throughout the
4
-
FastCGI protocol implementation.
6
-
FastCGI is an open extension to CGI that provides high performance for
7
-
all Internet applications without the penalties of Web server APIs.
8
-
Unlike traditional CGI programs that are started for each request,
9
-
FastCGI applications are long-lived processes that can handle multiple
10
-
requests over persistent connections. *)
12
-
(** {1 Core Types} *)
14
-
(** FastCGI protocol version.
16
-
The current protocol uses version 1. Future versions of the
17
-
protocol may increment this value. Applications should check the version
18
-
field in incoming records and reject unsupported versions.
20
-
Version 1 is represented by the value [1]. *)
23
-
(** FastCGI record types.
25
-
All data transmitted over a FastCGI connection is packaged in records.
26
-
Each record has a type that determines how the record's content should
27
-
be interpreted. The protocol defines both management records (for
28
-
protocol-level communication) and application records (for request
31
-
Management records contain information that is not specific to any web
32
-
server request, such as capability queries and unknown type responses.
33
-
Application records contain information about a particular request,
34
-
identified by a non-zero request ID. *)
36
-
| Begin_request (** Starts a new request. Sent by the web server to begin
37
-
processing. Contains the role and connection flags. *)
38
-
| Abort_request (** Aborts an existing request. Sent by the web server
39
-
when an HTTP client closes its connection while the
40
-
request is still being processed. *)
41
-
| End_request (** Completes a request. Sent by the application to
42
-
terminate processing, either normally or due to
43
-
an error condition. *)
44
-
| Params (** Parameter name-value pairs. Used to transmit CGI-style
45
-
environment variables from the web server to the
46
-
application. Sent as a stream. *)
47
-
| Stdin (** Standard input data. Contains the request body data
48
-
that would normally be available on stdin in CGI.
49
-
Sent as a stream. *)
50
-
| Stdout (** Standard output data. Response data from the application
51
-
to the web server. This becomes the HTTP response.
52
-
Sent as a stream. *)
53
-
| Stderr (** Standard error data. Error messages from the application.
54
-
Used for logging and debugging. Sent as a stream. *)
55
-
| Data (** Additional data stream. Used only in the Filter role
56
-
to transmit file data that needs to be filtered.
57
-
Sent as a stream. *)
58
-
| Get_values (** Management record to query application variables.
59
-
Allows the web server to discover application
60
-
capabilities like max connections and multiplexing. *)
61
-
| Get_values_result (** Management record response to Get_values. Contains
62
-
the requested variable values. *)
63
-
| Unknown_type (** Management record for unknown type handling. Sent by
64
-
the application when it receives a record type it
65
-
doesn't understand. *)
67
-
(** FastCGI application roles.
69
-
A FastCGI application can play one of several well-defined roles.
70
-
The role determines what information the application receives and
71
-
what it's expected to produce.
73
-
A FastCGI application plays one of several well-defined roles. The most
74
-
familiar is the Responder role, in which the application receives all
75
-
the information associated with an HTTP request and generates an HTTP
78
-
| Responder (** The most common role, equivalent to traditional CGI.
79
-
The application receives all information associated with
80
-
an HTTP request and generates an HTTP response. This
81
-
includes environment variables, request headers, and
82
-
request body data. *)
83
-
| Authorizer (** Performs access control decisions. The application
84
-
receives HTTP request information and generates an
85
-
authorized/unauthorized decision. In case of authorization,
86
-
it can associate additional variables with the request.
87
-
For unauthorized requests, it provides a complete HTTP
89
-
| Filter (** Processes data streams with filtering. The application
90
-
receives HTTP request information plus an additional
91
-
data stream from a file stored on the web server, and
92
-
generates a "filtered" version of the data as an HTTP
93
-
response. Both the file and the filter can be access
96
-
(** Request ID for multiplexing multiple requests over a single connection.
98
-
FastCGI supports multiplexing, allowing multiple concurrent requests
99
-
to be processed over a single transport connection. Each request is
100
-
identified by a unique request ID within the scope of that connection.
102
-
The Web server re-uses FastCGI request IDs; the application keeps track
103
-
of the current state of each request ID on a given transport connection.
104
-
Request IDs should be small integers to allow efficient tracking using
105
-
arrays rather than hash tables.
107
-
The value [0] is reserved for management records and is called the
108
-
"null request ID". *)
109
-
type request_id = int
111
-
(** Application-level status code.
113
-
When an application completes a request, it provides an application
114
-
status code similar to the exit status of a traditional CGI program.
115
-
A value of [0] indicates success, while non-zero values indicate
116
-
various error conditions.
118
-
The application sets the appStatus component to the status code that
119
-
the CGI program would have returned via the exit system call. *)
120
-
type app_status = int
122
-
(** Protocol-level status codes.
124
-
In addition to application status, each request completion includes
125
-
a protocol-level status that indicates whether the request was
126
-
processed normally or rejected for protocol-related reasons.
128
-
These status codes allow the web server to understand why a request
129
-
was not processed and take appropriate action. *)
130
-
type protocol_status =
131
-
| Request_complete (** Normal end of request. The application successfully
132
-
processed the request and the appStatus field
133
-
indicates the application-level result. *)
134
-
| Cant_mpx_conn (** Rejecting a new request because the application
135
-
cannot multiplex connections. This happens when
136
-
a web server sends concurrent requests over one
137
-
connection to an application that processes only
138
-
one request at a time per connection. *)
139
-
| Overloaded (** Rejecting a new request because the application
140
-
is overloaded. This occurs when the application
141
-
runs out of some resource, such as database
142
-
connections or memory. *)
143
-
| Unknown_role (** Rejecting a new request because the requested
144
-
role is unknown to the application. This happens
145
-
when the web server specifies a role that the
146
-
application doesn't implement. *)
148
-
(** Connection flags for controlling connection behavior.
150
-
These flags are sent in Begin_request records to control how the
151
-
connection should be managed after the request completes. *)
152
-
type connection_flags = {
153
-
keep_conn : bool; (** Keep connection open after request completion.
155
-
If false, the application closes the connection after
156
-
responding to this request. If true, the application
157
-
does not close the connection after responding to this
158
-
request; the Web server retains responsibility for the
161
-
This flag enables connection reuse for better performance,
162
-
especially important for high-traffic applications. *)
165
-
(** {1 Record Types} *)
167
-
(** FastCGI record header.
169
-
Every FastCGI record begins with an 8-byte header that identifies
170
-
the record type, request ID, and content length. This fixed-length
171
-
prefix allows efficient parsing and proper demultiplexing of records.
173
-
A FastCGI record consists of a fixed-length prefix followed by a
174
-
variable number of content and padding bytes.
176
-
The header format is platform-independent and uses network byte order
177
-
for multi-byte integers. *)
178
-
type record_header = {
179
-
version : int; (** Protocol version. Must be [1] for this specification.
180
-
Future versions may increment this value. *)
181
-
record_type : record_type; (** Type of this record, determining how to interpret
182
-
the content data. *)
183
-
request_id : request_id; (** Request ID this record belongs to. Value [0] is
184
-
reserved for management records. *)
185
-
content_length : int; (** Number of bytes in the content data. Must be
186
-
between [0] and [65535]. *)
187
-
padding_length : int; (** Number of padding bytes following content.
188
-
Must be between [0] and [255]. Used for alignment. *)
191
-
(** Begin request record body.
193
-
This record marks the start of a new request and specifies the role
194
-
the application should play and connection management flags.
196
-
The Web server sends a FCGI_BEGIN_REQUEST record to start a request.
197
-
The record body contains the role and flags that control request
199
-
type begin_request_body = {
200
-
role : role; (** The role the web server expects the application
201
-
to play for this request. *)
202
-
flags : connection_flags; (** Flags controlling connection behavior after
203
-
request completion. *)
206
-
(** End request record body.
208
-
This record marks the completion of a request and provides both
209
-
application-level and protocol-level status information.
211
-
The application sends a FCGI_END_REQUEST record to terminate a request,
212
-
either because the application has processed the request or because the
213
-
application has rejected the request. *)
214
-
type end_request_body = {
215
-
app_status : app_status; (** Application-level status code, similar to
216
-
a CGI program's exit status. *)
217
-
protocol_status : protocol_status; (** Protocol-level status indicating normal
218
-
completion or rejection reason. *)
221
-
(** Complete FastCGI record.
223
-
A complete record consists of the header, content data, and optional
224
-
padding. The content interpretation depends on the record type.
226
-
Records support padding to allow senders to keep data aligned for more
227
-
efficient processing. Experience with the X window system protocols shows
228
-
the performance benefit of such alignment. *)
230
-
header : record_header; (** Fixed 8-byte header with record metadata. *)
231
-
content : bytes; (** Variable-length content data. Length must match
232
-
header.content_length. *)
233
-
padding : bytes option; (** Optional padding data for alignment. Length must
234
-
match header.padding_length if present. *)
237
-
(** Name-value pair for parameters.
239
-
FastCGI uses a compact binary encoding for transmitting name-value pairs
240
-
such as CGI environment variables. This encoding supports both short
241
-
and long names/values efficiently.
243
-
FastCGI transmits a name-value pair as the length of the name, followed
244
-
by the length of the value, followed by the name, followed by the value.
245
-
Lengths of 127 bytes and less can be encoded in one byte, while longer
246
-
lengths are always encoded in four bytes. *)
247
-
type name_value_pair = {
248
-
name : string; (** Parameter name. For CGI compatibility, these are typically
249
-
uppercase environment variable names like "REQUEST_METHOD". *)
250
-
value : string; (** Parameter value. The value does not include a terminating
251
-
null byte in the FastCGI encoding. *)
254
-
(** {1 Request/Response Model} *)
256
-
(** Request context containing all information for a FastCGI request.
258
-
This high-level type aggregates all the information needed to process
259
-
a FastCGI request. It combines the protocol-level details (request ID,
260
-
role, flags) with the application data (parameters and input streams).
262
-
The request follows a two-level processing model: First, the protocol
263
-
multiplexes a single transport connection between several independent
264
-
FastCGI requests. Second, within each request the protocol provides
265
-
several independent data streams in each direction. *)
266
-
type 'a request = {
267
-
request_id : request_id; (** Unique identifier for this request within
268
-
the connection scope. Used for multiplexing. *)
269
-
role : role; (** The role this application should play for
270
-
this request (Responder, Authorizer, or Filter). *)
271
-
flags : connection_flags; (** Connection management flags from the web server. *)
272
-
params : (string * string) list; (** CGI-style environment variables transmitted
273
-
via FCGI_PARAMS records. These provide request
274
-
context like HTTP headers, server info, etc. *)
275
-
stdin : 'a Eio.Flow.source; (** Standard input stream, containing request body
276
-
data (equivalent to CGI stdin). For HTTP POST
277
-
requests, this contains the form data or payload. *)
278
-
data : 'a Eio.Flow.source option; (** Additional data stream, used only in Filter
279
-
role. Contains file data that needs to be
280
-
filtered. [None] for Responder and Authorizer. *)
283
-
(** Response builder for constructing FastCGI responses.
285
-
This type provides the output streams for sending response data back
286
-
to the web server. Following CGI conventions, it separates normal
287
-
output from error output.
289
-
Both stdout and stderr data pass over a single transport connection from
290
-
the application to the Web server, rather than requiring separate pipes
291
-
as with CGI/1.1. *)
292
-
type 'a response = {
293
-
stdout : 'a Eio.Flow.sink; (** Standard output stream for response data.
294
-
In Responder role, this contains the HTTP
295
-
response including headers and body. *)
296
-
stderr : 'a Eio.Flow.sink; (** Standard error stream for logging and debugging.
297
-
All role protocols use the FCGI_STDERR stream
298
-
just the way stderr is used in conventional
299
-
applications programming: to report application-level
300
-
errors in an intelligible way. *)
303
-
(** Complete response with status.
305
-
When an application finishes processing a request, it must provide
306
-
both application-level and protocol-level status information. This
307
-
allows the web server to understand the outcome and take appropriate
310
-
This corresponds to the FCGI_END_REQUEST record sent by the application. *)
311
-
type response_result = {
312
-
app_status : app_status; (** Application exit status, equivalent to what
313
-
a CGI program would return via exit(). *)
314
-
protocol_status : protocol_status; (** Protocol-level completion status, indicating
315
-
normal completion or various rejection reasons. *)
318
-
(** {1 Protocol Constants} *)
320
-
(** Protocol version constant.
322
-
This constant represents FCGI_VERSION_1. This value should be used in
323
-
the version field of all record headers. *)
324
-
val version_1 : int
326
-
(** Standard file descriptor for FastCGI listening socket.
328
-
The Web server leaves a single file descriptor, FCGI_LISTENSOCK_FILENO,
329
-
open when the application begins execution. This descriptor refers to a
330
-
listening socket created by the Web server.
332
-
The value equals STDIN_FILENO (0). Applications can distinguish between
333
-
CGI and FastCGI invocation by calling getpeername() on this descriptor. *)
334
-
val listensock_fileno : int
336
-
(** {2 Record Type Constants}
338
-
These integer constants correspond to the record_type variants and are
339
-
used in the binary protocol encoding. These are the values transmitted
340
-
in the type field of record headers. *)
342
-
(** Value [1]. Starts a new request. *)
343
-
val fcgi_begin_request : int
345
-
(** Value [2]. Aborts an existing request. *)
346
-
val fcgi_abort_request : int
348
-
(** Value [3]. Completes a request. *)
349
-
val fcgi_end_request : int
351
-
(** Value [4]. Parameter name-value pairs. *)
352
-
val fcgi_params : int
354
-
(** Value [5]. Standard input data. *)
355
-
val fcgi_stdin : int
357
-
(** Value [6]. Standard output data. *)
358
-
val fcgi_stdout : int
360
-
(** Value [7]. Standard error data. *)
361
-
val fcgi_stderr : int
363
-
(** Value [8]. Additional data stream (Filter). *)
364
-
val fcgi_data : int
366
-
(** Value [9]. Query application variables. *)
367
-
val fcgi_get_values : int
369
-
(** Value [10]. Response to Get_values. *)
370
-
val fcgi_get_values_result : int
372
-
(** Value [11]. Unknown record type response. *)
373
-
val fcgi_unknown_type : int
375
-
(** {2 Role Constants}
377
-
These integer constants correspond to the role variants and are used
378
-
in Begin_request record bodies. These identify the role the web server
379
-
expects the application to play. *)
381
-
(** Value [1]. Handle HTTP requests and generate responses. *)
382
-
val fcgi_responder : int
384
-
(** Value [2]. Perform authorization decisions. *)
385
-
val fcgi_authorizer : int
387
-
(** Value [3]. Process data streams with filtering. *)
388
-
val fcgi_filter : int
390
-
(** {2 Flag Constants}
392
-
These constants are used in the flags field of Begin_request records
393
-
to control connection behavior. *)
395
-
(** Value [1]. Keep connection open after request.
396
-
If zero, the application closes the connection after
397
-
responding to this request. If not zero, the application
398
-
does not close the connection after responding to this
400
-
val fcgi_keep_conn : int
402
-
(** {2 Protocol Limits}
404
-
These constants define the maximum sizes for various protocol elements,
405
-
ensuring compatibility and preventing buffer overflows. *)
407
-
(** Value [65535]. Maximum bytes in record content.
408
-
Between 0 and 65535 bytes of data, interpreted
409
-
according to the record type. *)
410
-
val max_content_length : int
412
-
(** Value [255]. Maximum bytes in record padding.
413
-
Between 0 and 255 bytes of data, which are ignored. *)
414
-
val max_padding_length : int
416
-
(** Value [8]. Fixed size of record headers.
417
-
Number of bytes in a FCGI_Header. Future versions
418
-
of the protocol will not reduce this number. *)
419
-
val header_length : int
421
-
(** {2 Management Record Variables}
423
-
These string constants identify the standard management variables that
424
-
can be queried using FCGI_GET_VALUES records. They allow the web server
425
-
to discover application capabilities.
427
-
The initial set provides information to help the server perform application
428
-
and connection management. *)
430
-
(** Variable name "FCGI_MAX_CONNS". The maximum number
431
-
of concurrent transport connections this application
432
-
will accept, e.g. "1" or "10". *)
433
-
val fcgi_max_conns : string
435
-
(** Variable name "FCGI_MAX_REQS". The maximum number
436
-
of concurrent requests this application will accept,
437
-
e.g. "1" or "50". *)
438
-
val fcgi_max_reqs : string
440
-
(** Variable name "FCGI_MPXS_CONNS". "0" if this
441
-
application does not multiplex connections (i.e.
442
-
handle concurrent requests over each connection),
444
-
val fcgi_mpxs_conns : string