Skip to content

Commit f7937cc

Browse files
author
Greg Bowler
authored
Redirects (#644)
* wip: redirects file for #643 * tweak: remove todo
1 parent 286b441 commit f7937cc

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

src/Middleware/Lifecycle.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class Lifecycle implements MiddlewareInterface {
4545
private Throwable $throwable;
4646

4747
public function start():void {
48+
// Before we start, we check if the current URI should be redirected. If it
49+
// should, we won't go any further into the lifecycle.
50+
$this->handleRedirects();
51+
4852
// The first thing that's done within the WebEngine lifecycle is start a timer.
4953
// This timer is only used again at the end of the call, when finish() is
5054
// called - at which point the entire duration of the request is logged out (and
@@ -237,4 +241,65 @@ public function finish(
237241

238242
exit;
239243
}
244+
245+
private function handleRedirects():void {
246+
$redirectFiles = [
247+
"\t" => "redirects.tsv",
248+
"," => "redirects.csv",
249+
];
250+
foreach($redirectFiles as $separatorCharacter => $fileName) {
251+
if(!is_file($fileName)) {
252+
continue;
253+
}
254+
255+
Log::debug("Checking redirect file: $fileName");
256+
$currentUri = $_SERVER["REQUEST_URI"];
257+
258+
$lines = file($fileName);
259+
usort($lines, function(string $lineA, string $lineB):int {
260+
$lineARegex = str_starts_with($lineA, "~");
261+
$lineBRegex = str_starts_with($lineB, "~");
262+
if($lineARegex && !$lineBRegex) {
263+
return -1;
264+
}
265+
266+
if(!$lineARegex && $lineBRegex) {
267+
return 1;
268+
}
269+
270+
return 0;
271+
});
272+
273+
foreach($lines as $line) {
274+
$row = str_getcsv($line, $separatorCharacter);
275+
if(!$row || !$row[0]) {
276+
continue;
277+
}
278+
279+
$matchingUri = $row[0];
280+
$redirectUri = $row[1];
281+
$responseCode = $row[2] ?? 302;
282+
283+
$match = $currentUri === $matchingUri;
284+
if($matchingUri[0] === "~") {
285+
$matchingUri = substr($matchingUri, 1);
286+
if(preg_match("~$matchingUri~", $currentUri, $matches)) {
287+
$match = true;
288+
$matchIndex = 1;
289+
while(str_contains($redirectUri, '$' . $matchIndex)) {
290+
$redirectUri = str_replace('$' . $matchIndex, $matches[$matchIndex], $redirectUri);
291+
}
292+
}
293+
}
294+
295+
if($match) {
296+
Log::notice("Redirecting: $currentUri -> $redirectUri ($responseCode)");
297+
header("Location: $redirectUri", true, $responseCode);
298+
exit;
299+
}
300+
}
301+
return;
302+
}
303+
}
304+
240305
}

0 commit comments

Comments
 (0)