2

I have some servlets running in Jetty, deployed on Heroku, handling POST requests.

Some, but not all, POST requests MUST come over https. Whether or not a request should be forced to be on https depends on the http body of the POST request.

I need to figure out, from inside the servlet, whether the incoming request used https (SSL) or not, so that I can send the appropriate response. However, nothing I have tried seems to work.

I tried the obvious HttpServletRequest.getProtocol() but that apparently returns the same constant whether the protocol was http or https.

I tried HttpServletRequest.isSecure() however that is returning false even though my test request was sent to a url starting with https://

When I call HttpUtils.getRequestURL( HttpServletRequest ).toString(); I get an apparrently reconstructed url that starts with "http://" even though my test request was sent to a url starting with "https://"

According to the post "Enforce HTTPS with Embedded Jetty on Heroku" heroku has some load balancers, and I should get the value of the "x-forwarded-proto" header. That header is blank.

FYI I am using the default SSL endpoint provided by the heroku api -- I am not using their SSL Endpoint extension, because this url is not being loaded in a browser (so I don't need a custom domain in the url).

Can anyone tell me how to tell if HTTPS was used in the incoming request?

Community
  • 1
  • 1

1 Answers1

2

I know nothing about Heroku, but if you're programmatically configuring Jetty (as opposed to using the XML configuration), you likely need to add the SecureRequestCustomizer to your HttpConfiguration. It sets the secure flag on the requests, as well as setting the scheme to HTTPS. You can find examples here, but briefly:

final HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSecurePort(httpsPort);
final ServerConnector httpConnector = new ServerConnector(server,
    new HttpConnectionFactory(httpConfig));
httpConnector.setPort(httpPort);
server.addConnector(httpConnector);

final HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
httpsConfig.addCustomizer(new SecureRequestCustomizer()); // !!!
final HttpConnectionFactory httpsFactory = new HttpConnectionFactory(httpsConfig);
final SslConnectionFactory sslFactory = new SslConnectionFactory(sslCtx,
    httpsFactory.getProtocol());
final ServerConnector httpsConnector = new ServerConnector(server,
    sslFactory, httpsFactory);
httpsConnector.setPort(httpsPort);
server.addConnector(httpsConnector);

I too found it rather surprising that this poorly documented step was necessary.

Community
  • 1
  • 1
Trevor Robinson
  • 15,694
  • 5
  • 73
  • 72