Hi,
I need to contact HTTPS servers through a proxy. I've managed to get this to work by having the http-request function issue an HTTP CONNECT commmand in order to tunnel SSL through the proxy: the patch is below (against 0.11.5). On the downside, it only works for Lispworks.
Cheers, Dave
--- a/request.lisp +++ b/request.lisp @@ -416,7 +416,8 @@ LispWorks 5.0 or higher." (t (setq content (alist-to-url-encoded-string parameters external-format-out) content-type "application/x-www-form-urlencoded"))))) - (let (http-stream must-close done) + (let ((proxying-https? (and proxy (eq :https (puri:uri-scheme uri)))) + http-stream raw-http-stream must-close done) (unwind-protect (progn (let ((host (or (and proxy (first proxy)) @@ -424,8 +425,8 @@ LispWorks 5.0 or higher." (port (cond (proxy (second proxy)) ((uri-port uri)) (t (default-port uri)))) - (use-ssl (or force-ssl - (eq (uri-scheme uri) :https)))) + (use-ssl (and (not proxying-https?) + (or force-ssl (eq (uri-scheme uri) :https))))) #+(and :lispworks5.0 :mswindows (not :lw-does-not-have-write-timeout)) (when use-ssl @@ -445,6 +446,7 @@ LispWorks 5.0 or higher." #-:lispworks (usocket:socket-stream (usocket:socket-connect host port :element-type 'octet)))) + (setq raw-http-stream http-stream) (when (and use-ssl ;; don't attach SSL to existing streams (not stream)) @@ -473,6 +475,24 @@ LispWorks 5.0 or higher." (format http-stream "~?~C~C" fmt args #\Return #\Linefeed)) (write-header (name value-fmt &rest value-args) (write-http-line "~A: ~?" name value-fmt value-args))) + (when proxying-https? + ;; Setup a tunnel through the proxy server to the + ;; final destination. + (write-http-line "CONNECT ~A:~A HTTP/1.1" (puri:uri-host uri) + (or (puri:uri-port uri) 443)) + (write-http-line "Host: ~A:~A" (puri:uri-host uri) + (or (puri:uri-port uri) 443)) + (write-http-line "") + (force-output http-stream) + ;; Check we get a 200 response before proceeding. + (let ((line (read-status-line http-stream *header-stream*))) + (unless (eq (second line) 200) + (error "Unable to establish HTTPS tunnel through proxy."))) + ;; Got a connection. We have to read a blank line, + ;; turn on SSL, and then we can transmit. + (read-line* http-stream) + #+:lispworks + (comm:attach-ssl raw-http-stream :ssl-side :client)) (when (and (not parameters-used-p) parameters) (setf (uri-query uri)