Reputation: 1033
I have an application that is deployed on Glassfish and listens to port 8181 for HTTPS traffic (currently). The problem is that when deployed, customers rarely create a valid certificate for the server. This means that the HTTPS fails certificate checks.
There is some type of content in our application that we'd like to fetch over HTTP, as it's static and the fact that fetching is not encrypted is not a problem.
The problem we DO have is that only port 8181 is available for the users (firewalls, etc., cannot be changed).
So, we need a way for Glassfish to listen to the incoming connection on port 8181 and identify what protocol is being attempted (https://myserver:8181
or http://myserver:8181
).
I've seen a solution for Tomcat: https://serverfault.com/questions/47876/handling-http-and-https-requests-using-a-single-port-with-nginx#comment-37501
Any ideas on how to do this with Glassfish? Can we implement a hook in there and hand off to either handler (HTTP or HTTPS) appropriately?
Upvotes: 2
Views: 1059
Reputation: 4440
I've looked at all answers over there and they tell almost the same: it is impossible because of the differences between HTTP and HTTPS. Even browsers use different default ports for handling HTTP/HTTPS.
Why this is happening: HTTP is basically text protocol, and browsers just sends HTTP (text) headers over TCP-IP. HTTPS isn't just SSL over HTTP. First of all browser performs "handshake", then it receives from server certificate, and all information from server to browser and vice versa is being encoded with symmetric keys negotiated during the handshake.
Because of 2 keys (public and private), which is used in asymmetric encryption, nobody (except who knows private key) can't sniff or change the information.
Experiment: try to do following: change https to http and explicitly add "443" in the end (something like http://google.com:443) You've got either "The connection was reset" or suggestion to store binary file (e.g. certificate).
Note: usually servers are set to reject such requests.
So even if you use the same connector to handle both HTTP and HHTPS connections, you are supposed to use different connection handlers (we faced with this when were implementing high-load server based on Netty).
And the only possibility to use HTTP and HTTPS on the same port is with using "magic recognizer", which would check either plain text has come or binary handshake. If we put that recognizer on the container's side (Glassfish protocol handler), it would have quite big performance overhead (checking each request whether it SSL or not!). If we put it on the proxy server's side (e.g. nginx or other non-blocking servers, such as Netty) performance wouldn't suffer too much, but anyway this doesn't guarantee 100% of success.
Note: that proxy server just recognizes, and after that it forwards request to 2 different ports!
As a conclusion: in general, it's possible, but from my point of view, the needed work doesn't worth the result.
EDIT: As @Bruno answered, there is present magic recognizer out of the box, but it is not officially supported by Glassfish.
Upvotes: 0
Reputation: 122599
What you're trying to do is called "port unification", and should be supported by Glassfish, as implemented in Grizzly.
Upvotes: 2