Difference between revisions for Users / Eo Ny / dev




← Previous edit
Next edit →

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