-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Web server bundle #21039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Web server bundle #21039
Conversation
21475e2
to
1a796c0
Compare
{ | ||
$this | ||
->setDefinition(array( | ||
new InputArgument('addressport', InputArgument::OPTIONAL, 'The address to listen to (can be address:port, address, or port)', '127.0.0.1:8000'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: instead of addressport
, we could call this uri
because we accept schemes or not, IP address or hostnames, port numbers or not, etc. So this looks like a URI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would name this socket
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about address
? Like WebServer
does?
|
||
$callback = null; | ||
$disableOutput = false; | ||
if (OutputInterface::VERBOSITY_NORMAL > $output->getVerbosity()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this means === QUIET
, right ? If yes, it may be much more readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
->isQuiet()
;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
'You can either install it or use the "server:run" command instead.', | ||
)); | ||
|
||
if ($io->ask('Do you want to execute <info>server:run</info> immediately? [Yn] ', true)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by making true
the default, it means that a non-interactive process will automatically fallback to server:run. Is it expected ? I don't think it is a good idea, as it switches to a long-lived command. I think this should be done only for interactive inputs (returning the failure exit code otherwise)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabpot what about this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is like this on the current commands. So, I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I've made a new commit to change the default value to false
->setDefinition(array( | ||
new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', '127.0.0.1:8000'), | ||
new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing this option is a BC break. We should deprecate it instead (even though the class is moved elsewhere, it is the same API for people using the CLI)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introducing a new composer package with a deprecation by default, is probably a bad idea? It should be done from the framework bundle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We never kept BC on CLI commands AFAIK.
} | ||
} | ||
|
||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer a string|null
API than string|false
. The absence of value is null, not a boolean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
$this->env = $env; | ||
} | ||
|
||
public function run($router = null, $disableOutput = true, $callback = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be typehinted as callable
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -0,0 +1,35 @@ | |||
{ | |||
"name": "symfony/web-server-bundle", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you forgot the replace
rule for this package in the root
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
"name": "symfony/web-server-bundle", | ||
"type": "web-server-bundle", | ||
"description": "Symfony WebServerBundle", | ||
"keywords": [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to add some keywords for discoverability through the Packagist search
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great move, with hope it's a start for a more readable console in full edition.
2 questions : will this bundle be installed by default on Symfony 4?
How about a Symfony/web-server package and a bundle? A lot of frameworks and cmses can be interested to reuse this tiny but useful piece of code.
Merry Christmas Fabien :)
I would not need really the commands by default, i guess. What about moving |
public function __construct($address = '127.0.0.1:8000') | ||
{ | ||
if (false !== strpos($address, ':')) { | ||
list($this->hostname, $this->port) = explode(':', $address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not work when IPv6 is used.
The format for IPv6 should actually be [address]:port
, eg. [::1]:8000
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
66b1ee3
to
2a31515
Compare
d927c06
to
585d445
Compare
Auto-port detection has just been added. I've also updated the description to describe usage and differences with current commands. |
69e6a02
to
62ec25b
Compare
ping @symfony/deciders |
👍 |
Also, as the behavior have changed this need - at least - an issue to document it :) |
$io = new SymfonyStyle($input, $output); | ||
$server = new WebServer(); | ||
if ($server->isRunning($input->getOption('pidfile'))) { | ||
$io->success('Web server still listening.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
new InputArgument('addressport', InputArgument::OPTIONAL, 'The address to listen to (can be address:port, address, or port)', null), | ||
new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', null), | ||
new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'), | ||
new InputOption('pidfile', '', InputOption::VALUE_REQUIRED, 'PID file', null), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
second argument should be null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed everywhere
new InputArgument('addressport', InputArgument::OPTIONAL, 'The address to listen to (can be address:port, address, or port)', null), | ||
new InputOption('docroot', 'd', InputOption::VALUE_REQUIRED, 'Document root', null), | ||
new InputOption('router', 'r', InputOption::VALUE_REQUIRED, 'Path to custom router script'), | ||
new InputOption('pidfile', '', InputOption::VALUE_REQUIRED, 'PID file', null), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The help of the comment should explain the PID file IMO
@@ -0,0 +1,19 @@ | |||
Copyright (c) 2004-2016 Fabien Potencier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2017
now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
$this->port = $address; | ||
} else { | ||
$this->hostname = $address; | ||
$this->port = 80; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this also find the best port ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea, done
if (false !== $pos = strrpos($address, ':')) { | ||
$this->hostname = substr($address, 0, $pos); | ||
$this->port = substr($address, $pos + 1); | ||
} elseif (ctype_digit($address)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (null === $address) { | ||
$this->address = '127.0.0.1'; | ||
$this->port = $this->findBestPort(); | ||
$address = $this->address.':'.$this->port; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should return here, or put this if
in the same chain than others, to avoid parsing the address and port again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
||
if (false !== $pos = strrpos($address, ':')) { | ||
$this->hostname = substr($address, 0, $pos); | ||
$this->port = substr($address, $pos + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
62ec25b
to
a95c8e7
Compare
$this->port = $this->findBestPort(); | ||
} elseif (false !== $pos = strrpos($address, ':')) { | ||
$this->hostname = substr($address, 0, $pos); | ||
$this->port = substr($address, $pos + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed that to only allow numeric values.
👍 Status: reviewed |
@javiereguiluz |
7e60729
to
427d5e4
Compare
427d5e4
to
612bb7e
Compare
612bb7e
to
961d1ce
Compare
All comments taken into account now. |
This PR was squashed before being merged into the 3.3-dev branch (closes #21039). Discussion ---------- Web server bundle | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | yes | Deprecations? | no | Tests pass? | yes | Fixed tickets | #21040 | License | MIT | Doc PR | n/a Moved the `server:*` commands to a new bundle. It makes them more easily discoverable and more decoupled. Discoverability is important when not using symfony/symfony. In that case, the commands are not available unless you have the symfony/process component installed. With a dedicated bundle, installing the bundle also installs the dependency, making the whole process easier. Usage is the same as the current commands for basic usage: To start a web server in the foreground: ``` bin/console server:run ``` To manage a background server: ``` bin/console server:start bin/console server:stop bin/console server:status ``` The big difference is that port is auto-determined if something is already listening on port 8000. Usage is **different** if you pass options: ``` bin/console server:start 127.0.0.1:8888 bin/console server:stop # no need to pass the address again bin/console server:status # no need to pass the address again ``` That's possible as the web server now stores its address in a pid file stored in the current directory. Commits ------- f39b327 [WebServerBundle] switched auto-run of server:start to off by default 961d1ce [WebServerBundle] fixed server:start when already running 126f4d9 [WebServerBundle] added support for port auto-detection 6f689d6 [WebServerBundle] changed the way we keep track of the web server 585d445 [WebServerBundle] tweaked command docs fa7ebc5 [WebServerBundle] moved most of the logic in a new class 951a1a2 [WebServerBundle] changed wording ac1ba77 made the router configurable via env vars 48dd2b0 removed obsolete check 132902c moved server:* command to a new bundle
…ands (xabbuh) This PR was merged into the 2.7 branch. Discussion ---------- [FrameworkBundle] fix IPv6 address handling in server commands | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #21039 (comment) | License | MIT | Doc PR | This fixes #21039 (comment) as reported by @sstok for the existing commands by backporting @fabpot's patch from #21039. Commits ------- 2bb4713 fix IPv6 address handling in server commands
…ands (xabbuh) This PR was merged into the 2.7 branch. Discussion ---------- [FrameworkBundle] fix IPv6 address handling in server commands | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony/symfony#21039 (comment) | License | MIT | Doc PR | This fixes symfony/symfony#21039 (comment) as reported by @sstok for the existing commands by backporting @fabpot's patch from #21039. Commits ------- 2bb4713 fix IPv6 address handling in server commands
what about add support for https ? |
I don't think the PHP built-in webserver supports HTTPS |
Moved the
server:*
commands to a new bundle. It makes them more easily discoverable and more decoupled. Discoverability is important when not using symfony/symfony. In that case, the commands are not available unless you have the symfony/process component installed. With a dedicated bundle, installing the bundle also installs the dependency, making the whole process easier.Usage is the same as the current commands for basic usage:
To start a web server in the foreground:
To manage a background server:
The big difference is that port is auto-determined if something is already listening on port 8000.
Usage is different if you pass options:
That's possible as the web server now stores its address in a pid file stored in the current directory.