Skip to content

Instantly share code, notes, and snippets.

@trovster
Last active December 7, 2022 11:52
Show Gist options
  • Save trovster/2581015c6795045f73134395c49ea566 to your computer and use it in GitHub Desktop.
Save trovster/2581015c6795045f73134395c49ea566 to your computer and use it in GitHub Desktop.
Replaying POST requests using Laravel Middleware + Service
<?php
namespace App\Http\Middleware;
use App\Services\ReplayRequest;
use Closure;
use Illuminate\Http\Request;
class PostSpecificReplay
{
public function __construct(protected ReplayRequest $service)
{
}
public function handle(Request $request, Closure $next): mixed
{
if ($this->service->has($request, 'request-key', 'POST')) {
$response = $this->service->replay($request, 'request-key', 'POST');
$request->session()->forget('is-replay');
return $response;
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use App\Services\ReplayRequest;
use Closure;
use Illuminate\Http\Request;
class PostSpecificReplay
{
public function __construct(protected ReplayRequest $service)
{
}
public function handle(Request $request, Closure $next): mixed
{
if (! $this->service->isReplay($request)) {
$this->service->queue($request, 'request-key', 'POST', $request->input());
}
return $next($request);
}
}
<?php
namespace App\Services;
use App\Http\Kernel;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
final class ReplayRequest
{
public function __construct(protected Kernel $service)
{
}
public function key(string $url, string $method): string
{
return Str::of($url)->append('-')->append($method)->slug();
}
public function queue(Request $request, string $url, string $method, array $data = []): void
{
$key = $this->key($url, $method);
$request->session()->put('is-replay', true);
$request->session()->put($key, [
'url' => $url,
'method' => $method,
'data' => $data,
]);
}
public function replay(Request $request, string $url, string $method): Response | RedirectResponse | View
{
$key = $this->key($url, $method);
$replay = $request->session()->pull($key);
$url = Arr::get($replay, 'url', '/');
$method = Arr::get($replay, 'method', 'POST');
$data = Arr::get($replay, 'data', []);
$request = Request::createFromBase(
SymfonyRequest::create($url, $method, $data, $request->cookie(), $request->allFiles(), $request->server())
);
return $this->service->handle($request);
}
public function isReplay(Request $request): bool
{
return $request->session()->has('is-replay');
}
public function has(Request $request, string $url, string $method): bool
{
$key = $this->key($url, $method);
return $this->isReplay($request) && $request->session()->has($key);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment