Repository navigation
Expand file tree
/
Copy pathfront-controller.php
More file actions
63 lines (52 loc) · 2.28 KB
/
Copy pathfront-controller.php
File metadata and controls
63 lines (52 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
/**
* Plain front-controller integration (no framework).
*
* Put this at the very top of your public/index.php, before any routing or
* output. If handle() returns a Response, send it and stop — the request was
* either trapped (labyrinth) or capped (429). Otherwise continue to your app.
*/
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use NorthWebDev\Labyrinth\Config;
use NorthWebDev\Labyrinth\Labyrinth;
use NorthWebDev\Labyrinth\Request;
use NorthWebDev\Labyrinth\Store\FileStore;
$config = new Config(
// Tune to taste. See README for the full reference.
heuristicThreshold: 3,
tarpitDelaySeconds: 2,
rateMaxRequests: 120, // per 60s window
dailyMaxBytes: 512 * 1024 * 1024,
// OPTIONAL static safety net of verified-crawler IP ranges you maintain.
// Leave empty to rely on forward-confirmed reverse DNS only.
// Example (documentation range, NOT a real crawler): ['192.0.2.0/24'].
staticCrawlerRanges: [],
);
// FileStore works out of the box on a single server. Use RedisStore for a
// multi-server deployment so counters are shared.
//
// Pass an explicit, app-owned, PRIVATE directory — never a shared/temp path.
// It MUST be an absolute, canonical path with no symlinked or "../" components
// (FileStore rejects anything whose realpath() differs). FileStore creates it
// mode 0700 and refuses it if it is group/world-accessible, not owned by this
// user, or reachable through a group/world-writable parent. Keep it OUTSIDE the
// web root so it is never served. If your deploy serves the app from a
// symlinked path (e.g. "current" -> "releases/..."), pass the resolved target.
$store = new FileStore(dirname(__DIR__) . '/var/labyrinth');
$labyrinth = new Labyrinth($config, $store);
// If you sit behind a proxy/CDN, pass the VERIFIED client IP here instead of
// relying on REMOTE_ADDR. Never trust a raw X-Forwarded-For.
$request = Request::fromGlobals();
$response = $labyrinth->handle($request);
if ($response !== null) {
$response->send();
exit;
}
// --- Not handled: carry on to your real application. ---
//
// To make the daily byte cap accurate, report what you serve:
//
// $labyrinth->recordBytes($request->clientIp(), strlen($bodyYouSent));
//
// (Skip verified crawlers; they are exempt from the caps.)