Skip to content

Commit 1c3a53f

Browse files
Nyholmdbu
authored andcommitted
Added cURL formatter (#50)
Added cURL formatter inspired by namshi/cuzzle
1 parent a69d952 commit 1c3a53f

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ $ composer test
4747

4848
Please see our [contributing guide](http://docs.php-http.org/en/latest/development/contributing.html).
4949

50+
## Cretids
51+
52+
Thanks to [Cuzzle](https://github.com/namshi/cuzzle) for inpiration for the `CurlCommandFormatter`.
5053

5154
## Security
5255

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace spec\Http\Message\Formatter;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\StreamInterface;
8+
use Psr\Http\Message\UriInterface;
9+
use PhpSpec\ObjectBehavior;
10+
11+
class CurlCommandFormatterSpec extends ObjectBehavior
12+
{
13+
function it_is_initializable()
14+
{
15+
$this->shouldHaveType('Http\Message\Formatter\CurlCommandFormatter');
16+
}
17+
18+
function it_is_a_formatter()
19+
{
20+
$this->shouldImplement('Http\Message\Formatter');
21+
}
22+
23+
function it_formats_the_request(RequestInterface $request, UriInterface $uri, StreamInterface $body)
24+
{
25+
$request->getUri()->willReturn($uri);
26+
$request->getBody()->willReturn($body);
27+
28+
$uri->withFragment('')->shouldBeCalled()->willReturn('http://foo.com/bar');
29+
$request->getMethod()->willReturn('GET');
30+
$request->getProtocolVersion()->willReturn('1.1');
31+
32+
$request->getHeaders()->willReturn(['foo'=>['bar', 'baz']]);
33+
$request->getHeaderLine('foo')->willReturn('bar, baz');
34+
35+
$this->formatRequest($request)->shouldReturn('curl \'http://foo.com/bar\' -H \'foo: bar, baz\'');
36+
}
37+
38+
function it_formats_post_request(RequestInterface $request, UriInterface $uri, StreamInterface $body)
39+
{
40+
$request->getUri()->willReturn($uri);
41+
$request->getBody()->willReturn($body);
42+
43+
$body->__toString()->willReturn('body " data'." test' bar");
44+
$body->getSize()->willReturn(1);
45+
$body->isSeekable()->willReturn(true);
46+
$body->rewind()->willReturn(true);
47+
48+
$uri->withFragment('')->shouldBeCalled()->willReturn('http://foo.com/bar');
49+
$request->getMethod()->willReturn('POST');
50+
$request->getProtocolVersion()->willReturn('2.0');
51+
52+
$request->getHeaders()->willReturn([]);
53+
54+
$this->formatRequest($request)->shouldReturn("curl 'http://foo.com/bar' --http2 --request POST --data 'body \" data test'\'' bar'");
55+
}
56+
57+
function it_does_nothing_for_response(ResponseInterface $response)
58+
{
59+
$this->formatResponse($response)->shouldReturn('');
60+
}
61+
}
+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Http\Message\Formatter;
4+
5+
use Http\Message\Formatter;
6+
use Psr\Http\Message\RequestInterface;
7+
use Psr\Http\Message\ResponseInterface;
8+
9+
/**
10+
* A formatter that prints a cURL command for HTTP requests.
11+
*
12+
* @author Tobias Nyholm <[email protected]>
13+
*/
14+
class CurlCommandFormatter implements Formatter
15+
{
16+
/**
17+
* {@inheritdoc}
18+
*/
19+
public function formatRequest(RequestInterface $request)
20+
{
21+
$command = sprintf('curl %s', escapeshellarg((string) $request->getUri()->withFragment('')));
22+
if ($request->getProtocolVersion() === '1.0') {
23+
$command .= ' --http1.0';
24+
} elseif ($request->getProtocolVersion() === '2.0') {
25+
$command .= ' --http2';
26+
}
27+
28+
$method = strtoupper($request->getMethod());
29+
if ('HEAD' === $method) {
30+
$command .= ' --head';
31+
} elseif ('GET' !== $method) {
32+
$command .= ' --request '.$method;
33+
}
34+
35+
$command .= $this->getHeadersAsCommandOptions($request);
36+
37+
$body = $request->getBody();
38+
if ($body->getSize() > 0) {
39+
if (!$body->isSeekable()) {
40+
return 'Cant format Request as cUrl command if body stream is not seekable.';
41+
}
42+
$command .= sprintf(' --data %s', escapeshellarg($body->__toString()));
43+
$body->rewind();
44+
}
45+
46+
return $command;
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
public function formatResponse(ResponseInterface $response)
53+
{
54+
return '';
55+
}
56+
57+
/**
58+
* @param RequestInterface $request
59+
*
60+
* @return string
61+
*/
62+
private function getHeadersAsCommandOptions(RequestInterface $request)
63+
{
64+
$command = '';
65+
foreach ($request->getHeaders() as $name => $values) {
66+
if ('host' === strtolower($name) && $values[0] === $request->getUri()->getHost()) {
67+
continue;
68+
}
69+
70+
if ('user-agent' === strtolower($name)) {
71+
$command .= sprintf('-A %s', escapeshellarg($values[0]));
72+
continue;
73+
}
74+
75+
$command .= sprintf(' -H %s', escapeshellarg($name.': '.$request->getHeaderLine($name)));
76+
}
77+
78+
return $command;
79+
}
80+
}

0 commit comments

Comments
 (0)