Files
ladill-link/app/Services/Link/LinkPlatformProxy.php
T
isaaccladandCursor 9516fcb9f3
Deploy Ladill Link / deploy (push) Successful in 37s
Expand Link app with analytics, settings, and custom domains.
Add Bitly-style branded domain support via Ladill Domains SSL API,
account analytics dashboard, settings page with default domain picker,
and fix SSO/dashboard issues from QR Plus template leftovers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 12:16:34 +00:00

97 lines
3.1 KiB
PHP

<?php
namespace App\Services\Link;
use App\Support\LadillLink;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Symfony\Component\HttpFoundation\Response;
/**
* Proxies ladl.link ecosystem paths to the platform QR resolver (/q/* on ladill.com).
* The browser stays on ladl.link; resolution happens server-side.
*/
class LinkPlatformProxy
{
public function forward(Request $request, string $slug, ?string $path = null): Response
{
$platform = rtrim((string) config('app.platform_url', 'https://ladill.com'), '/');
$target = $platform.'/q/'.$slug;
if ($path !== null && $path !== '') {
$target .= '/'.ltrim($path, '/');
}
if ($qs = $request->getQueryString()) {
$target .= '?'.$qs;
}
$client = Http::withOptions(['allow_redirects' => false])->timeout(15);
$method = strtoupper($request->method());
$pending = match ($method) {
'POST' => $client->withHeaders($this->forwardHeaders($request))->asForm()->post($target, $request->post()),
'PATCH' => $client->withHeaders($this->forwardHeaders($request))->patch($target, $request->all()),
'DELETE' => $client->withHeaders($this->forwardHeaders($request))->delete($target),
default => $client->withHeaders($this->forwardHeaders($request))->get($target),
};
$upstream = $pending->toPsrResponse();
$response = new Response(
(string) $upstream->getBody(),
$upstream->getStatusCode(),
$this->sanitizeHeaders($upstream->getHeaders())
);
if ($response->isRedirection()) {
$location = $response->headers->get('Location');
if (is_string($location)) {
$response->headers->set('Location', $this->rewriteLocation($location, $slug));
}
}
return $response;
}
/** @return array<string, string> */
private function forwardHeaders(Request $request): array
{
$headers = [];
foreach (['Accept', 'Accept-Language', 'User-Agent', 'Referer'] as $name) {
$value = $request->header($name);
if ($value !== null) {
$headers[$name] = $value;
}
}
return $headers;
}
/** @param array<string, array<int, string>> $headers */
private function sanitizeHeaders(array $headers): array
{
$flat = [];
foreach ($headers as $name => $values) {
if (strtolower($name) === 'transfer-encoding') {
continue;
}
$flat[$name] = $values[0] ?? '';
}
return $flat;
}
private function rewriteLocation(string $location, string $slug): string
{
$platform = rtrim((string) config('app.platform_url', 'https://ladill.com'), '/');
$prefix = $platform.'/q/'.$slug;
if (str_starts_with($location, $prefix)) {
$suffix = substr($location, strlen($prefix));
$rewritten = LadillLink::url($slug).$suffix;
return $rewritten;
}
return $location;
}
}