Question: I have a Sinatra app running in nginx (using thin as a back-proxy) and I'm using `redirect '/<path>'` statements in Sinatra. However, when I access the site under https, those redirects send me to `http://localhost/<path>` rather than to `https://localhost/<path>` as they should. 

Currently, nginx passes control to thin with this command `proxy_pass http://thin_cluster`, where `thin_cluster` is 

```
upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; }

```

How can I fix this?

Answer: 
`url()` determines whether to use HTTP or HTTPS based on information from the `Sinatra::Request` class, which is derived from the `Rack::Request` class. When put behind a reverse proxy like Nginx, the reverse proxy has to inject some headers telling Rack (and thus Sinatra) about how the world sees it. Sadly, Nginx doesn't set these headers by default, so we'll have to do so manually.

Let's look at an example problematic configuration.

```
# Bad configuration
location / {
    proxy_pass http://127.0.0.1:9000;
}

```

Sinatra doesn't know it's behind a reverse proxy, so `url('/robots.txt')` will generate `http://127.0.0.1:9000/robots.txt`. Nginx is going to try to correct it automatically with the default `proxy_redirect` substitution, resulting in `http://hostname/robots.txt`.

Here's an example proxy clause from my own Nginx configuration.

```
location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-SSL on;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:9000;
}

```

`X-Forwarded-SSL: on` tells Sinatra that it's sitting behind HTTPS and not HTTP, and setting `Host: $http_host` tells Sinatra the host name of the real server. Now, `url('/robots.txt')` will output `https://hostname/robots.txt`. Since we don't need Nginx to run substitutions on our redirects, I turned it off explicitly with `proxy_redirect off;`. (The `X-Forwarded-For` is just so Sinatra can figure out the user's IP address, too.)

An additional benefit to relying on Sinatra to do everything correctly instead of Nginx's `proxy_redirect` clause is that you can use the `url()` function in within views and the like as well.

`X-Forwarded-SSL` is only one of a few headers you can set. `HTTPS: on`, `X-Forwarded-Scheme: https`, and `X-Forwarded-Proto: https` should work just fine, too. Note that setting the scheme to something like `otherproto` will not work with Sinatra since it checks if it's HTTPS or not and generating the URL based on that boolean instead of just copying the scheme.

If you're interested in looking through the code yourself, I recommend these two references as a starting point:

<https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L284> (`def uri`)
<https://github.com/rack/rack/blob/master/lib/rack/request.rb#L199> (`def scheme`)
Try this:

```
redirect "https://#{request.host}/<path>"

```

Sinatra is lightweight, it does not have any detection for this by default i guess.