Skip to content

Commit

Permalink
[WIP] Added SSL support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul committed May 30, 2017
1 parent d8cd138 commit 24d7b01
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Expand Up @@ -3,6 +3,11 @@ notifications:

sudo: false

addons:
apt:
packages:
- stunnel4

language: php

php:
Expand Down
4 changes: 4 additions & 0 deletions src/Net/Http/HttpConnector.php
Expand Up @@ -59,6 +59,10 @@ public function fetchFreshData($source, EncapsulatedOptions $options = null)
$this->options->extractHttpContextOptions(),
$options ? $options->extractHttpContextOptions() : []
),
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
])
)) {
$error = error_get_last();
Expand Down
98 changes: 83 additions & 15 deletions test/Functional/Porter/Net/Http/HttpConnectorTest.php
Expand Up @@ -6,12 +6,14 @@
use ScriptFUSION\Porter\Net\Http\HttpConnector;
use ScriptFUSION\Porter\Net\Http\HttpOptions;
use ScriptFUSION\Porter\Net\Http\HttpServerException;
use ScriptFUSION\Porter\Specification\ImportSpecification;
use ScriptFUSION\Retry\ExceptionHandler\ExponentialBackoffExceptionHandler;
use Symfony\Component\Process\Process;

final class HttpConnectorTest extends \PHPUnit_Framework_TestCase
{
const HOST = '[::1]:12345';
const SSL_HOST = '[::1]:6666';
const URI = '/test?baz=qux';

private static $dir;
Expand Down Expand Up @@ -39,6 +41,20 @@ public function testConnectionToLocalWebserver()
self::assertRegExp("[^$header$]m", $response);
}

/**
* @requires OS Linux
*/
public function testSslConnectionToLocalWebserver()
{
$server = $this->startServer('feedback');
$this->startSsl();
$response = $this->fetchViaSsl();
$this->stopSsl();
$this->stopServer($server);

self::assertRegExp('[\AGET \Q' . self::SSL_HOST . '\E/ HTTP/\d+\.\d+$]m', $response);
}

public function testConnectionTimeout()
{
$this->setExpectedException(HttpConnectionException::class);
Expand Down Expand Up @@ -70,29 +86,20 @@ public function testErrorResponse()
*/
private function startServer($script)
{
$server = (
new Process(sprintf(
$server = new Process(
sprintf(
'%sphp -S %s %s.php',
// Prevent forking on some Unix systems.
file_exists('/bin/sh') ? 'exec ' : '',
self::HOST,
$script
))
)->setWorkingDirectory(self::$dir);
),
self::$dir
);
$server->start();

// Wait for server to spawn.
\ScriptFUSION\Retry\retry(5, function () {
self::waitForHttpServer(function () {
$this->fetch();
}, function (\Exception $exception) {
static $handler;
$handler = $handler ?: new ExponentialBackoffExceptionHandler();

if (!$exception instanceof HttpConnectionException) {
return false;
}

return $handler();
});

return $server;
Expand All @@ -103,10 +110,71 @@ private function stopServer(Process $server)
$server->stop();
}

private function startSsl()
{
$accept = str_replace($filter = ['[', ']'], null, self::SSL_HOST);
$connect = str_replace($filter, null, self::HOST);
$temp = tempnam(sys_get_temp_dir(), 'Porter');

(new Process(
// Generate blank, self-signed SSL certificate.
"openssl req -new -x509 -nodes -subj / -keyout '$temp' -out '$temp'
{ stunnel4 -fd 0 || stunnel -fd 0; } <<.
# Disable PID to run as non-root user.
pid=
# Must run as foreground process on Travis, for some reason.
foreground=yes
[]
cert=$temp
accept=$accept
connect=$connect
."
))->start();

self::waitForHttpServer(function () {
$this->fetchViaSsl();
});
}

private function stopSsl()
{
`pkill stunnel`;
}

private function fetch(Connector $connector = null)
{
$connector = $connector ?: $this->connector;

return $connector->fetch('http://' . self::HOST . self::URI);
}

private function fetchViaSsl()
{
return $this->connector->fetch('https://' . self::SSL_HOST);
}

/**
* Waits for the specified HTTP server invoker to stop throwing errors.
*
* @param \Closure $serviceInvoker HTTP service invoker.
*/
private static function waitForHttpServer(\Closure $serviceInvoker)
{
\ScriptFUSION\Retry\retry(
ImportSpecification::DEFAULT_FETCH_ATTEMPTS,
$serviceInvoker,
function (\Exception $exception) {
static $handler;
$handler = $handler ?: new ExponentialBackoffExceptionHandler;

if (!$exception instanceof HttpConnectionException) {
return false;
}

return $handler();
}
);
}
}

0 comments on commit 24d7b01

Please sign in to comment.