mirror of
https://github.com/symfony/http-kernel.git
synced 2026-03-24 01:12:09 +01:00
[WebProfiler] add cURL copy/paste to request tab
This commit is contained in:
@@ -22,6 +22,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\HttpKernel\Event\ControllerEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
|
||||
/**
|
||||
@@ -130,6 +131,8 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
|
||||
$this->data['content'] = $content;
|
||||
|
||||
$this->data['curlCommand'] = $this->computeCurlCommand($request, $content);
|
||||
|
||||
foreach ($this->data as $key => $value) {
|
||||
if (!\is_array($value)) {
|
||||
continue;
|
||||
@@ -495,4 +498,61 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
|
||||
return \is_string($controller) ? $controller : 'n/a';
|
||||
}
|
||||
|
||||
private function computeCurlCommand(Request $request, ?string $content): string
|
||||
{
|
||||
$command = ['curl', '--compressed'];
|
||||
|
||||
$method = $request->getMethod();
|
||||
|
||||
if (Request::METHOD_HEAD === $method) {
|
||||
$command[] = '--head';
|
||||
} elseif (Request::METHOD_GET !== $method) {
|
||||
$command[] = \sprintf('--request %s', $method);
|
||||
}
|
||||
|
||||
$command[] = \sprintf('--url %s', escapeshellarg($request->getUri()));
|
||||
|
||||
foreach ($request->headers->all() as $name => $values) {
|
||||
if (\in_array(strtolower($name), ['host', 'cookie'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$command[] = '--header '.escapeshellarg(ucwords($name, '-').': '.implode(', ', $values));
|
||||
}
|
||||
|
||||
if ($request->cookies->all()) {
|
||||
$cookies = [];
|
||||
foreach ($request->cookies->all() as $name => $value) {
|
||||
$cookies[] = urlencode($name).'='.urlencode($value);
|
||||
}
|
||||
$command[] = '--cookie '.escapeshellarg(implode('; ', $cookies));
|
||||
}
|
||||
|
||||
if ($content && \in_array($method, [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE], true)) {
|
||||
$command[] = '--data-raw '.$this->escapePayload($content);
|
||||
}
|
||||
|
||||
return implode(" \\\n ", $command);
|
||||
}
|
||||
|
||||
public function getCurlCommand(): string
|
||||
{
|
||||
return $this->data['curlCommand'] ?? '';
|
||||
}
|
||||
|
||||
private function escapePayload(string $payload): string
|
||||
{
|
||||
static $useProcess;
|
||||
|
||||
if ($useProcess ??= \function_exists('proc_open') && class_exists(Process::class)) {
|
||||
return substr((new Process(['', $payload]))->getCommandLine(), 3);
|
||||
}
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
return '"'.str_replace('"', '""', $payload).'"';
|
||||
}
|
||||
|
||||
return "'".str_replace("'", "'\\''", $payload)."'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,4 +462,111 @@ class RequestDataCollectorTest extends TestCase
|
||||
['', null],
|
||||
];
|
||||
}
|
||||
|
||||
public function testCurlCommandGet()
|
||||
{
|
||||
$request = Request::create('http://test.com/foo?bar=baz');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringStartsWith("curl \\\n --compressed", $curlCommand);
|
||||
$this->assertStringContainsString("--url 'http://test.com/foo?bar=baz'", $curlCommand);
|
||||
$this->assertStringNotContainsString('--request', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandPost()
|
||||
{
|
||||
$request = Request::create('http://test.com/foo', 'POST', [], [], [], [], '{"key":"value"}');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringContainsString('--request POST', $curlCommand);
|
||||
$this->assertStringContainsString('--data-raw', $curlCommand);
|
||||
$this->assertStringContainsString('{"key":"value"}', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandHead()
|
||||
{
|
||||
$request = Request::create('http://test.com/foo', 'HEAD');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringContainsString('--head', $curlCommand);
|
||||
$this->assertStringNotContainsString('--request', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandWithHeaders()
|
||||
{
|
||||
$request = Request::create('http://test.com/foo');
|
||||
$request->headers->set('Accept', 'application/json');
|
||||
$request->headers->set('X-Custom-Header', 'custom-value');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringContainsString("--header 'Accept: application/json'", $curlCommand);
|
||||
$this->assertStringContainsString("--header 'X-Custom-Header: custom-value'", $curlCommand);
|
||||
$this->assertStringNotContainsString('Host:', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandWithCookies()
|
||||
{
|
||||
$request = Request::create('http://test.com/foo', 'GET', [], ['session' => 'abc123', 'lang' => 'en']);
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringContainsString('--cookie', $curlCommand);
|
||||
$this->assertStringContainsString('session=abc123', $curlCommand);
|
||||
$this->assertStringContainsString('lang=en', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandPutWithBody()
|
||||
{
|
||||
$request = Request::create('http://test.com/resource/1', 'PUT', [], [], [], [], 'updated data');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringContainsString('--request PUT', $curlCommand);
|
||||
$this->assertStringContainsString('--data-raw', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandDoesNotDuplicateQueryString()
|
||||
{
|
||||
$request = Request::create('http://test.com/path?foo=bar&baz=qux');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertSame(1, substr_count($curlCommand, 'foo=bar'));
|
||||
$this->assertSame(1, substr_count($curlCommand, 'baz=qux'));
|
||||
}
|
||||
|
||||
public function testCurlCommandGetWithNoBody()
|
||||
{
|
||||
$request = Request::create('http://test.com/foo', 'GET');
|
||||
|
||||
$c = new RequestDataCollector();
|
||||
$c->collect($request, $this->createResponse());
|
||||
|
||||
$curlCommand = $c->getCurlCommand();
|
||||
$this->assertStringNotContainsString('--data-raw', $curlCommand);
|
||||
}
|
||||
|
||||
public function testCurlCommandIsEmptyStringWhenNotCollected()
|
||||
{
|
||||
$c = new RequestDataCollector();
|
||||
$this->assertSame('', $c->getCurlCommand());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user