Skip to content
58 changes: 58 additions & 0 deletions spec/Formatter/CurlCommandFormatterSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace spec\Http\Message\Formatter;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use PhpSpec\ObjectBehavior;

class CurlCommandFormatterSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Http\Message\Formatter\CurlCommandFormatter');
}

function it_is_a_formatter()
{
$this->shouldImplement('Http\Message\Formatter');
}

function it_formats_the_request(RequestInterface $request, UriInterface $uri, StreamInterface $body)
{
$request->getUri()->willReturn($uri);
$request->getBody()->willReturn($body);

$uri->__toString()->willReturn('http://foo.com/bar');
$request->getMethod()->willReturn('GET');
$request->getProtocolVersion()->willReturn('1.1');

$request->getHeaders()->willReturn(['foo'=>['bar', 'baz']]);
$request->getHeaderLine('foo')->willReturn('bar, baz');

$this->formatRequest($request)->shouldReturn('curl \'http://foo.com/bar\' --request GET -H \'foo: bar, baz\'');
}

function it_formats_post_request(RequestInterface $request, UriInterface $uri, StreamInterface $body)
{
$request->getUri()->willReturn($uri);
$request->getBody()->willReturn($body);

$body->__toString()->willReturn('body data');

$uri->__toString()->willReturn('http://foo.com/bar');
$request->getMethod()->willReturn('POST');
$request->getProtocolVersion()->willReturn('2.0');

$request->getHeaders()->willReturn([]);

$this->formatRequest($request)->shouldReturn('curl \'http://foo.com/bar\' --http2 --request POST --data \'body data\'');
}

function it_does_nothing_for_response(ResponseInterface $response)
{
$this->formatResponse($response)->shouldReturn('');
}
}
49 changes: 49 additions & 0 deletions src/Formatter/CurlCommandFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Http\Message\Formatter;

use Http\Message\Formatter;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
* A formatter that prints a cURL command for HTTP requests.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class CurlCommandFormatter implements Formatter
{
/**
* {@inheritdoc}
*/
public function formatRequest(RequestInterface $request)
{
$command = sprintf('curl \'%s\'', $request->getUri());
if ($request->getProtocolVersion() === '1.0') {
$command .= ' --http1.0';
} elseif ($request->getProtocolVersion() === '2.0') {
$command .= ' --http2';
}

$command .= ' --request '.$request->getMethod();

foreach ($request->getHeaders() as $name => $values) {
$command .= sprintf(' -H \'%s: %s\'', $name, $request->getHeaderLine($name));
}

$body = $request->getBody()->__toString();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should really cloned the stream before formatting IMO, i cannot imagine the number of issue and debugging nightmare for users not understanding how streams work.

Copy link
Member Author

@Nyholm Nyholm Jul 31, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, tell me why I should clone it. Shouldn't I just rewind it just like the FullHttpMessageFormatter?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewind is not possible everwhere, i.e. in the socket-client you cannot rewind a stream, but don't handle that here, that was just a reminder.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okey, So what do you propose?

$body = clone $request->getBody()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#49 :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not watching that repo until today. Sorry, I've missed that PR. ..

Thank you!

if (!empty($body)) {
$command .= sprintf(' --data \'%s\'', $body);
Copy link
Member

@joelwurtz joelwurtz Jul 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should espace the body (what give a json string with ' or " inside ?, need a test for this)

}

return $command;
}

/**
* {@inheritdoc}
*/
public function formatResponse(ResponseInterface $response)
{
return '';
}
}