Q:

How to force HTTPS with Jetty Embedded on Heroku with Automated Certificate Management

I have a REST app written in Java using Jetty Embedded, running on a Heroku environment. I would like to force all traffic to go through HTTPS. There are some good answers on how to achieve this such as this one and this one. However, all answers require the TLS/SSL certificate to be read from a file. I would like to use Heroku's Automated Certificate Management (details here) to avoid having to renew certificates every year as they expire. Using ACM means that I do not have access to the certificate file.
Is there any way to configure Jetty to force HTTPS without reading the certificate from a file, or somehow to still be able to use Heroku ACM?

A:

You'll can do this with a servlet filter that implement doFilter like this:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest)request;
    HttpServletResponse resp = (HttpServletResponse)response;

    String protocol = req.getHeader("X-Forwarded-Proto");

    if (protocol.equals("http")) {
        String url = "https://" + req.getServerName() + req.getContextPath() + req.getServletPath();
        if (req.getPathInfo() != null) {
            url += req.getPathInfo();
        }

        System.out.println("Forwarding request to: " + url);
        resp.sendRedirect(url);
    } else {
        System.out.println("Not forwarding protocol: " + protocol);
        chain.doFilter(request, response);
    }
}

Here's a complete example using Tomcat, but the principle is the same.

