Difference between revisions for Users / Eo Ny / dev





Next edit →

Version1 Version2 Differences
10 10
11 11 ----
12 12
13   === Class Properties ===  
14 13
15   ==== Public Properties ====  
16 14
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   || ==== Private Properties ==== ||  
25   || Property | Type | Description ||  
26   || ---------- | ------ | ------------- ||  
27   || ##$db## | object | Database connection reference ||  
28   || ##$tls_mark## | string | Cookie name for TLS session marking ||  
29   || ##$page## | string | Current page name being processed ||  
30   || ##$hash## | string | SHA1 hash of the page name ||  
31   || ##$query## | string | Encoded query string ||  
32   || ##$lang## | string | Current language code ||  
33   || ##$file## | string | Cache file path ||  
34   || ##$caching## | int | Flag indicating if page should be cached (0 or 1) ||  
35   || ---- ||  
36   || === Constructor === ||  
37   || %%php  
38   public function __construct(&$db)  
39   %% ||  
40   || **Purpose:** Initializes the Http object and sets up HTTP session handling. ||  
41   || **Parameters:** ||  
42   || - ##$db## - Database object reference ||  
43   || **Initialization Steps:** ||  
44   || 1. Stores database reference ||  
45   || 2. Extracts and normalizes REQUEST_URI ||  
46   || 3. Detects TLS/HTTPS session status ||  
47   || 4. Determines client's real IP address ||  
48   || 5. Sets up TLS mark cookie name ||  
49   || 6. Enforces TLS session upgrade if needed ||  
50   || **Example:** ||  
51   || %%php  
52   $http = new Http($db);  
53   %% ||  
54   || ---- ||  
55   || === Core Methods === ||  
56   || ==== Session Management ==== ||  
57   || ===== ##session($route): void## ===== ||  
58   || Initializes the session handler (file-based or database-based). ||  
59   || **Parameters:** ||  
60   || - ##$route## (int) - Routing flag: ||  
61   || - Bit 2 (##$route & 2##): Enable static mode for files/freecap (disables replay prevention and ID regeneration) ||  
62   || **Features:** ||  
63   || - Selects storage backend (file or database) ||  
64   || - Configures cookie settings (security, path, httponly) ||  
65   || - Binds IP and TLS validation ||  
66   || - Recovers diagnostic logs from previous session ||  
67   || **Example:** ||  
68   || %%php  
69   $http->session(0); // Normal session  
70   $http->session(2); // Static file serving mode  
71   %% ||  
72   || ---- ||  
73   || ==== Caching System ==== ||  
74   || ===== ##check_cache($page, $method): void## ===== ||  
75   || Determines if a page can be cached and prepares the cache check. ||  
76   || **Parameters:** ||  
77   || - ##$page## (string) - Page name to cache ||  
78   || - ##$method## (string) - Request method/action (e.g., 'show', 'edit') ||  
79   || **Caching Rules:** ||  
80   || - ✅ Enabled for GET requests only ||  
81   || - ✅ Disabled for POST requests ||  
82   || - ❌ Never cached for 'edit' or 'watch' methods ||  
83   || - ✅ Only cached for anonymous users (no logged-in users) ||  
84   || **Example:** ||  
85   || %%php  
86   $http->check_cache('HomePage', 'show');  
87   %% ||  
88   || ---- ||  
89   || ===== ##store_cache(): void## ===== ||  
90   || Saves the generated page content to cache file. ||  
91   || **Features:** ||  
92   || - Retrieves output buffer content ||  
93   || - Saves to cache file with proper permissions ||  
94   || - Records cache metadata in database ||  
95   || - Only executes if caching flag is set and user is anonymous ||  
96   || **Example:** ||  
97   || %%php  
98   // Called at end of page rendering  
99   $http->store_cache();  
100   %% ||  
101   || ---- ||  
102   || ===== ##invalidate_page($page): int## ===== ||  
103   || Invalidates all cached versions of a page. ||  
104   || **Parameters:** ||  
105   || - ##$page## (string) - Page name to invalidate ||  
106   || **Returns:** ||  
107   || - Number of cache entries invalidated ||  
108   || **Process:** ||  
109   || 1. Finds all cached versions (different methods/languages) ||  
110   || 2. Touches files to past timestamp (faster than deletion) ||  
111   || 3. Removes entries from cache metadata table ||  
112   || 4. Returns count of invalidated caches ||  
113   || **Example:** ||  
114   || %%php  
115   $count = $http->invalidate_page('HomePage');  
116   echo "Invalidated $count cache entries";  
117   %% ||  
118   || ---- ||  
119   || ==== TLS/HTTPS Security ==== ||  
120   || ===== ##secure_base_url(): void## ===== ||  
121   || Switches base URL from HTTP to HTTPS. ||  
122   || **Purpose:** ||  
123   || - Ensures all subsequent URLs use HTTPS ||  
124   || - Stores original HTTP URL for fallback ||  
125   || - Called when TLS session is detected ||  
126   || **Example:** ||  
127   || %%php  
128   $http->secure_base_url();  
129   // $db->base_url now uses https://  
130   %% ||  
131   || ---- ||  
132   || ===== ##ensure_tls($url): void## ===== ||  
133   || Enforces HTTPS for a specific URL and redirects if necessary. ||  
134   || **Parameters:** ||  
135   || - ##$url## (string) - URL to secure ||  
136   || **Behavior:** ||  
137   || - If not already HTTPS and TLS is enabled, forces HTTPS redirect ||  
138   || - Handles both relative and absolute URLs ||  
139   || - Converts relative URLs using current server name ||  
140   || **Example:** ||  
141   || %%php  
142   $http->ensure_tls('/secure/payment');  
143   %% ||  
144   || ---- ||  
145   || ==== IP Address Detection ==== ||  
146   || ===== ##real_ip(): string## (Private) ===== ||  
147   || Detects client's real IP address accounting for proxies. ||  
148   || **Proxy Headers Checked (in order):** ||  
149   || 1. ##HTTP_X_CLUSTER_CLIENT_IP## ||  
150   || 2. ##HTTP_X_FORWARDED_FOR## (or custom header) ||  
151   || 3. ##HTTP_CLIENT_IP## ||  
152   || 4. ##HTTP_X_REMOTE_ADDR## ||  
153   || 5. ##REMOTE_ADDR## (fallback) ||  
154   || **Features:** ||  
155   || - Filters out private/reserved IP ranges ||  
156   || - Respects configured reverse proxy addresses ||  
157   || - Returns ##'0.0.0.0'## as fallback ||  
158   || **Configuration in Database:** ||  
159   || - ##reverse_proxy_addresses## - Comma/space-separated proxy IPs ||  
160   || - ##reverse_proxy_header## - Custom header name (default: ##X-Forwarded-For##) ||  
161   || **Example:** ||  
162   || %%php  
163   $client_ip = $http->ip; // e.g., "203.0.113.42"  
164   %% ||  
165   || ---- ||  
166   || ==== HTTPS Detection ==== ||  
167   || ===== ##tls_session(): bool## (Private) ===== ||  
168   || Detects if current connection uses HTTPS/TLS. ||  
169   || **Checks (any being true = HTTPS):** ||  
170   || - ##$_SERVER['HTTPS']## is 'on' ||  
171   || - ##$_SERVER['SERVER_PORT']## is 443 ||  
172   || - ##$_SERVER['HTTP_X_FORWARDED_PROTO']## is 'https' ||  
173   || - ##$_SERVER['HTTP_X_FORWARDED_SSL']## is 'on' ||  
174   || - ##$_SERVER['HTTP_X_FORWARDED_PORT']## is 443 ||  
175   || ---- ||  
176   || ==== Security Headers ==== ||  
177   || ===== ##http_security_headers(): void## ===== ||  
178   || Sets security-related HTTP headers. ||  
179   || **Headers Set:** ||  
180   || Header | Purpose | Config Key ||  
181   || -------- | --------- | ------------ ||  
182   || Content-Security-Policy | XSS/injection protection | ##csp## ||  
183   || Permissions-Policy | Control browser features | ##permissions_policy## ||  
184   || Referrer-Policy | Control referrer information | ##referrer_policy## ||  
185   || Strict-Transport-Security | Force HTTPS | Auto (TLS only) ||  
186   || X-Frame-Options | Clickjacking protection | Hardcoded: ##SAMEORIGIN## ||  
187   || X-Content-Type-Options | MIME sniffing prevention | Hardcoded: ##nosniff## ||  
188   || **CSP Configuration Options:** ||  
189   || - ##0## - Disabled ||  
190   || - ##1## - Default policy (from ##csp.conf##) ||  
191   || - ##2## - Custom policy (from ##csp_custom.conf##) ||  
192   || **Example:** ||  
193   || %%php  
194   $http->http_security_headers();  
195   %% ||  
196   || ---- ||  
197   || ==== HTTP Methods ==== ||  
198   || ===== ##redirect($url, $permanent = false): void## ===== ||  
199   || Performs an HTTP redirect. ||  
200   || **Parameters:** ||  
201   || - ##$url## (string) - Target URL ||  
202   || - ##$permanent## (bool) - Use 301 (permanent) vs 302 (temporary) ||  
203   || **Features:** ||  
204   || - Decodes ##&## entities to prevent broken redirects ||  
205   || - Only works if headers not yet sent ||  
206   || - Uses output buffering to work anywhere in page processing ||  
207   || **Example:** ||  
208   || %%php  
209   $http->redirect('http://example.com/new-page', true); // 301  
210   $http->redirect('/wiki/HomePage'); // 302  
211   %% ||  
212   || ---- ||  
213   || ===== ##terminate(): void## ===== ||  
214   || Safe exit/die with cleanup. ||  
215   || **Cleanup Operations:** ||  
216   || - Saves diagnostic logs to session flash data ||  
217   || - Ends script execution ||  
218   || **Example:** ||  
219   || %%php  
220   $http->terminate();  
221   %% ||  
222   || ---- ||  
223   || ===== ##status($code): void## ===== ||  
224   || Sets HTTP response status code. ||  
225   || **Supported Status Codes:** ||  
226   || %%php  
227   200 => 'OK'  
228   206 => 'Partial Content'  
229   301 => 'Moved Permanently'  
230   302 => 'Moved Temporarily'  
231   304 => 'Not Modified'  
232   400 => 'Bad Request'  
233   401 => 'Unauthorized'  
234   403 => 'Forbidden'  
235   404 => 'Not Found'  
236   405 => 'Method Not Allowed'  
237   409 => 'Conflict'  
238   410 => 'Gone'  
239   416 => 'Requested Range Not Satisfiable'  
240   500 => 'Internal Server Error'  
241   501 => 'Not Implemented'  
242   503 => 'Service Unavailable'  
243   %% ||  
244   || **Example:** ||  
245   || %%php  
246   $http->status(404); // Send 404 Not Found  
247   %% ||  
248   || ---- ||  
249   || ==== Caching Control ==== ||  
250   || ===== ##no_cache($client_only = true): void## ===== ||  
251   || Disables caching of the current page. ||  
252   || **Parameters:** ||  
253   || - ##$client_only## (bool, default: TRUE) ||  
254   || - ##TRUE##: Disable browser cache only ||  
255   || - ##FALSE##: Disable both browser and server cache ||  
256   || **Headers Set:** ||  
257   || - ##Last-Modified: <current-time>## (always fresh) ||  
258   || - ##Cache-Control: no-store## ||  
259   || **Example:** ||  
260   || %%php  
261   $http->no_cache(); // Client-side only  
262   $http->no_cache(false); // Both client & server  
263   %% ||  
264   || ---- ||  
265   || ===== ##cache_promisc(): void## ===== ||  
266   || Marks page as publicly cacheable. ||  
267   || **Headers Set:** ||  
268   || - ##Cache-Control: public## ||  
269   || **Example:** ||  
270   || %%php  
271   $http->cache_promisc();  
272   %% ||  
273   || ---- ||  
274   || ==== Language Negotiation ==== ||  
275   || ===== ##user_agent_language(): string## ===== ||  
276   || Determines best language based on browser preferences. ||  
277   || **Features:** ||  
278   || - Follows RFC 9110 section 12.5.4 (HTTP Accept-Language) ||  
279   || - Parses ##Accept-Language## header with quality factors ||  
280   || - Attempts exact match first, then language fallback ||  
281   || - Falls back to default system language ||  
282   || **Example Header:** ||  
283   || %%  
284   Accept-Language: en-US,en;q=0.9,de;q=0.8  
285   %% ||  
286   || **Returns:** ||  
287   || - Language code (e.g., 'en', 'en-US', 'de') ||  
288   || ---- ||  
289   || ===== ##available_languages($subset = true): array## ===== ||  
290   || Returns list of available language translations. ||  
291   || **Parameters:** ||  
292   || - ##$subset## (bool, default: TRUE) ||  
293   || - ##TRUE##: Only allowed languages ||  
294   || - ##FALSE##: All available languages ||  
295   || **Features:** ||  
296   || - Scans ##LANG_DIR## for language files ||  
297   || - Filters by ##allowed_languages## config if set ||  
298   || - Caches result in session ||  
299   || - System language always included ||  
300   || **Returns:** ||  
301   || - Associative array: ##['en' => 'en', 'de' => 'de', ...]## ||  
302   || **Example:** ||  
303   || %%php  
304   $all_langs = $http->available_languages(false);  
305   $allowed = $http->available_languages(true);  
306   %% ||  
307   || ---- ||  
308   || ==== File Serving ==== ||  
309   || ===== ##sendfile($path, $filename = null, $age = null): void## ===== ||  
310   || Serves files with proper HTTP headers and caching. ||  
311   || **Parameters:** ||  
312   || - ##$path## (string) - File path (or HTTP_XXX constant for error pages) ||  
313   || - ##$filename## (string, optional) - Custom download filename ||  
314   || - ##$age## (int, optional) - Cache age in days ||  
315   || **Features:** ||  
316   || - HTTP range request support (partial file downloads) ||  
317   || - ETag and Last-Modified conditional requests ||  
318   || - Proper MIME type detection ||  
319   || - Content-Security-Policy for special file types ||  
320   || - Streaming for large files ||  
321   || - GZip compression for text files ||  
322   || **Special Paths:** ||  
323   || %%php  
324   $http->sendfile(404); // Serves file defined by HTTP_404 constant  
325   $http->sendfile(403); // Serves file defined by HTTP_403 constant  
326   %% ||  
327   || **Example:** ||  
328   || %%php  
329   $http->sendfile('uploads/document.pdf', 'my-document.pdf', 30);  
330   %% ||  
331   || ---- ||  
332   || ===== ##mime_type($path): string## ===== ||  
333   || Returns MIME type for a file. ||  
334   || **Returns:** ||  
335   || - MIME type string (e.g., 'application/pdf') ||  
336   || - Default: ##'application/octet-stream'## ||  
337   || **Example:** ||  
338   || %%php  
339   $mime = $http->mime_type('file.pdf'); // 'application/pdf'  
340   %% ||  
341   || ---- ||  
342   || ===== ##mime_types(): array## (Private) ===== ||  
343   || Loads and caches MIME types from configuration. ||  
344   || **Features:** ||  
345   || - Reads from ##config/mime.types## ||  
346   || - Caches to ##cache/config/mime.types## ||  
347   || - Reloads if config is updated ||  
348   || ---- ||  
349   || ==== Compression ==== ||  
350   || ===== ##gzip(): void## ===== ||  
351   || Compresses HTTP response with gzip/x-gzip. ||  
352   || **Features:** ||  
353   || - Manually implements gzip (not relying on zlib.output_compression) ||  
354   || - Produces correct ##Content-Length## header ||  
355   || - Only compresses if: ||  
356   || - 860 bytes < content < 1 MB ||  
357   || - Client accepts compression ||  
358   || - Headers not already sent ||  
359   || **Example:** ||  
360   || %%php  
361   $http->gzip();  
362   %% ||  
363   || ---- ||  
364   || ==== Utility Methods ==== ||  
365   || ===== ##parse_str($str): array## (Private) ===== ||  
366   || Parses URL-encoded strings with special character handling. ||  
367   || **Purpose:** ||  
368   || - Safely handles special characters in query/form data ||  
369   || - Converts encoding properly ||  
370   || **Example:** ||  
371   || %%php  
372   $data = $http->parse_str('name=John&age=30');  
373   %% ||  
374   || ---- ||  
375   || ===== ##request_uri(): string## (Private) ===== ||  
376   || Extracts and normalizes REQUEST_URI from server. ||  
377   || **Normalization:** ||  
378   || - Removes base URL prefix ||  
379   || - Removes spaces ||  
380   || - Collapses multiple slashes ||  
381   || - Removes ##..## path traversal attempts ||  
382   || - Removes leading/trailing slashes ||  
383   || ---- ||  
384   || ===== ##cut_prefix($prefix, $path): string## (Private) ===== ||  
385   || Removes prefix from path (case-insensitive). ||  
386   || ---- ||  
387   || ===== ##get_header_conf($file_name): string## (Private) ===== ||  
388   || Loads security header configuration from files. ||  
389   || **Files Supported:** ||  
390   || - ##csp.conf## / ##csp_custom.conf## ||  
391   || - ##permissions_policy.conf## / ##permissions_policy_custom.conf## ||  
392   || ---- ||  
393   || === Configuration Dependencies === ||  
394   || The class relies on these database configuration settings: ||  
395   || Setting | Type | Purpose ||  
396   || --------- | ------ | --------- ||  
397   || ##base_url## | string | Wiki's base URL ||  
398   || ##tls## | bool | Enable HTTPS enforcement ||  
399   || ##cache## | bool | Enable page caching ||  
400   || ##cache_ttl## | int | Cache lifetime in seconds ||  
401   || ##session_store## | int | 1=File, 0=Database ||  
402   || ##system_seed_hash## | string | Session encryption seed ||  
403   || ##cookie_prefix## | string | Session cookie prefix ||  
404   || ##cookie_path## | string | Cookie path ||  
405   || ##allow_persistent_cookie## | bool | Allow persistent login ||  
406   || ##session_length## | int | Session lifetime in seconds ||  
407   || ##reverse_proxy_addresses## | string | Comma/space-separated proxy IPs ||  
408   || ##reverse_proxy_header## | string | Custom X-Forwarded header ||  
409   || ##language## | string | Default language code ||  
410   || ##multilanguage## | bool | Enable language negotiation ||  
411   || ##allowed_languages## | string | Comma/space-separated allowed langs ||  
412   || ##enable_security_headers## | bool | Send security headers ||  
413   || ##csp## | int | CSP setting (0/1/2) ||  
414   || ##permissions_policy## | int | Permissions-Policy setting (0/1/2) ||  
415   || ##referrer_policy## | int | Referrer-Policy setting (0-8) ||  
416   || ---- ||  
417   || === Constants Used === ||  
418   || Constant | Type | Purpose ||  
419   || ---------- | ------ | --------- ||  
420   || ##IN_WACKO## | bool | Security check (exit if not defined) ||  
421   || ##CHMOD_SAFE## | int | File permissions for cache files ||  
422   || ##CHMOD_FILE## | int | File permissions for config cache ||  
423   || ##CACHE_PAGE_DIR## | string | Page cache directory ||  
424   || ##CACHE_SESSION_DIR## | string | Session cache directory ||  
425   || ##CACHE_CONFIG_DIR## | string | Config cache directory ||  
426   || ##CONFIG_DIR## | string | Configuration directory ||  
427   || ##LANG_DIR## | string | Language files directory ||  
428   || ##DAYSECS## | int | Seconds in a day (86400) ||  
429   || ##HTTP_404## | string | Path to 404 error page ||  
430   || ##HTTP_403## | string | Path to 403 error page ||  
431   |#  
432 15
433   ----  
434 16
435   === Workflow Examples ===  
436 17
437   ==== Example 1: Handling a GET Request ====  
438    
439   %%php  
440   // In main wiki entry point  
441   $http = new Http($db);  
442   $http->session(0); // Start session  
443    
444   // Check if page can be served from cache  
445   $http->check_cache('HomePage', 'show');  
446    
447   // ... render page content ...  
448    
449   // Store rendered page in cache if applicable  
450   $http->store_cache();  
451    
452   // Send security headers  
453   $http->http_security_headers();  
454    
455   // Possibly compress output  
456   $http->gzip();  
457   %%  
458    
459   ==== Example 2: Handling TLS/HTTPS Upgrade ====  
460    
461   %%php  
462   $http = new Http($db); // Constructor detects TLS requirement  
463   // If TLS is enabled and user wasn't in TLS before:  
464   // - Sets TLS session flag  
465   // - Marks session with TLS cookie  
466   // - Redirects to HTTPS version  
467   %%  
468    
469   ==== Example 3: Invalidating Cache After Page Edit ====  
470    
471   %%php  
472   // User edits a page  
473   $http = new Http($db);  
474   $count = $http->invalidate_page('HomePage');  
475   // All cached versions (different languages, methods) are invalidated  
476   %%  
477    
478   ==== Example 4: Serving a File ====  
479    
480   %%php  
481   $http = new Http($db);  
482   $http->session(2); // Static file mode - no session replay prevention  
483    
484   // Serve with 30-day cache  
485   $http->sendfile('uploads/manual.pdf', 'user-manual.pdf', 30);  
486   %%  
487    
488   ----  
489 18
490 19 === Security Considerations ===
491 20