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
20 changes: 12 additions & 8 deletions src/Illuminate/Foundation/Console/ServeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
use Illuminate\Support\Carbon;
use Illuminate\Support\Env;
use Illuminate\Support\InteractsWithTime;
use InvalidArgumentException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Process\Process;

use function Illuminate\Support\php_binary;
use function Termwind\terminal;

Expand Down Expand Up @@ -291,23 +291,23 @@ protected function flushOutputBuffer()
}

if (str($line)->contains(' Accepted')) {
$requestPort = $this->getRequestPortFromLine($line);
$requestPort = static::getRequestPortFromLine($line);

$this->requestsPool[$requestPort] = [
$this->getDateFromLine($line),
$this->requestsPool[$requestPort][1] ?? false,
microtime(true),
];
} elseif (str($line)->contains([' [200]: GET '])) {
$requestPort = $this->getRequestPortFromLine($line);
$requestPort = static::getRequestPortFromLine($line);

$this->requestsPool[$requestPort][1] = trim(explode('[200]: GET', $line)[1]);
} elseif (str($line)->contains('URI:')) {
$requestPort = $this->getRequestPortFromLine($line);
$requestPort = static::getRequestPortFromLine($line);

$this->requestsPool[$requestPort][1] = trim(explode('URI: ', $line)[1]);
} elseif (str($line)->contains(' Closing')) {
$requestPort = $this->getRequestPortFromLine($line);
$requestPort = static::getRequestPortFromLine($line);

if (empty($this->requestsPool[$requestPort])) {
$this->requestsPool[$requestPort] = [
Expand Down Expand Up @@ -374,11 +374,15 @@ protected function getDateFromLine($line)
* @param string $line
* @return int
*/
protected function getRequestPortFromLine($line)
public static function getRequestPortFromLine($line)
{
preg_match('/:(\d+)\s(?:(?:\w+$)|(?:\[.*))/', $line, $matches);
preg_match('/(\[\w+\s\w+\s\d+\s[\d:]+\s\d{4}\]\s)?:(\d+)\s(?:(?:\w+$)|(?:\[.*))/', $line, $matches);

if (! isset($matches[2])) {
throw new \InvalidArgumentException("Failed to extract the request port. Ensure the log line contains a valid port: {$line}");
}

return (int) $matches[1];
return (int) $matches[2];
}

/**
Expand Down
76 changes: 76 additions & 0 deletions tests/Foundation/Console/ServeCommandLogParserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Illuminate\Tests\Foundation\Console;

use Illuminate\Foundation\Console\ServeCommand;
use PHPUnit\Framework\TestCase;

class ServeCommandLogParserTest extends TestCase
{
public function testExtractRequestPortWithValidLogLine()
{
$line = '[Mon Nov 19 10:30:45 2024] :8080 Info';

$this->assertEquals(8080, ServeCommand::getRequestPortFromLine($line));
}

public function testExtractRequestPortWithValidLogLineAndExtraData()
{
$line = '[Mon Nov 19 10:30:45 2024] :3000 [Client Connected]';

$this->assertEquals(3000, ServeCommand::getRequestPortFromLine($line));
}

public function testExtractRequestPortWithValidLogLineWithoutDate()
{
$line = ':5000 [Server Started]';

$this->assertEquals(5000, ServeCommand::getRequestPortFromLine($line));
}

public function testExtractRequestPortWithMissingPort()
{
$line = '[Mon Nov 19 10:30:45 2024] Info';

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: [Mon Nov 19 10:30:45 2024] Info');

ServeCommand::getRequestPortFromLine($line);
}

public function testExtractRequestPortWithInvalidPortFormat()
{
$line = '[Mon Nov 19 10:30:45 2024] :abcd Info';

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: [Mon Nov 19 10:30:45 2024] :abcd Info');

ServeCommand::getRequestPortFromLine($line);
}

public function testExtractRequestPortWithEmptyLogLine()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: ');

ServeCommand::getRequestPortFromLine('');
}

public function testExtractRequestPortWithWhitespaceOnlyLine()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: ');

ServeCommand::getRequestPortFromLine(' ');
}

public function testExtractRequestPortWithRandomString()
{
$line = 'Random log entry without port';

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Failed to extract the request port. Ensure the log line contains a valid port: Random log entry without port');

ServeCommand::getRequestPortFromLine($line);
}
}