Skip to content

Commit

Permalink
Provides the response as an object, #2
Browse files Browse the repository at this point in the history
  • Loading branch information
hollodotme committed Mar 6, 2017
1 parent 2d1c963 commit 6b24663
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 44 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CH
### Changed

* Methods `sendRequest` and `sendAsyncRequest` expect to get an object of interface `hollodotme\FastCGI\Interfaces\ProvidesRequestData` - [#5]
* Methods `sendRequest` and `waitForResponse` now return an object of interface `hollodotme\FastCGI\Interfaces\ProvidesResponseData` - [#2]

### Added

Expand All @@ -20,6 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CH
* `hollodotme\FastCGI\Requests\PutRequest`
* `hollodotme\FastCGI\Requests\PatchRequest`
* `hollodotme\FastCGI\Requests\DeleteRequest`
* Response implementation - [#2]

## [2.0.1] - 2017-02-23

Expand Down Expand Up @@ -71,4 +73,5 @@ Based on [Pierrick Charron](https://github.com/adoy)'s [PHP-FastCGI-Client](http
[1.0.0]: https://github.com/hollodotme/fast-cgi-client/tree/v1.0.0

[#1]: https://github.com/hollodotme/fast-cgi-client/issues/1
[#2]: https://github.com/hollodotme/fast-cgi-client/issues/2
[#5]: https://github.com/hollodotme/fast-cgi-client/issues/5
65 changes: 62 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,13 @@ $response = $client->waitForResponse(

### Requests

Request are defined by the following interface:
As of version 1.1.0 (PHP 7.0) and 2.1.0 (PHP 7.1), request are defined by the following interface:

```php
<?php declare(strict_types=1);

namespace hollodotme\FastCGI\Interfaces;

interface ProvidesRequestData
{
public function getGatewayInterface() : string;
Expand Down Expand Up @@ -230,6 +232,29 @@ The abstract request class defines several default values which you can optional

### Responses

As of version 1.1.0 (PHP 7.0) and 2.1.0 (PHP 7.1), responses are defined by the following interface:

```php
<?php declare(strict_types=1);

namespace hollodotme\FastCGI\Interfaces;

interface ProvidesResponseData
{
public function getRequestId() : int;

public function getHeaders() : array;

public function getHeader( string $headerKey ) : string;

public function getBody() : string;

public function getRawResponse() : string;

public function getDuration() : float;
}
```

Assuming `/path/to/target/script.php` has the following content:

```php
Expand All @@ -238,7 +263,7 @@ Assuming `/path/to/target/script.php` has the following content:
echo "Hello World";
```

The response would look like this:
The raw response would look like this:

```
Content-type: text/html; charset=UTF-8
Expand All @@ -260,13 +285,47 @@ header('X-Custom: Header');
echo "Hello World";
```

The response would look like this:
The raw response would look like this:

```
X-Custom: Header
Content-type: text/html; charset=UTF-8
Hello World
```

You can retrieve all of the response data separately from the response object:

```php
# Get the request ID
echo $response->getRequestId(); # random int set by client

# Get a single response header
echo $response->getHeader('X-Custom'); # 'Header'

# Get all headers
print_r($response->getHeaders());
/*
Array (
[X-Custom] => Header
[Content-type] => text/html; charset=UTF-8
)
*/

# Get the body
echo $response->getBody(); # 'Hello World'

# Get the raw response
echo $response->getRawResponse();
/*
X-Custom: Header
Content-type: text/html; charset=UTF-8

Hello World
*/

# Get the duration
echo $response->getDuration(); # e.g. 0.0016319751739502
```

---
Expand Down
49 changes: 22 additions & 27 deletions bin/fcgiget
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,17 @@

namespace hollodotme\FastCGI;

use hollodotme\FastCGI\Requests\GetRequest;
use hollodotme\FastCGI\SocketConnections\NetworkSocket;
use hollodotme\FastCGI\SocketConnections\UnixDomainSocket;

if ( file_exists( __DIR__ . '/../vendor/autoload.php' ) )
{
require(__DIR__ . '/../vendor/autoload.php');
require __DIR__ . '/../vendor/autoload.php';
}
elseif ( file_exists( __DIR__ . '/../../../autoload.php' ) )
{
require(__DIR__ . '/../../../autoload.php');
require __DIR__ . '/../../../autoload.php';
}
else
{
Expand All @@ -47,9 +48,9 @@ if ( !isset( $_SERVER['argc'] ) )

if ( $_SERVER['argc'] < 2 )
{
echo "Usage: " . $_SERVER['argv'][0] . " URI\n\n";
echo "Ex: " . $_SERVER['argv'][0] . " localhost:9000/status\n";
echo "Ex: " . $_SERVER['argv'][0] . " unix:/var/run/php-fpm/web.sock/status\n";
echo 'Usage: ' . $_SERVER['argv'][0] . " URI\n\n";
echo 'Ex: ' . $_SERVER['argv'][0] . " localhost:9000/status\n";
echo 'Ex: ' . $_SERVER['argv'][0] . " unix:/var/run/php-fpm/web.sock/status\n";
exit( 1 );
}

Expand All @@ -76,7 +77,7 @@ else
}
if ( !$url || !isset( $url['path'] ) )
{
die( "Malformed URI" );
die( 'Malformed URI' );
}

$req = '/' . basename( $url['path'] );
Expand All @@ -96,30 +97,24 @@ if ( $sock )
}
else
{
$host = (string)(isset( $url['host'] ) ? $url['host'] : 'localhost');
$port = (int)(isset( $url['port'] ) ? $url['port'] : 9000);
$host = (string)($url['host'] ?? 'localhost');
$port = (int)($url['port'] ?? 9000);
$client = new Client( new NetworkSocket( $host, $port ) );

echo "Call: {$uri} on {$host}:{$port}\n\n";
}

$params = [
'GATEWAY_INTERFACE' => 'FastCGI/1.0',
'REQUEST_METHOD' => 'GET',
'SCRIPT_FILENAME' => $url['path'],
'SCRIPT_NAME' => $req,
'QUERY_STRING' => $url['query'],
'REQUEST_URI' => $uri,
'DOCUMENT_URI' => $req,
'SERVER_SOFTWARE' => 'php/fcgiclient',
'REMOTE_ADDR' => '127.0.0.1',
'REMOTE_PORT' => '9985',
'SERVER_ADDR' => '127.0.0.1',
'SERVER_PORT' => '80',
'SERVER_NAME' => php_uname( 'n' ),
'SERVER_PROTOCOL' => 'HTTP/1.1',
'CONTENT_TYPE' => '',
'CONTENT_LENGTH' => 0,
];
$request = new GetRequest( $url['path'], '' );
$request->addCustomVars(
[
'SCRIPT_NAME' => $req,
'QUERY_STRING' => $url['query'],
'REQUEST_URI' => $uri,
'DOCUMENT_URI' => $req,
]
);

echo $client->sendRequest( $params, '' ) . "\n";
$response = $client->sendRequest( $request );

echo $response->getRawResponse() . "\n\n";
echo 'Duration: ' . $response->getDuration() . " Sec.\n";
42 changes: 30 additions & 12 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
use hollodotme\FastCGI\Exceptions\WriteFailedException;
use hollodotme\FastCGI\Interfaces\ConfiguresSocketConnection;
use hollodotme\FastCGI\Interfaces\ProvidesRequestData;
use hollodotme\FastCGI\Interfaces\ProvidesResponseData;
use hollodotme\FastCGI\Responses\Response;
use hollodotme\FastCGI\Timing\Timer;

/**
Expand Down Expand Up @@ -105,13 +107,13 @@ public function __construct( ConfiguresSocketConnection $connection )
*
* @param ProvidesRequestData $request
*
* @return string
* @throws \hollodotme\FastCGI\Exceptions\ReadFailedException
* @throws \hollodotme\FastCGI\Exceptions\ForbiddenException
* @throws \hollodotme\FastCGI\Exceptions\WriteFailedException
* @throws \hollodotme\FastCGI\Exceptions\TimedoutException
* @return ProvidesResponseData
*/
public function sendRequest( ProvidesRequestData $request ) : string
public function sendRequest( ProvidesRequestData $request ) : ProvidesResponseData
{
$requestId = $this->sendAsyncRequest( $request );

Expand Down Expand Up @@ -165,6 +167,8 @@ public function sendAsyncRequest( ProvidesRequestData $request ) : int

$requestPacket .= $this->packetEncoder->encodePacket( self::STDIN, '', $requestId );

$startTime = microtime( true );

if ( fwrite( $this->socket, $requestPacket ) === false || fflush( $this->socket ) === false )
{
$info = stream_get_meta_data( $this->socket );
Expand All @@ -181,8 +185,10 @@ public function sendAsyncRequest( ProvidesRequestData $request ) : int
}

$this->requests[ $requestId ] = [
'state' => self::REQ_STATE_WRITTEN,
'response' => null,
'state' => self::REQ_STATE_WRITTEN,
'response' => null,
'startTime' => $startTime,
'duration' => 0,
];

return $requestId;
Expand Down Expand Up @@ -288,9 +294,9 @@ private function readPacket() : ?array
* @throws ReadFailedException
* @throws TimedoutException
* @throws WriteFailedException
* @return string
* @return ProvidesResponseData
*/
public function waitForResponse( int $requestId, int $timeoutMs = 0 ) : string
public function waitForResponse( int $requestId, int $timeoutMs = 0 ) : ProvidesResponseData
{
if ( !isset( $this->requests[ $requestId ] ) )
{
Expand All @@ -300,7 +306,11 @@ public function waitForResponse( int $requestId, int $timeoutMs = 0 ) : string
// If we already read the response during an earlier call for different id, just return it
if ( in_array( $this->requests[ $requestId ]['state'], [ self::REQ_STATE_OK, self::REQ_STATE_ERR ], true ) )
{
return $this->requests[ $requestId ]['response'];
return new Response(
$requestId,
(string)$this->requests[ $requestId ]['response'],
(float)$this->requests[ $requestId ]['duration']
);
}

if ( $timeoutMs > 0 )
Expand Down Expand Up @@ -380,16 +390,24 @@ public function waitForResponse( int $requestId, int $timeoutMs = 0 ) : string
{
case self::CANT_MPX_CONN:
throw new WriteFailedException( 'This app can\'t multiplex [CANT_MPX_CONN]' );
break;

case self::OVERLOADED:
throw new WriteFailedException( 'New request rejected; too busy [OVERLOADED]' );
break;

case self::UNKNOWN_ROLE:
throw new WriteFailedException( 'Role value not known [UNKNOWN_ROLE]' );
break;

case self::REQUEST_COMPLETE:
return $this->requests[ $requestId ]['response'];
break;
$duration = microtime( true ) - (float)$this->requests[ $requestId ]['startTime'];

$this->requests[ $requestId ]['duration'] = $duration;

return new Response(
$requestId,
(string)$this->requests[ $requestId ]['response'],
(float)$this->requests[ $requestId ]['duration']
);

default:
throw new ReadFailedException( 'Unknown content.' );
}
Expand Down
43 changes: 43 additions & 0 deletions src/Interfaces/ProvidesResponseData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php declare(strict_types = 1);
/*
* Copyright (c) 2010-2014 Pierrick Charron
* Copyright (c) 2016 Holger Woltersdorf
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

namespace hollodotme\FastCGI\Interfaces;

/**
* Interface ProvidesResponseData
* @package hollodotme\FastCGI\Interfaces
*/
interface ProvidesResponseData
{
public function getRequestId() : int;

public function getHeaders() : array;

public function getHeader( string $headerKey ) : string;

public function getBody() : string;

public function getRawResponse() : string;

public function getDuration() : float;
}
Loading

0 comments on commit 6b24663

Please sign in to comment.