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