Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
command: |
rm -Rf var/*
composer require react/filesystem --no-update
composer require wyrihaximus/react-child-process-pool:1.6.* --no-update
composer require seregazhuk/php-watcher:^0.5.2 --no-update
composer require drift/event-bus-bundle:^0.1 --no-update
composer update -n --prefer-dist
Expand Down Expand Up @@ -71,4 +72,4 @@ workflows:
jobs:
- test-php74
- test-php74-with-filesystem
- test-php80
- test-php80
18 changes: 9 additions & 9 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@
use Psr\Http\Message\StreamInterface;
use React\EventLoop\LoopInterface;
use React\Filesystem\FilesystemInterface;
use React\Http\HttpServer;
use React\Http\Message\Response as ReactResponse;
use React\Http\Middleware\LimitConcurrentRequestsMiddleware;
use React\Http\Middleware\StreamingRequestMiddleware;
use React\Http\Server as HttpServer;
use React\Promise\Promise;
use React\Promise\PromiseInterface;
use function React\Promise\reject;
use function React\Promise\resolve;
use React\Socket\Server as SocketServer;
use React\Socket\SocketServer;
use React\Stream\ReadableStreamInterface;
use React\Stream\ThroughStream;
use Throwable;
Expand All @@ -52,7 +52,6 @@ class Application
private LoopInterface $loop;
private ServerContext $serverContext;
private string $rootPath;
private string $bootstrapPath;
private string $kernelAdapter;
private OutputPrinter $outputPrinter;
private MimeTypeChecker $mimeTypeChecker;
Expand All @@ -63,7 +62,6 @@ class Application
* @param OutputPrinter $outputPrinter
* @param MimeTypeChecker $mimeTypeChecker
* @param string $rootPath
* @param string $bootstrapPath
*
* @throws Exception
*/
Expand All @@ -72,14 +70,12 @@ public function __construct(
ServerContext $serverContext,
OutputPrinter $outputPrinter,
MimeTypeChecker $mimeTypeChecker,
string $rootPath,
string $bootstrapPath
string $rootPath
) {
$this->loop = $loop;
$this->serverContext = $serverContext;
$this->outputPrinter = $outputPrinter;
$this->rootPath = $rootPath;
$this->bootstrapPath = $bootstrapPath;
$this->mimeTypeChecker = $mimeTypeChecker;

ErrorHandler::handle();
Expand Down Expand Up @@ -111,8 +107,8 @@ public function runServer(
$socket = new SocketServer(
$this->serverContext->getHost().':'.
$this->serverContext->getPort(),
$this->loop,
['tcp' => ['so_reuseport' => ($this->serverContext->getWorkers() > 1)]]
['tcp' => ['so_reuseport' => ($this->serverContext->getWorkers() > 1)]],
$this->loop
);

$http = new HttpServer(
Expand Down Expand Up @@ -219,6 +215,10 @@ private function toServerResponse(
$response = $response->withoutHeader('x-server-message');
}

if ($this->serverContext->mustCloseConnections()) {
$response = $response->withHeader('Connection', 'close');
}

$serverResponse =
new ServerResponseWithMessage(
$response,
Expand Down
1 change: 0 additions & 1 deletion src/Console/RunServerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ protected function executeServerCommand(
$outputPrinter,
$mimeTypeChecker,
$rootPath,
$this->bootstrapPath
);

$kernelAdapterNamespace = $serverContext->getAdapter();
Expand Down
7 changes: 4 additions & 3 deletions src/Console/ServerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
use Drift\Server\Context\ServerContext;
use Drift\Server\ServerHeaderPrinter;
use Exception;
use React\EventLoop\Factory as EventLoopFactory;
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
Expand Down Expand Up @@ -76,7 +76,8 @@ protected function configure()
->addOption('allowed-loop-stops', null, InputOption::VALUE_OPTIONAL, 'Number of allowed loop stops', 0)
->addOption('workers', null, InputOption::VALUE_OPTIONAL,
'Number of workers. Use -1 to get as many workers as physical thread available for your system. Maximum of 128 workers. Option disabled for watch command.', 1
);
)
->addOption('close-connections', null, InputOption::VALUE_NONE, 'Close all connections by adding "Connection: Close" header each time.');

/*
* If we have the EventBus loaded, we can add listeners as well
Expand Down Expand Up @@ -115,7 +116,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->configureServerContext($serverContext);
$outputPrinter = $this->createOutputPrinter($output, $serverContext->isQuiet(), $serverContext->isAlmostQuiet());

$loop = EventLoopFactory::create();
$loop = Loop::get();
if ($serverContext->shouldPrintImportantOutput()) {
ServerHeaderPrinter::print(
$serverContext,
Expand Down
3 changes: 1 addition & 2 deletions src/Console/WatchServerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ protected function executeServerCommand(
$serverContext,
$outputPrinter,
$mimeTypeChecker,
$rootPath,
$this->bootstrapPath
$rootPath
);

$argv = $this->argv;
Expand Down
10 changes: 10 additions & 0 deletions src/Context/ServerContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ final class ServerContext
private int $requestBodyBuffer;
private int $allowedLoopStops;
private int $workers;
private bool $closeConnections;

/**
* @param InputInterface $input
Expand Down Expand Up @@ -113,6 +114,7 @@ public static function buildByInput(InputInterface $input): ServerContext
$serverContext->limitConcurrentRequests = intval($input->getOption('concurrent-requests'));
$serverContext->requestBodyBuffer = intval($input->getOption('request-body-buffer'));

$serverContext->closeConnections = boolval($input->getOption('close-connections'));
$serverContext->allowedLoopStops = intval($input->getOption('allowed-loop-stops'));
$serverContext->workers = \intval($input->getOption('workers'));
if (-1 === $serverContext->workers) {
Expand Down Expand Up @@ -310,6 +312,14 @@ public function cleanWorkers()
$this->workers = 1;
}

/**
* @return bool
*/
public function mustCloseConnections(): bool
{
return $this->closeConnections;
}

/**
* Build queue architecture from array of strings.
*
Expand Down
48 changes: 48 additions & 0 deletions tests/CloseConnectionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

/*
* This file is part of the Drift Server
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* Feel free to edit as you please, and have fun.
*
* @author Marc Morera <yuhu@mmoreram.com>
*/

declare(strict_types=1);

namespace Drift\Server\Tests;

/**
* Class CloseConnectionsTest.
*/
class CloseConnectionsTest extends BaseTest
{
/**
* @group lol
*/
public function testKeepAlive()
{
list($process, $port, $initialOutput) = $this->buildServer(['--debug']);
list($_, $headers) = Utils::curl("http://127.0.0.1:$port/text");
$this->waitForChange($process, $initialOutput);
$this->assertEquals('keep-alive', $headers['Connection']);

$process->stop();
}

/**
* @group lol
*/
public function testConnectionCloses()
{
list($process, $port, $initialOutput) = $this->buildServer(['--debug', '--close-connections']);
list($_, $headers) = Utils::curl("http://127.0.0.1:$port/text");
$this->waitForChange($process, $initialOutput);
$this->assertEquals('close', $headers['Connection']);

$process->stop();
}
}
2 changes: 1 addition & 1 deletion tests/CompressionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function testAlreadyEncodedContent()
{
list($process, $port) = $this->buildServer();
$response = Utils::curl("http://127.0.0.1:$port/gzip", [
"Accept-Encoding: gzip",
'Accept-Encoding: gzip',
]);

$this->assertEquals('ReactPHP Response', gzdecode($response[0]));
Expand Down
2 changes: 1 addition & 1 deletion tests/FakeKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ

if ('/gzip' === $pathInfo) {
return new Response($code, [
'Content-Encoding' => 'gzip'
'Content-Encoding' => 'gzip',
], gzencode('ReactPHP Response'));
}

Expand Down