guiocavalcanti
guiocavalcanti

Reputation: 13

Protocol relative URLs missing port in Rails URL helpers

I'm trying to generate protocol relative URLs using Rails URL helpers. For this I set the protocol option to false. But whenever I generate a URL, the port part is missing.

dashboard (master) > rails c
Loading development environment (Rails 4.0.3)
2.0.0p247 :001 >   include Rails.application.routes.url_helpers
 => Object
2.0.0p247 :002 > tunnels_url(host: "0.0.0.0:3000", protocol: false)
 => "//0.0.0.0/tunnels"

The thing is: I'd like to generate protocol relative URL but for a custom port.

Upvotes: 1

Views: 1625

Answers (1)

user740584
user740584

Reputation:

This seems to be intentional. From url.rb, there is the code:

options[:protocol] = normalize_protocol(options)
options[:host]     = normalize_host(options)
options[:port]     = normalize_port(options)

result << options[:protocol]
result << rewrite_authentication(options)
result << options[:host]
result << ":#{options[:port]}" if options[:port]

result ends up being the url string you want to build.

Now, normalize_protocol will return \\ if you set the protocol: false

normalize_port then looks at options[:protocol] specifically returning nil if options[:protocol] == '//' regardless of whether you included the port in the host option or specifically give the port option.

By doing the normalization in this order what you want seems to be impossible from the core code.

I don't know if this is an oversight or if it is deliberate. Maybe it is considered that you cannot have a port without the protocol. In any event it might be worth you raising an issue with Rails.

In the meantime, you could workaround it with a gsub. Not brilliant but probably better than nothing. Something like:

2.0.0-p247 :002 > tunnels_url(host: "0.0.0.0port", protocol: false).gsub('port',':3000')
 => "//0.0.0.0:3000/tunnels" 

Upvotes: 1

Related Questions