From e1a7105d1df7ca6fe12aaa951fb38c1612dc7344 Mon Sep 17 00:00:00 2001 From: John S Long Date: Thu, 1 Mar 2018 17:36:07 -0700 Subject: [PATCH] Add support for formatting large request bodies Solves #20 --- composer.json | 3 ++- src/Formatter/CurlFormatter.php | 18 +++++++++++++----- tests/Formatter/CurlFormatterTest.php | 9 +++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index c2ed439..d5a5bbd 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "require": { "php": ">=5.5.0", "guzzlehttp/guzzle": "^6.0", - "psr/log": "^1.0" + "psr/log": "^1.0", + "symfony/process": "^3.0" }, "require-dev": { "phpunit/phpunit": "^4.2.2" diff --git a/src/Formatter/CurlFormatter.php b/src/Formatter/CurlFormatter.php index 8e789b1..13e4a12 100644 --- a/src/Formatter/CurlFormatter.php +++ b/src/Formatter/CurlFormatter.php @@ -5,6 +5,7 @@ use GuzzleHttp\Cookie\CookieJarInterface; use GuzzleHttp\Cookie\SetCookie; use Psr\Http\Message\RequestInterface; +use Symfony\Component\Process\Process; /** * Class CurlFormatter it formats a Guzzle request to a cURL shell command @@ -134,7 +135,7 @@ protected function extractBodyArgument(RequestInterface $request) if ($contents) { // clean input of null bytes $contents = str_replace(chr(0), '', $contents); - $this->addOption('d', escapeshellarg($contents)); + $this->addOption('d', $this->escapeShellArgument($contents)); } //if get request has data Add G otherwise curl will make a post request @@ -168,7 +169,7 @@ protected function extractCookiesArgument(RequestInterface $request, array $opti } if ($values) { - $this->addOption('b', escapeshellarg(implode('; ', $values))); + $this->addOption('b', $this->escapeShellArgument(implode('; ', $values))); } } @@ -183,12 +184,12 @@ protected function extractHeadersArgument(RequestInterface $request) } if ('user-agent' === strtolower($name)) { - $this->addOption('A', escapeshellarg($header[0])); + $this->addOption('A', $this->escapeShellArgument($header[0])); continue; } foreach ((array)$header as $headerValue) { - $this->addOption('H', escapeshellarg("{$name}: {$headerValue}")); + $this->addOption('H', $this->escapeShellArgument("{$name}: {$headerValue}")); } } } @@ -228,6 +229,13 @@ protected function extractArguments(RequestInterface $request, array $options) */ protected function extractUrlArgument(RequestInterface $request) { - $this->addCommandPart(escapeshellarg((string)$request->getUri()->withFragment(''))); + $this->addCommandPart($this->escapeShellArgument((string)$request->getUri()->withFragment(''))); + } + + protected function escapeShellArgument($argument) + { + $process = new Process([$argument]); + $escaped = $process->getCommandLine(); + return $escaped; } } diff --git a/tests/Formatter/CurlFormatterTest.php b/tests/Formatter/CurlFormatterTest.php index 2275bd3..1710c40 100644 --- a/tests/Formatter/CurlFormatterTest.php +++ b/tests/Formatter/CurlFormatterTest.php @@ -161,4 +161,13 @@ public function getHeadersAndBodyData() ], ]; } + + public function testLongArgument() + { + ini_set('memory_limit', -1); + $body = str_repeat('A', 1024*1024*64); + $request = new Request('POST', 'http://example.local', [], \GuzzleHttp\Psr7\stream_for($body)); + + $curl = $this->curlFormatter->format($request); + } }