Conversation
When booting Puma via a `rails server` command it is desired to bind to `localhost` over `0.0.0.0`. It is less secure to run a development application on `0.0.0.0`. To understand the differences here is a SO post https://stackoverflow.com/questions/20778771/what-is-the-difference-between-0-0-0-0-127-0-0-1-and-localhost This PR works by detecting the "environment" option passed by default from Rails https://github.com/rails/rails/blob/663f6cc14fd01650546ed508efb3f7ad8e30135c/railties/lib/rails/commands/server/server_command.rb#L175. When it is set to "development" then `localhost` is used.
rafaelfranca
approved these changes
Jan 4, 2019
schneems
added a commit
to schneems/puma
that referenced
this pull request
Jan 4, 2019
This issue is somewhat tricky. When Rails is booted via `rails server` there are two types of configuration options passed, ones specified directly by a user like `rails s -p 3001` will always "win". For any other config that is not explicitly passed in, puma will consider it a "default". For example when you run `rails s` (without -p) then the default port will be 3000. There is one other way to configure puma though, and that is via a config file: ``` # config/puma.rb port 3002 ``` This is the order of precedence for configuration 1) Anything the user explicitly passes to `rails s` 2) Config specified in `config/puma.rb` file 3) Default values passed in via `rails s` 4) Defaults values stored in puma This fallback mechanism works well except in the case of calling `port` in a `config/puma.rb` file. To understand look at the [old method definition](https://github.com/puma/puma/blob/2668597ec1dd9546d83db9f2ec5ad092add483e6/lib/puma/dsl.rb#L140-L145): ``` def port(port, host=nil) host ||= Configuration::DefaultTCPHost bind "tcp://#{host}:#{port}" end ``` When the `port` method gets called, even if the user did not specify a `host` the `Configuration::DefaultTCPHost` will be used, which is a problem for local development because it defaults to `0.0.0.0`. [SO about 0.0.0.0 versus localhost](https://stackoverflow.com/questions/20778771/what-is-the-difference-between-0-0-0-0-127-0-0-1-and-localhost). In this case, while a user did directly specify a port, they did not specify a host, so you would expect the `rails s` defaults passed in to take affect. To make Puma respect that the host coming from `rails s` has more precedence than it's own default host, we must introduce the ability to set and retrieve a default_host value. This is then used in the rack handler so when `rails s` passes in `:Host => "localhost"` then it is used instead of reverting to `0.0.0.0`. The issue with puma#1699 is the test was wrong, it would have failed if a config file was present with a `port` invocation.
schneems
added a commit
to schneems/puma
that referenced
this pull request
Jan 4, 2019
This issue is somewhat tricky. When Rails is booted via `rails server` there are two types of configuration options passed, ones specified directly by a user like `rails s -p 3001` will always "win". For any other config that is not explicitly passed in, puma will consider it a "default". For example when you run `rails s` (without -p) then the default port will be 3000. There is one other way to configure puma though, and that is via a config file: ``` # config/puma.rb port 3002 ``` This is the order of precedence for configuration 1) Anything the user explicitly passes to `rails s` 2) Config specified in `config/puma.rb` file 3) Default values passed in via `rails s` 4) Defaults values stored in puma This fallback mechanism works well except in the case of calling `port` in a `config/puma.rb` file. To understand look at the [old method definition](https://github.com/puma/puma/blob/2668597ec1dd9546d83db9f2ec5ad092add483e6/lib/puma/dsl.rb#L140-L145): ``` def port(port, host=nil) host ||= Configuration::DefaultTCPHost bind "tcp://#{host}:#{port}" end ``` When the `port` method gets called, even if the user did not specify a `host` the `Configuration::DefaultTCPHost` will be used, which is a problem for local development because it defaults to `0.0.0.0`. [SO about 0.0.0.0 versus localhost](https://stackoverflow.com/questions/20778771/what-is-the-difference-between-0-0-0-0-127-0-0-1-and-localhost). In this case, while a user did directly specify a port, they did not specify a host, so you would expect the `rails s` defaults passed in to take affect. To make Puma respect that the host coming from `rails s` has more precedence than it's own default host, we must introduce the ability to set and retrieve a default_host value. This is then used in the rack handler so when `rails s` passes in `:Host => "localhost"` then it is used instead of reverting to `0.0.0.0`. The issue with puma#1699 is the test was wrong, it would have failed if a config file was present with a `port` invocation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When booting Puma via a
rails servercommand it is desired to bind tolocalhostover0.0.0.0. It is less secure to run a development application on0.0.0.0.To understand the differences here is a SO post https://stackoverflow.com/questions/20778771/what-is-the-difference-between-0-0-0-0-127-0-0-1-and-localhost
This PR works by detecting the "environment" option passed by default from Rails https://github.com/rails/rails/blob/663f6cc14fd01650546ed508efb3f7ad8e30135c/railties/lib/rails/commands/server/server_command.rb#L175. When it is set to "development" then
localhostis used.