What is it?
FastCGI is a binary protocol for interfacing interactive programs with a web server.
- wikipedia
That‘s it!
HTTP
FastCGI
How it works
Multithreaded application
application running as daemon
Easy!
Socket connection
(potentially multiplexed)
FastCGI Data Streams of
FastCGI Records
Web server (Nginx)
FastCGI record general structure
typedef struct {
unsigned char version;
unsigned char type;
unsigned char requestIdB1;
unsigned char requestIdB0;
unsigned char contentLengthB1;
unsigned char contentLengthB0;
unsigned char paddingLength;
unsigned char reserved;
unsigned char contentData[contentLength];
unsigned char paddingData[paddingLength];
} FCGI_Record;
Multi-byte data
split across
singular bytes
One byte of data
Restoring multi-byte data
across 2 bytes:
number = (b1 << 8) + b0
across 4 bytes:
number = ((b3 & 0x7f) << 24) +
(b2 << 16) +
(b1 << 8) +
b0
unsigned char contentLengthB1;
unsigned char contentLengthB0;
FastCGI message structure
Header
(8 bytes)
Body
(content
length +
padding
length
bytes)
FastCgimessage
[ ]
Each message (basically a
piece of data) starts with a
Header record
FastCGI header structure
typedef struct {
unsigned char version;
unsigned char type;
unsigned char requestIdB1;
unsigned char requestIdB0;
unsigned char contentLengthB1;
unsigned char contentLengthB0;
unsigned char paddingLength;
unsigned char reserved;
} FCGI_Record;
Multi-byte data
split across
singular bytes
8 bytes
Record type
Body length
Types of record types
● BeginRequest
● Params
● GetValues
● StdIn / Data
● GetValuesResult
● StdOut
● StdErr
● EndRequest
● AbortRequest
● UnknownType
Incoming
Outgoing
Has body
Management record types:
- GetValues
- GetValuesResult
- UnknownType
Application record types:
- BeginRequest
- Params
- StdIn
- StdOut
- StdErr
- Data
- AbortRequest
- EndRequest
Params visual structure
Name length info
1 byte or
4 bytes
Value length info
1 byte or
4 bytes
Name
( N bytes)
Value
( N bytes)
nameLengthB0 >> 7 == 0
nameLengthB3 >> 7 ==1
valueLengthB0 >> 7 == 0
valueLengthB3 >> 7 ==1
GetValuesResult structure
= Params structure in reversed order
Cool formulas to split number across 2 or 4 bytes:
across 2 bytes:
byte0 = number & 0xff
byte1 = (number >> 8) & 0xff
across 4 bytes:
byte0 = (number >> 24) & 0xff
byte1 = (number >> 16) & 0xff
byte2 = (number >> 8) & 0xff
byte3 = number & 0xff
StdIn / StdOut / StdErr / Data
It’s pretty simple to read from and to write to
these record types. Just read everything!
(<= contentlength + paddingLength)
End Request structure
typedef struct {
unsigned char appStatusB3;
unsigned char appStatusB2;
unsigned char appStatusB1;
unsigned char appStatusB0;
unsigned char protocolStatus;
unsigned char reserved[3];
} FCGI_EndRequestBody;
Custom application status
Protocol status
Can’t multiplex connection
Overloaded
Request complete
Unknown role
Sample message flow
Header
(BeginRequest)
BeginRequest
Body
Header
(Params)
Params Body
(Server
variables,
headers and
etc.)
Header
(StdIn / Data)
Raw content
(Form data, file
transfers and
etc., usually in
a raw HTTP
message
format)
Header
(StdOut /
StdErr)
Raw content
(Form data, file
transfers and
etc., usually in
a raw HTTP
message
format)
Header
(EndRequest)
EndRequest
body with
“Request
Complete”
status
Hey, speedy!
or biased benchmarking
$ ab -k -c 10 -n 1000 http://127.0.0.1:8080/
Percentage of the requests served within a certain time
(ms)
50% 1
66% 1
75% 1
80% 1
90% 2
95% 2
98% 2
99% 2
100% 3 (longest request)