Difference between revisions for Users / Eo Ny / dev




← Previous edit
Next edit →

Version1 Version2
1 # HTTP Class Technical Documentation 1 == HTTP Class Technical Documentation ==
2 2
3 ## Overview 3 === Overview ===
4 4
5 The `Http` class (`src/class/http.php`) is a core component of the WackoWiki system responsible for handling HTTP request/response processing, session management, caching, and security features. This class acts as a bridge between the web server and the wiki engine. 5 The ##Http## class (##src/class/http.php##) is a core component of the WackoWiki system responsible for handling HTTP request/response processing, session management, caching, and security features. This class acts as a bridge between the web server and the wiki engine.
6 6
7 **File Location:** `src/class/http.php` 7 **File Location:** ##src/class/http.php##
8 **Language:** PHP 8 **Language:** PHP
9 **Dependencies:** Database class, Session classes, Utility classes (`Ut`), Diagnostics class (`Diag`) 9 **Dependencies:** Database class, Session classes, Utility classes (##Ut##), Diagnostics class (##Diag##)
10 10
11 --- 11 ----
12 12
13 ## Class Properties 13 === Class Properties ===
14 14
15 ### Public Properties 15 ==== Public Properties ====
16 16
17 | Property | Type | Description | 17 #|
18 |----------|------|-------------| 18 *| Property | Type | Description |*
19 | `$tls_session` | bool | Indicates if the current session uses HTTPS/TLS encryption | 19 || ##$tls_session## | bool | Indicates if the current session uses HTTPS/TLS encryption ||
20 | `$request_uri` | string | Normalized REQUEST_URI (e.g., 'PageOfNoReturn/show?a=1') | 20 || ##$request_uri## | string | Normalized REQUEST_URI (e.g., 'PageOfNoReturn/show?a=1') ||
21 | `$ip` | string | Client's real IP address (accounts for proxies) | 21 || ##$ip## | string | Client's real IP address (accounts for proxies) ||
22 | `$sess` | Session | Reference to the Session object | 22 || ##$sess## | Session | Reference to the Session object ||
23 | `$method` | string | Current HTTP method/request type | 23 || ##$method## | string | Current HTTP method/request type ||
24 24 || ==== Private Properties ==== ||
25 ### Private Properties 25 || Property | Type | Description ||
26 26 || ---------- | ------ | ------------- ||
27 | Property | Type | Description | 27 || ##$db## | object | Database connection reference ||
28 |----------|------|-------------| 28 || ##$tls_mark## | string | Cookie name for TLS session marking ||
29 | `$db` | object | Database connection reference | 29 || ##$page## | string | Current page name being processed ||
30 | `$tls_mark` | string | Cookie name for TLS session marking | 30 || ##$hash## | string | SHA1 hash of the page name ||
31 | `$page` | string | Current page name being processed | 31 || ##$query## | string | Encoded query string ||
32 | `$hash` | string | SHA1 hash of the page name | 32 || ##$lang## | string | Current language code ||
33 | `$query` | string | Encoded query string | 33 || ##$file## | string | Cache file path ||
34 | `$lang` | string | Current language code | 34 || ##$caching## | int | Flag indicating if page should be cached (0 or 1) ||
35 | `$file` | string | Cache file path | 35 || ---- ||
36 | `$caching` | int | Flag indicating if page should be cached (0 or 1) | 36 || === Constructor === ||
37 37 || %%php
38 ---    
39    
40 ## Constructor    
41    
42 ```php    
43 public function __construct(&$db) 38 public function __construct(&$db)
44 ``` 39 %% ||
45 40 || **Purpose:** Initializes the Http object and sets up HTTP session handling. ||
46 **Purpose:** Initializes the Http object and sets up HTTP session handling. 41 || **Parameters:** ||
47 42 || - ##$db## - Database object reference ||
48 **Parameters:** 43 || **Initialization Steps:** ||
49 - `$db` - Database object reference 44 || 1. Stores database reference ||
50 45 || 2. Extracts and normalizes REQUEST_URI ||
51 **Initialization Steps:** 46 || 3. Detects TLS/HTTPS session status ||
52 1. Stores database reference 47 || 4. Determines client's real IP address ||
53 2. Extracts and normalizes REQUEST_URI 48 || 5. Sets up TLS mark cookie name ||
54 3. Detects TLS/HTTPS session status 49 || 6. Enforces TLS session upgrade if needed ||
55 4. Determines client's real IP address 50 || **Example:** ||
56 5. Sets up TLS mark cookie name 51 || %%php
57 6. Enforces TLS session upgrade if needed    
58    
59 **Example:**    
60 ```php    
61 $http = new Http($db); 52 $http = new Http($db);
62 ``` 53 %% ||
63 54 || ---- ||
64 --- 55 || === Core Methods === ||
65 56 || ==== Session Management ==== ||
66 ## Core Methods 57 || ===== ##session($route): void## ===== ||
67 58 || Initializes the session handler (file-based or database-based). ||
68 ### Session Management 59 || **Parameters:** ||
69 60 || - ##$route## (int) - Routing flag: ||
70 #### `session($route): void` 61 || - Bit 2 (##$route & 2##): Enable static mode for files/freecap (disables replay prevention and ID regeneration) ||
71 Initializes the session handler (file-based or database-based). 62 || **Features:** ||
72 63 || - Selects storage backend (file or database) ||
73 **Parameters:** 64 || - Configures cookie settings (security, path, httponly) ||
74 - `$route` (int) - Routing flag: 65 || - Binds IP and TLS validation ||
75   - Bit 2 (`$route & 2`): Enable static mode for files/freecap (disables replay prevention and ID regeneration) 66 || - Recovers diagnostic logs from previous session ||
76 67 || **Example:** ||
77 **Features:** 68 || %%php
78 - Selects storage backend (file or database)    
79 - Configures cookie settings (security, path, httponly)    
80 - Binds IP and TLS validation    
81 - Recovers diagnostic logs from previous session    
82    
83 **Example:**    
84 ```php    
85 $http->session(0); // Normal session 69 $http->session(0); // Normal session
86 $http->session(2); // Static file serving mode 70 $http->session(2); // Static file serving mode
87 ``` 71 %% ||
88 72 || ---- ||
89 --- 73 || ==== Caching System ==== ||
90 74 || ===== ##check_cache($page, $method): void## ===== ||
91 ### Caching System 75 || Determines if a page can be cached and prepares the cache check. ||
92 76 || **Parameters:** ||
93 #### `check_cache($page, $method): void` 77 || - ##$page## (string) - Page name to cache ||
94 Determines if a page can be cached and prepares the cache check. 78 || - ##$method## (string) - Request method/action (e.g., 'show', 'edit') ||
95 79 || **Caching Rules:** ||
96 **Parameters:** 80 || - ✅ Enabled for GET requests only ||
97 - `$page` (string) - Page name to cache 81 || - ✅ Disabled for POST requests ||
98 - `$method` (string) - Request method/action (e.g., 'show', 'edit') 82 || - ❌ Never cached for 'edit' or 'watch' methods ||
99 83 || - ✅ Only cached for anonymous users (no logged-in users) ||
100 **Caching Rules:** 84 || **Example:** ||
101 - ✅ Enabled for GET requests only 85 || %%php
102 - ✅ Disabled for POST requests    
103 - ❌ Never cached for 'edit' or 'watch' methods    
104 - ✅ Only cached for anonymous users (no logged-in users)    
105    
106 **Example:**    
107 ```php    
108 $http->check_cache('HomePage', 'show'); 86 $http->check_cache('HomePage', 'show');
109 ``` 87 %% ||
110 88 || ---- ||
111 --- 89 || ===== ##store_cache(): void## ===== ||
112 90 || Saves the generated page content to cache file. ||
113 #### `store_cache(): void` 91 || **Features:** ||
114 Saves the generated page content to cache file. 92 || - Retrieves output buffer content ||
115 93 || - Saves to cache file with proper permissions ||
116 **Features:** 94 || - Records cache metadata in database ||
117 - Retrieves output buffer content 95 || - Only executes if caching flag is set and user is anonymous ||
118 - Saves to cache file with proper permissions 96 || **Example:** ||
119 - Records cache metadata in database 97 || %%php
120 - Only executes if caching flag is set and user is anonymous    
121    
122 **Example:**    
123 ```php    
124 // Called at end of page rendering 98 // Called at end of page rendering
125 $http->store_cache(); 99 $http->store_cache();
126 ``` 100 %% ||
127 101 || ---- ||
128 --- 102 || ===== ##invalidate_page($page): int## ===== ||
129 103 || Invalidates all cached versions of a page. ||
130 #### `invalidate_page($page): int` 104 || **Parameters:** ||
131 Invalidates all cached versions of a page. 105 || - ##$page## (string) - Page name to invalidate ||
132 106 || **Returns:** ||
133 **Parameters:** 107 || - Number of cache entries invalidated ||
134 - `$page` (string) - Page name to invalidate 108 || **Process:** ||
135 109 || 1. Finds all cached versions (different methods/languages) ||
136 **Returns:** 110 || 2. Touches files to past timestamp (faster than deletion) ||
137 - Number of cache entries invalidated 111 || 3. Removes entries from cache metadata table ||
138 112 || 4. Returns count of invalidated caches ||
139 **Process:** 113 || **Example:** ||
140 1. Finds all cached versions (different methods/languages) 114 || %%php
141 2. Touches files to past timestamp (faster than deletion)    
142 3. Removes entries from cache metadata table    
143 4. Returns count of invalidated caches    
144    
145 **Example:**    
146 ```php    
147 $count = $http->invalidate_page('HomePage'); 115 $count = $http->invalidate_page('HomePage');
148 echo "Invalidated $count cache entries"; 116 echo "Invalidated $count cache entries";
149 ``` 117 %% ||
150 118 || ---- ||
151 --- 119 || ==== TLS/HTTPS Security ==== ||
152 120 || ===== ##secure_base_url(): void## ===== ||
153 ### TLS/HTTPS Security 121 || Switches base URL from HTTP to HTTPS. ||
154 122 || **Purpose:** ||
155 #### `secure_base_url(): void` 123 || - Ensures all subsequent URLs use HTTPS ||
156 Switches base URL from HTTP to HTTPS. 124 || - Stores original HTTP URL for fallback ||
157 125 || - Called when TLS session is detected ||
158 **Purpose:** 126 || **Example:** ||
159 - Ensures all subsequent URLs use HTTPS 127 || %%php
160 - Stores original HTTP URL for fallback    
161 - Called when TLS session is detected    
162    
163 **Example:**    
164 ```php    
165 $http->secure_base_url(); 128 $http->secure_base_url();
166 // $db->base_url now uses https:// 129 // $db->base_url now uses https://
167 ``` 130 %% ||
168 131 || ---- ||
169 --- 132 || ===== ##ensure_tls($url): void## ===== ||
170 133 || Enforces HTTPS for a specific URL and redirects if necessary. ||
171 #### `ensure_tls($url): void` 134 || **Parameters:** ||
172 Enforces HTTPS for a specific URL and redirects if necessary. 135 || - ##$url## (string) - URL to secure ||
173 136 || **Behavior:** ||
174 **Parameters:** 137 || - If not already HTTPS and TLS is enabled, forces HTTPS redirect ||
175 - `$url` (string) - URL to secure 138 || - Handles both relative and absolute URLs ||
176 139 || - Converts relative URLs using current server name ||
177 **Behavior:** 140 || **Example:** ||
178 - If not already HTTPS and TLS is enabled, forces HTTPS redirect 141 || %%php
179 - Handles both relative and absolute URLs    
180 - Converts relative URLs using current server name    
181    
182 **Example:**    
183 ```php    
184 $http->ensure_tls('/secure/payment'); 142 $http->ensure_tls('/secure/payment');
185 ``` 143 %% ||
186 144 || ---- ||
187 --- 145 || ==== IP Address Detection ==== ||
188 146 || ===== ##real_ip(): string## (Private) ===== ||
189 ### IP Address Detection 147 || Detects client's real IP address accounting for proxies. ||
190 148 || **Proxy Headers Checked (in order):** ||
191 #### `real_ip(): string` (Private) 149 || 1. ##HTTP_X_CLUSTER_CLIENT_IP## ||
192 Detects client's real IP address accounting for proxies. 150 || 2. ##HTTP_X_FORWARDED_FOR## (or custom header) ||
193 151 || 3. ##HTTP_CLIENT_IP## ||
194 **Proxy Headers Checked (in order):** 152 || 4. ##HTTP_X_REMOTE_ADDR## ||
195 1. `HTTP_X_CLUSTER_CLIENT_IP` 153 || 5. ##REMOTE_ADDR## (fallback) ||
196 2. `HTTP_X_FORWARDED_FOR` (or custom header) 154 || **Features:** ||
197 3. `HTTP_CLIENT_IP` 155 || - Filters out private/reserved IP ranges ||
198 4. `HTTP_X_REMOTE_ADDR` 156 || - Respects configured reverse proxy addresses ||
199 5. `REMOTE_ADDR` (fallback) 157 || - Returns ##'0.0.0.0'## as fallback ||
200 158 || **Configuration in Database:** ||
201 **Features:** 159 || - ##reverse_proxy_addresses## - Comma/space-separated proxy IPs ||
202 - Filters out private/reserved IP ranges 160 || - ##reverse_proxy_header## - Custom header name (default: ##X-Forwarded-For##) ||
203 - Respects configured reverse proxy addresses 161 || **Example:** ||
204 - Returns `'0.0.0.0'` as fallback 162 || %%php
205    
206 **Configuration in Database:**    
207 - `reverse_proxy_addresses` - Comma/space-separated proxy IPs    
208 - `reverse_proxy_header` - Custom header name (default: `X-Forwarded-For`)    
209    
210 **Example:**    
211 ```php    
212 $client_ip = $http->ip; // e.g., "203.0.113.42" 163 $client_ip = $http->ip; // e.g., "203.0.113.42"
213 ``` 164 %% ||
214 165 || ---- ||
215 --- 166 || ==== HTTPS Detection ==== ||
216 167 || ===== ##tls_session(): bool## (Private) ===== ||
217 ### HTTPS Detection 168 || Detects if current connection uses HTTPS/TLS. ||
218 169 || **Checks (any being true = HTTPS):** ||
219 #### `tls_session(): bool` (Private) 170 || - ##$_SERVER['HTTPS']## is 'on' ||
220 Detects if current connection uses HTTPS/TLS. 171 || - ##$_SERVER['SERVER_PORT']## is 443 ||
221 172 || - ##$_SERVER['HTTP_X_FORWARDED_PROTO']## is 'https' ||
222 **Checks (any being true = HTTPS):** 173 || - ##$_SERVER['HTTP_X_FORWARDED_SSL']## is 'on' ||
223 - `$_SERVER['HTTPS']` is 'on' 174 || - ##$_SERVER['HTTP_X_FORWARDED_PORT']## is 443 ||
224 - `$_SERVER['SERVER_PORT']` is 443 175 || ---- ||
225 - `$_SERVER['HTTP_X_FORWARDED_PROTO']` is 'https' 176 || ==== Security Headers ==== ||
226 - `$_SERVER['HTTP_X_FORWARDED_SSL']` is 'on' 177 || ===== ##http_security_headers(): void## ===== ||
227 - `$_SERVER['HTTP_X_FORWARDED_PORT']` is 443 178 || Sets security-related HTTP headers. ||
228 179 || **Headers Set:** ||
229 --- 180 || Header | Purpose | Config Key ||
230 181 || -------- | --------- | ------------ ||
231 ### Security Headers 182 || Content-Security-Policy | XSS/injection protection | ##csp## ||
232 183 || Permissions-Policy | Control browser features | ##permissions_policy## ||
233 #### `http_security_headers(): void` 184 || Referrer-Policy | Control referrer information | ##referrer_policy## ||
234 Sets security-related HTTP headers. 185 || Strict-Transport-Security | Force HTTPS | Auto (TLS only) ||
235 186 || X-Frame-Options | Clickjacking protection | Hardcoded: ##SAMEORIGIN## ||
236 **Headers Set:** 187 || X-Content-Type-Options | MIME sniffing prevention | Hardcoded: ##nosniff## ||
237 188 || **CSP Configuration Options:** ||
238 | Header | Purpose | Config Key | 189 || - ##0## - Disabled ||
239 |--------|---------|------------| 190 || - ##1## - Default policy (from ##csp.conf##) ||
240 | Content-Security-Policy | XSS/injection protection | `csp` | 191 || - ##2## - Custom policy (from ##csp_custom.conf##) ||
241 | Permissions-Policy | Control browser features | `permissions_policy` | 192 || **Example:** ||
242 | Referrer-Policy | Control referrer information | `referrer_policy` | 193 || %%php
243 | Strict-Transport-Security | Force HTTPS | Auto (TLS only) |    
244 | X-Frame-Options | Clickjacking protection | Hardcoded: `SAMEORIGIN` |    
245 | X-Content-Type-Options | MIME sniffing prevention | Hardcoded: `nosniff` |    
246    
247 **CSP Configuration Options:**    
248 - `0` - Disabled    
249 - `1` - Default policy (from `csp.conf`)    
250 - `2` - Custom policy (from `csp_custom.conf`)    
251    
252 **Example:**    
253 ```php    
254 $http->http_security_headers(); 194 $http->http_security_headers();
255 ``` 195 %% ||
256 196 || ---- ||
257 --- 197 || ==== HTTP Methods ==== ||
258 198 || ===== ##redirect($url, $permanent = false): void## ===== ||
259 ### HTTP Methods 199 || Performs an HTTP redirect. ||
260 200 || **Parameters:** ||
261 #### `redirect($url, $permanent = false): void` 201 || - ##$url## (string) - Target URL ||
262 Performs an HTTP redirect. 202 || - ##$permanent## (bool) - Use 301 (permanent) vs 302 (temporary) ||
263 203 || **Features:** ||
264 **Parameters:** 204 || - Decodes ##&## entities to prevent broken redirects ||
265 - `$url` (string) - Target URL 205 || - Only works if headers not yet sent ||
266 - `$permanent` (bool) - Use 301 (permanent) vs 302 (temporary) 206 || - Uses output buffering to work anywhere in page processing ||
267 207 || **Example:** ||
268 **Features:** 208 || %%php
269 - Decodes `&` entities to prevent broken redirects    
270 - Only works if headers not yet sent    
271 - Uses output buffering to work anywhere in page processing    
272    
273 **Example:**    
274 ```php    
275 $http->redirect('http://example.com/new-page', true); // 301 209 $http->redirect('http://example.com/new-page', true); // 301
276 $http->redirect('/wiki/HomePage'); // 302 210 $http->redirect('/wiki/HomePage'); // 302
277 ``` 211 %% ||
278 212 || ---- ||
279 --- 213 || ===== ##terminate(): void## ===== ||
280 214 || Safe exit/die with cleanup. ||
281 #### `terminate(): void` 215 || **Cleanup Operations:** ||
282 Safe exit/die with cleanup. 216 || - Saves diagnostic logs to session flash data ||
283 217 || - Ends script execution ||
284 **Cleanup Operations:** 218 || **Example:** ||
285 - Saves diagnostic logs to session flash data 219 || %%php
286 - Ends script execution    
287    
288 **Example:**    
289 ```php    
290 $http->terminate(); 220 $http->terminate();
291 ``` 221 %% ||
292 222 || ---- ||
293 --- 223 || ===== ##status($code): void## ===== ||
294 224 || Sets HTTP response status code. ||
295 #### `status($code): void` 225 || **Supported Status Codes:** ||
296 Sets HTTP response status code. 226 || %%php
297    
298 **Supported Status Codes:**    
299 ```php    
300 200 => 'OK' 227 200 => 'OK'
301 206 => 'Partial Content' 228 206 => 'Partial Content'
302 301 => 'Moved Permanently' 229 301 => 'Moved Permanently'
313 500 => 'Internal Server Error' 240 500 => 'Internal Server Error'
314 501 => 'Not Implemented' 241 501 => 'Not Implemented'
315 503 => 'Service Unavailable' 242 503 => 'Service Unavailable'
316 ``` 243 %% ||
317 244 || **Example:** ||
318 **Example:** 245 || %%php
319 ```php    
320 $http->status(404); // Send 404 Not Found 246 $http->status(404); // Send 404 Not Found
321 ``` 247 %% ||
322 248 || ---- ||
323 --- 249 || ==== Caching Control ==== ||
324 250 || ===== ##no_cache($client_only = true): void## ===== ||
325 ### Caching Control 251 || Disables caching of the current page. ||
326 252 || **Parameters:** ||
327 #### `no_cache($client_only = true): void` 253 || - ##$client_only## (bool, default: TRUE) ||
328 Disables caching of the current page. 254 || - ##TRUE##: Disable browser cache only ||
329 255 || - ##FALSE##: Disable both browser and server cache ||
330 **Parameters:** 256 || **Headers Set:** ||
331 - `$client_only` (bool, default: TRUE) 257 || - ##Last-Modified: <current-time>## (always fresh) ||
332   - `TRUE`: Disable browser cache only 258 || - ##Cache-Control: no-store## ||
333   - `FALSE`: Disable both browser and server cache 259 || **Example:** ||
334 260 || %%php
335 **Headers Set:**    
336 - `Last-Modified: <current-time>` (always fresh)    
337 - `Cache-Control: no-store`    
338    
339 **Example:**    
340 ```php    
341 $http->no_cache(); // Client-side only 261 $http->no_cache(); // Client-side only
342 $http->no_cache(false); // Both client & server 262 $http->no_cache(false); // Both client & server
343 ``` 263 %% ||
344 264 || ---- ||
345 --- 265 || ===== ##cache_promisc(): void## ===== ||
346 266 || Marks page as publicly cacheable. ||
347 #### `cache_promisc(): void` 267 || **Headers Set:** ||
348 Marks page as publicly cacheable. 268 || - ##Cache-Control: public## ||
349 269 || **Example:** ||
350 **Headers Set:** 270 || %%php
351 - `Cache-Control: public`    
352    
353 **Example:**    
354 ```php    
355 $http->cache_promisc(); 271 $http->cache_promisc();
356 ``` 272 %% ||
357 273 || ---- ||
358 --- 274 || ==== Language Negotiation ==== ||
359 275 || ===== ##user_agent_language(): string## ===== ||
360 ### Language Negotiation 276 || Determines best language based on browser preferences. ||
361 277 || **Features:** ||
362 #### `user_agent_language(): string` 278 || - Follows RFC 9110 section 12.5.4 (HTTP Accept-Language) ||
363 Determines best language based on browser preferences. 279 || - Parses ##Accept-Language## header with quality factors ||
364 280 || - Attempts exact match first, then language fallback ||
365 **Features:** 281 || - Falls back to default system language ||
366 - Follows RFC 9110 section 12.5.4 (HTTP Accept-Language) 282 || **Example Header:** ||
367 - Parses `Accept-Language` header with quality factors 283 || %%
368 - Attempts exact match first, then language fallback    
369 - Falls back to default system language    
370    
371 **Example Header:**    
372 ```    
373 Accept-Language: en-US,en;q=0.9,de;q=0.8 284 Accept-Language: en-US,en;q=0.9,de;q=0.8
374 ``` 285 %% ||
375 286 || **Returns:** ||
376 **Returns:** 287 || - Language code (e.g., 'en', 'en-US', 'de') ||
377 - Language code (e.g., 'en', 'en-US', 'de') 288 || ---- ||
378 289 || ===== ##available_languages($subset = true): array## ===== ||
379 --- 290 || Returns list of available language translations. ||
380 291 || **Parameters:** ||
381 #### `available_languages($subset = true): array` 292 || - ##$subset## (bool, default: TRUE) ||
382 Returns list of available language translations. 293 || - ##TRUE##: Only allowed languages ||
383 294 || - ##FALSE##: All available languages ||
384 **Parameters:** 295 || **Features:** ||
385 - `$subset` (bool, default: TRUE) 296 || - Scans ##LANG_DIR## for language files ||
386   - `TRUE`: Only allowed languages 297 || - Filters by ##allowed_languages## config if set ||
387   - `FALSE`: All available languages 298 || - Caches result in session ||
388 299 || - System language always included ||
389 **Features:** 300 || **Returns:** ||
390 - Scans `LANG_DIR` for language files 301 || - Associative array: ##['en' => 'en', 'de' => 'de', ...]## ||
391 - Filters by `allowed_languages` config if set 302 || **Example:** ||
392 - Caches result in session 303 || %%php
393 - System language always included    
394    
395 **Returns:**    
396 - Associative array: `['en' => 'en', 'de' => 'de', ...]`    
397    
398 **Example:**    
399 ```php    
400 $all_langs = $http->available_languages(false); 304 $all_langs = $http->available_languages(false);
401 $allowed = $http->available_languages(true); 305 $allowed = $http->available_languages(true);
402 ``` 306 %% ||
403 307 || ---- ||
404 --- 308 || ==== File Serving ==== ||
405 309 || ===== ##sendfile($path, $filename = null, $age = null): void## ===== ||
406 ### File Serving 310 || Serves files with proper HTTP headers and caching. ||
407 311 || **Parameters:** ||
408 #### `sendfile($path, $filename = null, $age = null): void` 312 || - ##$path## (string) - File path (or HTTP_XXX constant for error pages) ||
409 Serves files with proper HTTP headers and caching. 313 || - ##$filename## (string, optional) - Custom download filename ||
410 314 || - ##$age## (int, optional) - Cache age in days ||
411 **Parameters:** 315 || **Features:** ||
412 - `$path` (string) - File path (or HTTP_XXX constant for error pages) 316 || - HTTP range request support (partial file downloads) ||
413 - `$filename` (string, optional) - Custom download filename 317 || - ETag and Last-Modified conditional requests ||
414 - `$age` (int, optional) - Cache age in days 318 || - Proper MIME type detection ||
415 319 || - Content-Security-Policy for special file types ||
416 **Features:** 320 || - Streaming for large files ||
417 - HTTP range request support (partial file downloads) 321 || - GZip compression for text files ||
418 - ETag and Last-Modified conditional requests 322 || **Special Paths:** ||
419 - Proper MIME type detection 323 || %%php
420 - Content-Security-Policy for special file types    
421 - Streaming for large files    
422 - GZip compression for text files    
423    
424 **Special Paths:**    
425 ```php    
426 $http->sendfile(404); // Serves file defined by HTTP_404 constant 324 $http->sendfile(404); // Serves file defined by HTTP_404 constant
427 $http->sendfile(403); // Serves file defined by HTTP_403 constant 325 $http->sendfile(403); // Serves file defined by HTTP_403 constant
428 ``` 326 %% ||
429 327 || **Example:** ||
430 **Example:** 328 || %%php
431 ```php    
432 $http->sendfile('uploads/document.pdf', 'my-document.pdf', 30); 329 $http->sendfile('uploads/document.pdf', 'my-document.pdf', 30);
433 ``` 330 %% ||
434 331 || ---- ||
435 --- 332 || ===== ##mime_type($path): string## ===== ||
436 333 || Returns MIME type for a file. ||
437 #### `mime_type($path): string` 334 || **Returns:** ||
438 Returns MIME type for a file. 335 || - MIME type string (e.g., 'application/pdf') ||
439 336 || - Default: ##'application/octet-stream'## ||
440 **Returns:** 337 || **Example:** ||
441 - MIME type string (e.g., 'application/pdf') 338 || %%php
442 - Default: `'application/octet-stream'`    
443    
444 **Example:**    
445 ```php    
446 $mime = $http->mime_type('file.pdf'); // 'application/pdf' 339 $mime = $http->mime_type('file.pdf'); // 'application/pdf'
447 ``` 340 %% ||
448 341 || ---- ||
449 --- 342 || ===== ##mime_types(): array## (Private) ===== ||
450 343 || Loads and caches MIME types from configuration. ||
451 #### `mime_types(): array` (Private) 344 || **Features:** ||
452 Loads and caches MIME types from configuration. 345 || - Reads from ##config/mime.types## ||
453 346 || - Caches to ##cache/config/mime.types## ||
454 **Features:** 347 || - Reloads if config is updated ||
455 - Reads from `config/mime.types` 348 || ---- ||
456 - Caches to `cache/config/mime.types` 349 || ==== Compression ==== ||
457 - Reloads if config is updated 350 || ===== ##gzip(): void## ===== ||
458 351 || Compresses HTTP response with gzip/x-gzip. ||
459 --- 352 || **Features:** ||
460 353 || - Manually implements gzip (not relying on zlib.output_compression) ||
461 ### Compression 354 || - Produces correct ##Content-Length## header ||
462 355 || - Only compresses if: ||
463 #### `gzip(): void` 356 || - 860 bytes < content < 1 MB ||
464 Compresses HTTP response with gzip/x-gzip. 357 || - Client accepts compression ||
465 358 || - Headers not already sent ||
466 **Features:** 359 || **Example:** ||
467 - Manually implements gzip (not relying on zlib.output_compression) 360 || %%php
468 - Produces correct `Content-Length` header    
469 - Only compresses if:    
470   - 860 bytes < content < 1 MB    
471   - Client accepts compression    
472   - Headers not already sent    
473    
474 **Example:**    
475 ```php    
476 $http->gzip(); 361 $http->gzip();
477 ``` 362 %% ||
478 363 || ---- ||
479 --- 364 || ==== Utility Methods ==== ||
480 365 || ===== ##parse_str($str): array## (Private) ===== ||
481 ### Utility Methods 366 || Parses URL-encoded strings with special character handling. ||
482 367 || **Purpose:** ||
483 #### `parse_str($str): array` (Private) 368 || - Safely handles special characters in query/form data ||
484 Parses URL-encoded strings with special character handling. 369 || - Converts encoding properly ||
485 370 || **Example:** ||
486 **Purpose:** 371 || %%php
487 - Safely handles special characters in query/form data    
488 - Converts encoding properly    
489    
490 **Example:**    
491 ```php    
492 $data = $http->parse_str('name=John&age=30'); 372 $data = $http->parse_str('name=John&age=30');
493 ``` 373 %% ||
494 374 || ---- ||
495 --- 375 || ===== ##request_uri(): string## (Private) ===== ||
496 376 || Extracts and normalizes REQUEST_URI from server. ||
497 #### `request_uri(): string` (Private) 377 || **Normalization:** ||
498 Extracts and normalizes REQUEST_URI from server. 378 || - Removes base URL prefix ||
499 379 || - Removes spaces ||
500 **Normalization:** 380 || - Collapses multiple slashes ||
501 - Removes base URL prefix 381 || - Removes ##..## path traversal attempts ||
502 - Removes spaces 382 || - Removes leading/trailing slashes ||
503 - Collapses multiple slashes 383 || ---- ||
504 - Removes `..` path traversal attempts 384 || ===== ##cut_prefix($prefix, $path): string## (Private) ===== ||
505 - Removes leading/trailing slashes 385 || Removes prefix from path (case-insensitive). ||
506 386 || ---- ||
507 --- 387 || ===== ##get_header_conf($file_name): string## (Private) ===== ||
508 388 || Loads security header configuration from files. ||
509 #### `cut_prefix($prefix, $path): string` (Private) 389 || **Files Supported:** ||
510 Removes prefix from path (case-insensitive). 390 || - ##csp.conf## / ##csp_custom.conf## ||
511 391 || - ##permissions_policy.conf## / ##permissions_policy_custom.conf## ||
512 --- 392 || ---- ||
513 393 || === Configuration Dependencies === ||
514 #### `get_header_conf($file_name): string` (Private) 394 || The class relies on these database configuration settings: ||
515 Loads security header configuration from files. 395 || Setting | Type | Purpose ||
516 396 || --------- | ------ | --------- ||
517 **Files Supported:** 397 || ##base_url## | string | Wiki's base URL ||
518 - `csp.conf` / `csp_custom.conf` 398 || ##tls## | bool | Enable HTTPS enforcement ||
519 - `permissions_policy.conf` / `permissions_policy_custom.conf` 399 || ##cache## | bool | Enable page caching ||
520 400 || ##cache_ttl## | int | Cache lifetime in seconds ||
521 --- 401 || ##session_store## | int | 1=File, 0=Database ||
522 402 || ##system_seed_hash## | string | Session encryption seed ||
523 ## Configuration Dependencies 403 || ##cookie_prefix## | string | Session cookie prefix ||
524 404 || ##cookie_path## | string | Cookie path ||
525 The class relies on these database configuration settings: 405 || ##allow_persistent_cookie## | bool | Allow persistent login ||
526 406 || ##session_length## | int | Session lifetime in seconds ||
527 | Setting | Type | Purpose | 407 || ##reverse_proxy_addresses## | string | Comma/space-separated proxy IPs ||
528 |---------|------|---------| 408 || ##reverse_proxy_header## | string | Custom X-Forwarded header ||
529 | `base_url` | string | Wiki's base URL | 409 || ##language## | string | Default language code ||
530 | `tls` | bool | Enable HTTPS enforcement | 410 || ##multilanguage## | bool | Enable language negotiation ||
531 | `cache` | bool | Enable page caching | 411 || ##allowed_languages## | string | Comma/space-separated allowed langs ||
532 | `cache_ttl` | int | Cache lifetime in seconds | 412 || ##enable_security_headers## | bool | Send security headers ||
533 | `session_store` | int | 1=File, 0=Database | 413 || ##csp## | int | CSP setting (0/1/2) ||
534 | `system_seed_hash` | string | Session encryption seed | 414 || ##permissions_policy## | int | Permissions-Policy setting (0/1/2) ||
535 | `cookie_prefix` | string | Session cookie prefix | 415 || ##referrer_policy## | int | Referrer-Policy setting (0-8) ||
536 | `cookie_path` | string | Cookie path | 416 || ---- ||
537 | `allow_persistent_cookie` | bool | Allow persistent login | 417 || === Constants Used === ||
538 | `session_length` | int | Session lifetime in seconds | 418 || Constant | Type | Purpose ||
539 | `reverse_proxy_addresses` | string | Comma/space-separated proxy IPs | 419 || ---------- | ------ | --------- ||
540 | `reverse_proxy_header` | string | Custom X-Forwarded header | 420 || ##IN_WACKO## | bool | Security check (exit if not defined) ||
541 | `language` | string | Default language code | 421 || ##CHMOD_SAFE## | int | File permissions for cache files ||
542 | `multilanguage` | bool | Enable language negotiation | 422 || ##CHMOD_FILE## | int | File permissions for config cache ||
543 | `allowed_languages` | string | Comma/space-separated allowed langs | 423 || ##CACHE_PAGE_DIR## | string | Page cache directory ||
544 | `enable_security_headers` | bool | Send security headers | 424 || ##CACHE_SESSION_DIR## | string | Session cache directory ||
545 | `csp` | int | CSP setting (0/1/2) | 425 || ##CACHE_CONFIG_DIR## | string | Config cache directory ||
546 | `permissions_policy` | int | Permissions-Policy setting (0/1/2) | 426 || ##CONFIG_DIR## | string | Configuration directory ||
547 | `referrer_policy` | int | Referrer-Policy setting (0-8) | 427 || ##LANG_DIR## | string | Language files directory ||
548 428 || ##DAYSECS## | int | Seconds in a day (86400) ||
549 --- 429 || ##HTTP_404## | string | Path to 404 error page ||
550 430 || ##HTTP_403## | string | Path to 403 error page ||
551 ## Constants Used 431 |#
552 432
553 | Constant | Type | Purpose | 433 ----
554 |----------|------|---------| 434
555 | `IN_WACKO` | bool | Security check (exit if not defined) | 435 === Workflow Examples ===
556 | `CHMOD_SAFE` | int | File permissions for cache files | 436
557 | `CHMOD_FILE` | int | File permissions for config cache | 437 ==== Example 1: Handling a GET Request ====
558 | `CACHE_PAGE_DIR` | string | Page cache directory | 438
559 | `CACHE_SESSION_DIR` | string | Session cache directory | 439 %%php
560 | `CACHE_CONFIG_DIR` | string | Config cache directory |    
561 | `CONFIG_DIR` | string | Configuration directory |    
562 | `LANG_DIR` | string | Language files directory |    
563 | `DAYSECS` | int | Seconds in a day (86400) |    
564 | `HTTP_404` | string | Path to 404 error page |    
565 | `HTTP_403` | string | Path to 403 error page |    
566    
567 ---    
568    
569 ## Workflow Examples    
570    
571 ### Example 1: Handling a GET Request    
572    
573 ```php    
574 // In main wiki entry point 440 // In main wiki entry point
575 $http = new Http($db); 441 $http = new Http($db);
576 $http->session(0); // Start session 442 $http->session(0); // Start session
588 454
589 // Possibly compress output 455 // Possibly compress output
590 $http->gzip(); 456 $http->gzip();
591 ``` 457 %%
592 458
593 ### Example 2: Handling TLS/HTTPS Upgrade 459 ==== Example 2: Handling TLS/HTTPS Upgrade ====
594 460
595 ```php 461 %%php
596 $http = new Http($db); // Constructor detects TLS requirement 462 $http = new Http($db); // Constructor detects TLS requirement
597 // If TLS is enabled and user wasn't in TLS before: 463 // If TLS is enabled and user wasn't in TLS before:
598 // - Sets TLS session flag 464 // - Sets TLS session flag
599 // - Marks session with TLS cookie 465 // - Marks session with TLS cookie
600 // - Redirects to HTTPS version 466 // - Redirects to HTTPS version
601 ``` 467 %%
602 468
603 ### Example 3: Invalidating Cache After Page Edit 469 ==== Example 3: Invalidating Cache After Page Edit ====
604 470
605 ```php 471 %%php
606 // User edits a page 472 // User edits a page
607 $http = new Http($db); 473 $http = new Http($db);
608 $count = $http->invalidate_page('HomePage'); 474 $count = $http->invalidate_page('HomePage');
609 // All cached versions (different languages, methods) are invalidated 475 // All cached versions (different languages, methods) are invalidated
610 ``` 476 %%
611 477
612 ### Example 4: Serving a File 478 ==== Example 4: Serving a File ====
613 479
614 ```php 480 %%php
615 $http = new Http($db); 481 $http = new Http($db);
616 $http->session(2); // Static file mode - no session replay prevention 482 $http->session(2); // Static file mode - no session replay prevention
617 483
618 // Serve with 30-day cache 484 // Serve with 30-day cache
619 $http->sendfile('uploads/manual.pdf', 'user-manual.pdf', 30); 485 $http->sendfile('uploads/manual.pdf', 'user-manual.pdf', 30);
620 ``` 486 %%
621 487
622 --- 488 ----
623 489
624 ## Security Considerations 490 === Security Considerations ===
625 491
626 ### 1. **IP Address Spoofing** 492 ==== 1. **IP Address Spoofing** ====
627 - Validates IPs against private ranges 493   - Validates IPs against private ranges
628 - Filters proxy-provided IPs appropriately 494   - Filters proxy-provided IPs appropriately
629 - Configurable reverse proxy trust 495   - Configurable reverse proxy trust
630 496
631 ### 2. **Session Security** 497 ==== 2. **Session Security** ====
632 - Binds sessions to IP address 498   - Binds sessions to IP address
633 - Binds sessions to TLS status 499   - Binds sessions to TLS status
634 - Supports both file and database storage 500   - Supports both file and database storage
635 - HttpOnly cookies by default 501   - HttpOnly cookies by default
636 502
637 ### 3. **TLS Enforcement** 503 ==== 3. **TLS Enforcement** ====
638 - Automatic HTTPS upgrade when configured 504   - Automatic HTTPS upgrade when configured
639 - Marks TLS sessions to prevent downgrade attacks 505   - Marks TLS sessions to prevent downgrade attacks
640 - HSTS header support 506   - HSTS header support
641 507
642 ### 4. **Content Security** 508 ==== 4. **Content Security** ====
643 - CSP headers to prevent XSS 509   - CSP headers to prevent XSS
644 - X-Frame-Options to prevent clickjacking 510   - X-Frame-Options to prevent clickjacking
645 - X-Content-Type-Options to prevent MIME sniffing 511   - X-Content-Type-Options to prevent MIME sniffing
646 - Referrer-Policy control 512   - Referrer-Policy control
647 - Permissions-Policy for browser features 513   - Permissions-Policy for browser features
648 514
649 ### 5. **File Serving** 515 ==== 5. **File Serving** ====
650 - Validates file existence and readability 516   - Validates file existence and readability
651 - Prevents directory traversal via `realpath()` 517   - Prevents directory traversal via ##realpath()##
652 - Rejects symbolic links 518   - Rejects symbolic links
653 - Special CSP for SVG and PDF files 519   - Special CSP for SVG and PDF files
654 520
655 ### 6. **Cache Security** 521 ==== 6. **Cache Security** ====
656 - Cached only for anonymous users 522   - Cached only for anonymous users
657 - Disabled for sensitive operations (edit, watch) 523   - Disabled for sensitive operations (edit, watch)
658 - Only GET requests cached 524   - Only GET requests cached
659 525
660 --- 526 ----
661 527
662 ## Performance Optimization 528 === Performance Optimization ===
663 529
664 ### 1. **Page Caching** 530 ==== 1. **Page Caching** ====
665 - Stores full HTML output 531   - Stores full HTML output
666 - TTL-based expiration 532   - TTL-based expiration
667 - Language and method-aware caching 533   - Language and method-aware caching
668 - Conditional request support (304 Not Modified) 534   - Conditional request support (304 Not Modified)
669 535
670 ### 2. **MIME Type Caching** 536 ==== 2. **MIME Type Caching** ====
671 - Loads MIME types once and caches 537   - Loads MIME types once and caches
672 - Regenerates only when config changes 538   - Regenerates only when config changes
673 539
674 ### 3. **Session Options** 540 ==== 3. **Session Options** ====
675 - File-based sessions for simple deployments 541   - File-based sessions for simple deployments
676 - Database sessions for distributed systems 542   - Database sessions for distributed systems
677 543
678 ### 4. **Compression** 544 ==== 4. **Compression** ====
679 - Manual gzip implementation 545   - Manual gzip implementation
680 - Proper Content-Length generation 546   - Proper Content-Length generation
681 - Only compresses appropriate sizes 547   - Only compresses appropriate sizes
682 548
683 --- 549 ----
684 550
685 ## Debugging 551 === Debugging ===
686 552
687 The class integrates with WackoWiki's diagnostic system: 553 The class integrates with WackoWiki's diagnostic system:
688 554
689 ```php 555 %%php
690 // Diagnostic messages are preserved across redirects 556 // Diagnostic messages are preserved across redirects
691 // via session flash data 557 // via session flash data
692 558
693 // Check cached pages (debug comments in output): 559 // Check cached pages (debug comments in output):
694 // <!-- WackoWiki Caching Engine: page cached at 2024-01-15 12:30:45 GMT --> 560 // <!-- WackoWiki Caching Engine: page cached at 2024-01-15 12:30:45 GMT -->
695 ``` 561 %%
696 562
697 --- 563 ----
698 564
699 ## Related Classes 565 === Related Classes ===
700 566   - **Session Classes** (##SessionFileStore##, ##SessionDbalStore##) - Session management backends
701 - **Session Classes** (`SessionFileStore`, `SessionDbalStore`) - Session management backends 567   - **Database Class** - Configuration and cache metadata storage
702 - **Database Class** - Configuration and cache metadata storage 568   - **Ut Utility Class** - String/path utilities
703 - **Ut Utility Class** - String/path utilities 569   - **Diag Class** - Diagnostic logging
704 - **Diag Class** - Diagnostic logging 570
705 571 ----
706 --- 572
707 573 === Version History ===
708 ## Version History 574   - Supports PHP 8.0+ (uses match expressions, union types)
709 575   - Follows RFC 9110 for HTTP header handling
710 - Supports PHP 8.0+ (uses match expressions, union types) 576   - Modern cookie security practices
711 - Follows RFC 9110 for HTTP header handling 577
712 - Modern cookie security practices 578 ----
713 579
714 --- 580 === Conclusion ===
715 581
716 ## Conclusion 582 The ##Http## class is the central request/response handler in WackoWiki, managing everything from session initialization to security headers to file serving. Understanding this class is essential for:
717 583   - Extending WackoWiki with custom request handlers
718 The `Http` class is the central request/response handler in WackoWiki, managing everything from session initialization to security headers to file serving. Understanding this class is essential for: 584   - Implementing custom session logic
719 585   - Adding new security policies
720 - Extending WackoWiki with custom request handlers 586   - Optimizing cache strategies
721 - Implementing custom session logic 587   - Debugging HTTP-related issues
722 - Adding new security policies    
723 - Optimizing cache strategies    
724 - Debugging HTTP-related issues