urlerlangnitrogen

How to get full URL of a page with Nitrogen?


I want to make certain pages of my site available only by https. I think it would be ok to recognize protocol right in the page.erl and then redirect to the right URL. Something like

case Protocol of
    http -> wf:redirect('https://' ++ UrlWithNoProtocol);
    _ -> ok
end

Of course I can get Protocol and UrlWithNoProtocol simply splitting URL by "://". But the thing is, I have no idea: how to get an full URL of page?


Solution

  • My response on the Nitrogen Mailing list, duplicated here due to the nice markdownish formatting:

    I would do this one of two ways, and both of them mean putting Nitrogen behind a reverse proxy like Nginx.

    The first way would be to have simple rewrite rules in nginx that force SSL for certain pages. For example, in nginx, if you wanted to redirect all requests that start with /admin to be over HTTPS, you could do this in your HTTP section.

    location ^~ /admin {
         rewrite ^ https://$http_host$request_uri? permanent;
    }
    

    You can read about configuring nginx to run over SSL at (all the way at the bottom): https://github.com/nitrogen/nitrogen_core/blob/master/doc/org-mode/config.org

    The next alternative would be to (once again) put nitrogen behind a reverse proxy, but this time, check for the existence of a header indicating that the request is secure (this header would be inserted by nginx).

    For example, you could add a rule in your 'ssl' section in your nginx configuration that sets a header like:

    proxy_set_header X-Forwarded-SSL on;
    

    Then you could check for the existence of the header with wf:header(x_forwarded_ssl).

    If you're not using a reverse proxy, then the easiest check is probably to check which port the site is being served with by getting the request, then the socket port

    Req = wf_context:request_bridge(),
    Port = Req:peer_port().
    

    Then, the check is simply if the Port is 80, it's http, if it 443, then it's https.

    Personally, I'd opt for the nginx solution, since with any degree of scaling, it'd be nice to simply scale out by adding additional servers and letting nginx do the load balancing and ssl handling for you.