Finished BUD 1
This commit is contained in:
368
FASTCGI.md
Normal file
368
FASTCGI.md
Normal file
@@ -0,0 +1,368 @@
|
||||
# FastCGI Protocol Flow Documentation
|
||||
|
||||
This document provides ASCII flow charts to understand how FastCGI works with nginx for the ginxsom blossom server.
|
||||
|
||||
## FastCGI Overview
|
||||
|
||||
FastCGI is a binary protocol that allows web servers (like nginx) to communicate with application servers efficiently. Unlike CGI which spawns a new process per request, FastCGI applications are persistent and can handle multiple concurrent requests.
|
||||
|
||||
## 1. FastCGI Connection Setup Flow
|
||||
|
||||
```
|
||||
┌─────────────────┐ Socket ┌─────────────────┐
|
||||
│ nginx │◄──────────────►│ FastCGI App │
|
||||
│ Web Server │ Connection │ (ginxsom) │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
│ 1. Create Unix socket │
|
||||
│ /tmp/ginxsom.sock │
|
||||
│ │
|
||||
│ 2. FastCGI app binds & listens │
|
||||
│◄───────────────────────────────────│
|
||||
│ │
|
||||
│ 3. nginx connects when needed │
|
||||
│───────────────────────────────────►│
|
||||
│ │
|
||||
│ 4. Connection established │
|
||||
│◄──────────────────────────────────►│
|
||||
```
|
||||
|
||||
## 2. HTTP Request Processing Flow
|
||||
|
||||
```
|
||||
┌─────────┐ HTTP ┌─────────┐ FastCGI ┌─────────┐
|
||||
│ Client │────────────►│ nginx │─────────────►│ ginxsom │
|
||||
│Browser │ │ │ │ FastCGI │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
│ │ │
|
||||
│ HTTP Request │ │
|
||||
│ PUT /upload │ │
|
||||
│────────────────────────► │
|
||||
│ │ │
|
||||
│ │ FCGI_BEGIN_REQUEST │
|
||||
│ │───────────────────────►│
|
||||
│ │ │
|
||||
│ │ FCGI_PARAMS │
|
||||
│ │ (HTTP headers, etc) │
|
||||
│ │───────────────────────►│
|
||||
│ │ │
|
||||
│ │ FCGI_STDIN │
|
||||
│ │ (Request body) │
|
||||
│ │───────────────────────►│
|
||||
│ │ │
|
||||
│ │ Process │
|
||||
│ │◄───────Request─────────│
|
||||
│ │ │
|
||||
│ │ FCGI_STDOUT │
|
||||
│ │ (Response headers) │
|
||||
│ │◄───────────────────────│
|
||||
│ │ │
|
||||
│ │ FCGI_STDOUT │
|
||||
│ │ (Response body) │
|
||||
│ │◄───────────────────────│
|
||||
│ │ │
|
||||
│ │ FCGI_END_REQUEST │
|
||||
│ │◄───────────────────────│
|
||||
│ │ │
|
||||
│ HTTP Response │ │
|
||||
│◄──────────────────────│ │
|
||||
```
|
||||
|
||||
## 3. FastCGI Record Structure
|
||||
|
||||
```
|
||||
FastCGI Record Format:
|
||||
┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
|
||||
│ Version │ Type │RequestID│RequestID│ Length │ Length │ Padding │Reserved │
|
||||
│ (1) │ (1) │ Hi │ Lo │ Hi │ Lo │ Length │ (1) │
|
||||
│ │ │ (1) │ (1) │ (1) │ (1) │ (1) │ │
|
||||
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
|
||||
│◄────────────────── 8 bytes header ──────────────────────►│
|
||||
│ │
|
||||
│◄─────────────────── Content (Length bytes) ─────────────►│
|
||||
│ │
|
||||
│◄───── Padding (Padding Length bytes) ────►│
|
||||
|
||||
Record Types:
|
||||
- FCGI_BEGIN_REQUEST (1) - Start new request
|
||||
- FCGI_PARAMS (4) - Environment variables
|
||||
- FCGI_STDIN (5) - Request body data
|
||||
- FCGI_STDOUT (6) - Response data
|
||||
- FCGI_END_REQUEST (3) - End of request
|
||||
```
|
||||
|
||||
## 4. Ginxsom Endpoint Handling Flow
|
||||
|
||||
### 4a. Static File Request (Direct nginx)
|
||||
|
||||
```
|
||||
┌─────────┐ ┌─────────┐
|
||||
│ Client │ │ nginx │
|
||||
└─────────┘ └─────────┘
|
||||
│ │
|
||||
│ GET /{sha256hash} │
|
||||
│───────────────────────►│
|
||||
│ │
|
||||
│ │ Check file exists:
|
||||
│ │ /var/lib/ginxsom/files/
|
||||
│ │ {first2}/{remaining}
|
||||
│ │
|
||||
│ │ ┌─ File exists? ─┐
|
||||
│ │ │ YES │
|
||||
│ │ └────────────────┘
|
||||
│ │ │
|
||||
│ HTTP 200 + File │ │ Serve directly
|
||||
│◄──────────────────────│◄──────┘
|
||||
│ │
|
||||
|
||||
Alternative flow:
|
||||
│ │ ┌─ File exists? ─┐
|
||||
│ │ │ NO │
|
||||
│ │ └────────────────┘
|
||||
│ │ │
|
||||
│ HTTP 404 Not Found │ │
|
||||
│◄──────────────────────│◄──────┘
|
||||
```
|
||||
|
||||
### 4b. Upload Request (FastCGI)
|
||||
|
||||
```
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│ Client │ │ nginx │ │ ginxsom │ │ File │
|
||||
│ │ │ │ │ FastCGI │ │ System │
|
||||
└─────────┘ └─────────┘ └─────────┘ └─────────┘
|
||||
│ │ │ │
|
||||
│ PUT /upload │ │ │
|
||||
│ Auth: xyz │ │ │
|
||||
│ Body: file │ │ │
|
||||
│─────────────►│ │ │
|
||||
│ │ │ │
|
||||
│ │ FCGI_PARAMS │ │
|
||||
│ │ METHOD=PUT │ │
|
||||
│ │ URI=/upload │ │
|
||||
│ │ AUTH=xyz │ │
|
||||
│ │─────────────►│ │
|
||||
│ │ │ │
|
||||
│ │ FCGI_STDIN │ │
|
||||
│ │ (file data) │ │
|
||||
│ │─────────────►│ │
|
||||
│ │ │ │
|
||||
│ │ │ Verify Auth │
|
||||
│ │ │ (nostr sig) │
|
||||
│ │ │ │
|
||||
│ │ │ Calculate │
|
||||
│ │ │ SHA-256 │
|
||||
│ │ │ │
|
||||
│ │ │ Write file │
|
||||
│ │ │─────────────►│
|
||||
│ │ │ │
|
||||
│ │ │ Store │
|
||||
│ │ │ metadata │
|
||||
│ │ │────────────────────►
|
||||
│ │ │ │ DB
|
||||
│ │ │ │
|
||||
│ │ FCGI_STDOUT │ │
|
||||
│ │ 200 OK │ │
|
||||
│ │ {sha256} │ │
|
||||
│ │◄─────────────│ │
|
||||
│ │ │ │
|
||||
│ HTTP 200 OK │ │ │
|
||||
│ {sha256} │ │ │
|
||||
│◄─────────────│ │ │
|
||||
```
|
||||
|
||||
### 4c. HEAD Request for Metadata (FastCGI)
|
||||
|
||||
```
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│ Client │ │ nginx │ │ ginxsom │
|
||||
│ │ │ │ │ FastCGI │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
│ │ │
|
||||
│ HEAD /{sha256} │ │
|
||||
│──────────────────►│ │
|
||||
│ │ │
|
||||
│ │ FCGI_PARAMS │
|
||||
│ │ METHOD=HEAD │
|
||||
│ │ BLOSSOM_HASH=... │
|
||||
│ │──────────────────►│
|
||||
│ │ │
|
||||
│ │ │ Query DB for
|
||||
│ │ │ file metadata
|
||||
│ │ │
|
||||
│ │ FCGI_STDOUT │
|
||||
│ │ Content-Length: X │
|
||||
│ │ Content-Type: Y │
|
||||
│ │ x-sha256: hash │
|
||||
│ │◄──────────────────│
|
||||
│ │ │
|
||||
│ HTTP Headers Only │ │
|
||||
│◄──────────────────│ │
|
||||
```
|
||||
|
||||
## 5. Development vs Production Deployment
|
||||
|
||||
### Development Mode
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ Terminal │ │ nginx │
|
||||
│ │ │ │
|
||||
│ ./ginxsom │◄──────────────►│ Config: │
|
||||
│ --fastcgi │ Unix Socket │ fastcgi_pass│
|
||||
│ --socket │ /tmp/ginxsom │ unix:/tmp/ │
|
||||
│ /tmp/... │ .sock │ ginxsom.sock│
|
||||
└─────────────┘ └─────────────┘
|
||||
│ │
|
||||
│ Direct execution │ sudo systemctl
|
||||
│ Easy debugging │ reload nginx
|
||||
│ Ctrl+C to stop │ (config changes)
|
||||
│ Real-time logs │
|
||||
```
|
||||
|
||||
### Production Mode
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ systemd │ │ nginx │
|
||||
│ │ │ │
|
||||
│ ginxsom │◄──────────────►│ Config: │
|
||||
│ .service │ Unix Socket │ fastcgi_pass│
|
||||
│ │ /run/ginxsom/ │ unix:/run/ │
|
||||
│ Auto-start │ ginxsom.sock │ ginxsom/... │
|
||||
│ Auto-restart│ │ │
|
||||
│ Log to file │ │ │
|
||||
└─────────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
## 6. Complete nginx + FastCGI Request Flow
|
||||
|
||||
```
|
||||
┌───────┐ ┌─────────────────────────────────────────────────┐ ┌─────────┐
|
||||
│Client │ │ nginx │ │ginxsom │
|
||||
└───────┘ └─────────────────────────────────────────────────┘ │FastCGI │
|
||||
│ │ └─────────┘
|
||||
│ GET /abc123...def │ │
|
||||
│───────────────────────►│ │
|
||||
│ │ │
|
||||
│ │ location ~ ^/([a-f0-9]{64})$ { │
|
||||
│ │ # Check if static file exists │
|
||||
│ │ try_files /$prefix/$suffix =404 │
|
||||
│ │ } │
|
||||
│ │ │
|
||||
│ │ ┌─ File exists? ─┐ │
|
||||
│ │ │ YES │ │
|
||||
│ │ └────────────────┘ │
|
||||
│ │ │ │
|
||||
│ │ │ Serve directly (fast!) │
|
||||
│ HTTP 200 + File │ │ │
|
||||
│◄──────────────────────│◄──────┘ │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ PUT /upload │ │
|
||||
│ Authorization: xyz │ │
|
||||
│───────────────────────►│ │
|
||||
│ │ │
|
||||
│ │ location /upload { │
|
||||
│ │ fastcgi_pass unix:/tmp/ │
|
||||
│ │ ginxsom.sock; │
|
||||
│ │ } │
|
||||
│ │ │
|
||||
│ │ ┌─ FastCGI Protocol ─┐ │
|
||||
│ │ │ FCGI_BEGIN_REQUEST │─────────────►│
|
||||
│ │ │ FCGI_PARAMS │─────────────►│
|
||||
│ │ │ FCGI_STDIN │─────────────►│
|
||||
│ │ └─────────────────────┘ │
|
||||
│ │ │
|
||||
│ │ │ Verify
|
||||
│ │ │ nostr
|
||||
│ │ │ signature
|
||||
│ │ │
|
||||
│ │ │ Calculate
|
||||
│ │ │ SHA-256
|
||||
│ │ │
|
||||
│ │ │ Store file
|
||||
│ │ │ & metadata
|
||||
│ │ │
|
||||
│ │ ┌─ FastCGI Response ─┐ │
|
||||
│ │ │ FCGI_STDOUT │◄─────────────│
|
||||
│ │ │ FCGI_END_REQUEST │◄─────────────│
|
||||
│ │ └─────────────────────┘ │
|
||||
│ │ │
|
||||
│ HTTP 200 OK │ │
|
||||
│ {"sha256": "..."} │ │
|
||||
│◄──────────────────────│ │
|
||||
```
|
||||
|
||||
## 7. libfcgi Library Usage
|
||||
|
||||
### Basic FastCGI Application Structure
|
||||
|
||||
```c
|
||||
#include <fcgiapp.h>
|
||||
|
||||
int main() {
|
||||
FCGX_Request request;
|
||||
|
||||
// Initialize FastCGI library
|
||||
FCGX_Init();
|
||||
FCGX_InitRequest(&request, 0, 0);
|
||||
|
||||
// Main request processing loop
|
||||
while (FCGX_Accept_r(&request) == 0) {
|
||||
|
||||
// Read environment variables (HTTP headers, etc)
|
||||
char* method = FCGX_GetParam("REQUEST_METHOD", request.envp);
|
||||
char* uri = FCGX_GetParam("REQUEST_URI", request.envp);
|
||||
char* auth = FCGX_GetParam("HTTP_AUTHORIZATION", request.envp);
|
||||
|
||||
// Route requests
|
||||
if (strcmp(uri, "/health") == 0) {
|
||||
handle_health(&request);
|
||||
} else if (strcmp(uri, "/upload") == 0) {
|
||||
handle_upload(&request);
|
||||
} else if (strncmp(uri, "/head/", 6) == 0) {
|
||||
handle_head(&request);
|
||||
}
|
||||
|
||||
// Finish this request
|
||||
FCGX_Finish_r(&request);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Reading Request Data
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ nginx sends: │ │ ginxsom reads: │
|
||||
├─────────────────┤ ├─────────────────┤
|
||||
│ FCGI_PARAMS │────────►│ FCGX_GetParam() │
|
||||
│ REQUEST_METHOD │ │ "PUT" │
|
||||
│ REQUEST_URI │ │ "/upload" │
|
||||
│ CONTENT_LENGTH │ │ "1024" │
|
||||
│ HTTP_* │ │ headers │
|
||||
├─────────────────┤ ├─────────────────┤
|
||||
│ FCGI_STDIN │────────►│ FCGX_GetStr() │
|
||||
│ (request body) │ │ file data │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### Writing Response Data
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ ginxsom writes: │ │ nginx sends: │
|
||||
├─────────────────┤ ├─────────────────┤
|
||||
│ FCGX_PutS() │────────►│ HTTP Response │
|
||||
│ "Content-Type: │ │ Headers │
|
||||
│ application/ │ │ │
|
||||
│ json\r\n\r\n" │ │ │
|
||||
├─────────────────┤ ├─────────────────┤
|
||||
│ FCGX_PutS() │────────►│ HTTP Response │
|
||||
│ '{"status": │ │ Body │
|
||||
│ "ok"}' │ │ │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
This documentation shows how FastCGI enables nginx to efficiently serve static blossom files directly while delegating authenticated operations to the ginxsom FastCGI application.
|
||||
Reference in New Issue
Block a user