Skip to content

Commit

Permalink
Merge pull request #1 from holladaydigital/master
Browse files Browse the repository at this point in the history
Add support for formatting large request bodies + Windows Test Fixes
  • Loading branch information
octoper authored Mar 15, 2021
2 parents abbe14a + 683dc0c commit d644aaf
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 24 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
"require": {
"php": ">=7.3",
"guzzlehttp/guzzle": "^7.2",
"psr/log": "^1.1"
"psr/log": "^1.1",
"symfony/process": "^5.2"
},
"require-dev": {
"phpunit/phpunit": "^9.4.3",
"pestphp/pest": "^0.3.14",
"pestphp/pest": "^1.0",
"phpstan/phpstan": "^0.12.58"
},
"autoload": {
Expand Down
18 changes: 13 additions & 5 deletions src/Formatter/CurlFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use GuzzleHttp\Cookie\CookieJarInterface;
use GuzzleHttp\Cookie\SetCookie;
use Psr\Http\Message\RequestInterface;
use Symfony\Component\Process\Process;

class CurlFormatter
{
Expand Down Expand Up @@ -140,7 +141,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
Expand Down Expand Up @@ -176,7 +177,7 @@ protected function extractCookiesArgument(RequestInterface $request, array $opti
}

if ($values) {
$this->addOption('b', escapeshellarg(implode('; ', $values)));
$this->addOption('b', $this->escapeShellArgument(implode('; ', $values)));
}
}

Expand All @@ -193,12 +194,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}"));
}
}
}
Expand Down Expand Up @@ -245,6 +246,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;
}
}
12 changes: 6 additions & 6 deletions tests/Client/RequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
$jar = CookieJar::fromArray(['Foo' => 'Bar', 'identity' => 'xyz'], 'local.example');
$curl = $this->curlFormatter->format($request, ['cookies' => $jar]);

expect($curl)->not()->toContain("-H 'Host: local.example'");
expect($curl)->toContain("-b 'Foo=Bar; identity=xyz'");
expect(str_replace('"', '\'', $curl))->not()->toContain("-H 'Host: local.example'");
expect(str_replace('"', '\'', $curl))->toContain("-b 'Foo=Bar; identity=xyz'");
});

test('POST', function () {
$request = new Request('POST', 'http://local.example', [], Utils::streamFor('foo=bar&hello=world'));
$curl = $this->curlFormatter->format($request);

expect($curl)->toContain("-d 'foo=bar&hello=world'");
expect(str_replace('"', '\'', $curl))->toContain("-d 'foo=bar&hello=world'");
});

test('PUT', function () {
$request = new Request('PUT', 'http://local.example', [], Utils::streamFor('foo=bar&hello=world'));
$curl = $this->curlFormatter->format($request);

expect($curl)->toContain("-d 'foo=bar&hello=world'");
expect(str_replace('"', '\'', $curl))->toContain("-d 'foo=bar&hello=world'");
expect($curl)->toContain('-X PUT');
});

Expand All @@ -48,12 +48,12 @@
$request = new Request('HEAD', 'http://local.example');
$curl = $this->curlFormatter->format($request);

expect($curl)->toContain("curl 'http://local.example' --head");
expect(str_replace('"', '\'', $curl))->toContain("curl 'http://local.example' --head");
});

test('OPTIONS', function () {
$request = new Request('OPTIONS', 'http://local.example');
$curl = $this->curlFormatter->format($request);

expect($curl)->toContain('-X OPTIONS');
});
});
34 changes: 23 additions & 11 deletions tests/Formatter/CurlFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,47 @@
$request = new Request('GET', 'http://example.local');
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local'", $curl);
$this->assertEquals("curl 'http://example.local'", str_replace('"', '\'', $curl));
});

test('simple get', function () {
$request = new Request('GET', 'http://example.local');
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local'", $curl);
$this->assertEquals("curl 'http://example.local'", str_replace('"', '\'', $curl));
});

test('simple GET with header', function () {
$request = new Request('GET', 'http://example.local', ['foo' => 'bar']);
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local' -H 'foo: bar'", $curl);
$this->assertEquals("curl 'http://example.local' -H 'foo: bar'", str_replace('"', '\'', $curl));
});

test('simple GET with multiple header', function () {
$request = new Request('GET', 'http://example.local', ['foo' => 'bar', 'Accept-Encoding' => 'gzip,deflate,sdch']);
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local' -H 'foo: bar' -H 'Accept-Encoding: gzip,deflate,sdch'", $curl);
$this->assertEquals("curl 'http://example.local' -H 'foo: bar' -H 'Accept-Encoding: gzip,deflate,sdch'", str_replace('"', '\'', $curl));
});

test('GET With Query String', function () {
$request = new Request('GET', 'http://example.local?foo=bar');
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local?foo=bar'", $curl);
$this->assertEquals("curl 'http://example.local?foo=bar'", str_replace('"', '\'', $curl));

$request = new Request('GET', 'http://example.local?foo=bar');
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local?foo=bar'", $curl);
$this->assertEquals("curl 'http://example.local?foo=bar'", str_replace('"', '\'', $curl));

$body = Utils::streamFor(http_build_query(['foo' => 'bar', 'hello' => 'world'], '', '&'));

$request = new Request('GET', 'http://example.local',[],$body);
$curl = $this->curlFormatter->format($request);

$this->assertEquals("curl 'http://example.local' -G -d 'foo=bar&hello=world'",$curl);
$this->assertEquals("curl 'http://example.local' -G -d 'foo=bar&hello=world'", str_replace('"', '\'', $curl));
});

test('POST', function () {
Expand All @@ -71,7 +71,19 @@
$curl = $this->curlFormatter->format($request);

expect($curl)->not()->toContain(" -G ");
expect($curl)->toContain("-d 'foo=bar&hello=world'");
expect(str_replace('"', '\'', $curl))->toContain("-d 'foo=bar&hello=world'");

});

test('large POST request', function () {
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);

expect($curl)->not()->toBeNull();
});

test('HEAD', function () {
Expand Down Expand Up @@ -99,15 +111,15 @@
$request = new Request('PUT', 'http://example.local', [], Utils::streamFor('foo=bar&hello=world'));
$curl = $this->curlFormatter->format($request);

expect($curl)->toContain("-d 'foo=bar&hello=world'");
expect(str_replace('"', '\'', $curl))->toContain("-d 'foo=bar&hello=world'");
expect($curl)->toContain("-X PUT");
});

test('proper body relative', function () {
$request = new Request('PUT', 'http://example.local', [], Utils::streamFor('foo=bar&hello=world'));
$curl = $this->curlFormatter->format($request);

expect($curl)->toContain("-d 'foo=bar&hello=world'");
expect(str_replace('"', '\'', $curl))->toContain("-d 'foo=bar&hello=world'");
expect($curl)->toContain("-X PUT");
});

Expand All @@ -124,4 +136,4 @@
['X-Foo' => 'Bar'],
chr(0). 'foo=bar&hello=world',
]
]);
]);

0 comments on commit d644aaf

Please sign in to comment.