내용:
HTTPS/SSL Tunneling and Proxy Server
November 14, 2008 – 10:29 pm by coachwei | Category WebDev |HTTPS Tunneling, also called HTTPS Proxy, SSL proxy, or SSL tunneling, refers to sending HTTPS content via a proxy server. This is a very common usage scenario over the web.
Unfortunately, I have not found any Java server that supports this yet. Tomcat chokes up quickly if you tunnel HTTPS messages (tried both Tomcat 5.x and 6.x). Other Java servers don’t even come close. Jetty is the furthest and closest to supporting it. Greg Wilkins even wrote two examples showing Jetty’s proxy support (ProxyServlet and AsyncProxyServlet, though both of them only partially work when I tried to run them on on Jetty 6.x and Jetty 7.x).
The main problem for all these servers is that they do not support HTTP Connect. We all know HTTP GET, and HTTP POST, and all servers support these common HTTP methods beautifully, except for HTTP Connect.
The problem with HTTP connect are two folds:
- Most servers simply fail at even parsing an HTTP connect request, except for Jetty, let alone anything else.
- Jetty can parse HTTP connect request (semi) successfully, but it does not seem to enable any further processing of HTTP connect request (such as reading from the request’s inputstream);
Problem No.1 is that HTTP connect request looks very different from other HTTP requests, and most servers do not take HTTP connect requests into consideration. When the browser is initiating an HTTPS connection via a proxy server, the browser will send the following request to a proxy server:
CONNECT some.server.com:443 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17
Proxy-Connection: keep-alive
Host: some.server.com
In contrast, a typical HTTP request would look like:
GET /a/b/c.html HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17
Host: some.server.com
Problem No.2 is that HTTP Connect requires a two-step handling. After sending out this request header, the browser will “halt” the request and wait to hear back from the network before sending out any content;
The proxy server should respond to the above request by trying to initiating a connection with the remote server (some.server.com at port 443 in the above example). If a connection is established successfully, the proxy server should respond to the browser by sending back:
HTTP/1.1 200 Connection Established
Then proxy server should wait. On the other side, once the browser receives “200″ status from the server, the browser will now send the actual HTTPS content to the request connection. Once the proxy server receives the content, it should send such content to the remote server. The remote server will then respond and such response needs to be “copied” back to the browser, which would appear as part of the “HTTP/1.1 200 Connection Established” message shown earlier.
I hope I am missing something here - if you know Jetty server or any other server that works well for HTTPS tunneling, please comment below!
Some useful links for more information on this subject:
- Tunneling SSL Through a WWW Proxy, http://muffin.doit.org/docs/rfc/tunneling_ssl.html
- Implement HTTPS tunneling with JSSE, http://www.javaworld.com/javaworld/javatips/jw-javatip111.html?page=1
- Jetty bug tracker “Allow interception of CONNECT method to support proxy impls”, http://jira.codehaus.org/browse/JETTY-625?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
- Jetty ProxyServlet, http://www.mortbay.org/jetty/jetty-6/apidocs/org/mortbay/servlet/ProxyServlet.html