# Client specified server port

**URL:** <https://www.ruby-forum.com/t/client-specified-server-port/243134>\
**Category:** NGINX\
**Created:** [August 25, 2015, 12:36am UTC](https://www.ruby-forum.com/t/client-specified-server-port/243134 "2015-08-25T00:36:25Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [August 25, 2015, 12:36am UTC](https://www.ruby-forum.com/t/client-specified-server-port/243134/1 "2015-08-25T00:36:25Z")

</div>

Hi,

The return directive allows the use of URLs relative to the server, in  
which case the scheme, server name and port are automatically  
prepended by Nginx.

The port is, however, the port on which the request was received,  
which is not always the port to which the request was sent, i. e. the  
one specified in the Host header field. For example, tunneling  
[nginx.org:80](http://nginx.org:80) through [example.com:8000](http://example.com:8000) a redirect will lead to  
[example.com:80](http://example.com:80).

Also, there is no variable exposing this value, so one must extract it  
themselves to explicitly specify in the redirect URL:

```
set $is_port '';
set $port '';

if ($http_host ~ :(\d+)$) {
    set $is_port ':';
    set $port $1;
}

```

Maybe this is something that would worth considering as an  
enhancement. Making return use the port in the Host header or to  
preserve backwards compatibility, introducing a switch,  
request\_port\_in\_redirect, complementing server\_name\_in\_redirect, off  
by default, and at the same time exposing this in a $request\_port  
variable.

What do you think?

Ádám

---

<div class="post-metadata">

**Author:** ![JoSSSSdSSm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5f9b8f/32.png) [@JoSSSSdSSm](https://www.ruby-forum.com/u/JoSSSSdSSm)\
**Post date:** [August 25, 2015, 4:56am UTC](https://www.ruby-forum.com/t/client-specified-server-port/243134/2 "2015-08-25T04:56:58Z")

</div>

Hi,

Maybe you can use following config which is shorter and does not use the  
evil “if”.

map $http\_host $redirect\_port {  
default “”;  
.\*(:\d+) $1;  
}

return 302 $scheme://$host$redirect\_port/

---

<div class="post-metadata">

**Author:** ![JoSSSSdSSm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/5f9b8f/32.png) [@JoSSSSdSSm](https://www.ruby-forum.com/u/JoSSSSdSSm)\
**Post date:** [August 26, 2015, 12:03am UTC](https://www.ruby-forum.com/t/client-specified-server-port/243134/3 "2015-08-26T00:03:11Z")

</div>

On Tue, Aug 25, 2015 at 12:35:55AM +0200, Jo dm wrote:

Hi there,

> Also, there is no variable exposing this value, so one must extract it  
> themselves to explicitly specify in the redirect URL:

I agree that it would be nice to have the  
port-specified-in-the-Host-header easily available.

Until it is, you might be able to just use $http\_host directly, possibly  
falling back to $host if it is empty.

(Basically, any current request that does not include a Host: header is  
probably someone playing games. Sending them back a broken redirect is  
possibly not a problem. If you’re willing to restrict your potential  
clients to “ones that send a sensible Host: header”, you don’t need to  
worry about the fallback.)

That is, just always use

return 301 $scheme://$http\_host/local;

instead of the current

return 301 /local;

(and even $scheme may be overkill, unless you use a single server{}  
block for http and https.)

> Maybe this is something that would worth considering as an  
> enhancement. Making return use the port in the Host header or to  
> preserve backwards compatibility, introducing a switch,  
> request\_port\_in\_redirect, complementing server\_name\_in\_redirect, off  
> by default, and at the same time exposing this in a $request\_port  
> variable.
> 
> What do you think?

I think it is probably worthwhile; and I think I won’t be writing the  
code to implement it 😉

Cheers,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
