orthecreedence / cl-async

Asynchronous IO library for Common Lisp.
MIT License
273 stars 40 forks source link

https connection with cl-async #146

Open fiddlerwoaroof opened 7 years ago

fiddlerwoaroof commented 7 years ago

I have issues connecting to certain SSL servers using cl-async, the code is here: http://paste.lisp.org/display/343066

Basically, this doesn't work, I don't get any output from the read callback.

(as-ssl:tcp-ssl-connect #1="api.ipify.org" 443
                        (lambda (a r)
                          a
                          (format t "~&GOT: ~s~%"
                                  (babel:octets-to-string r :encoding :iso-8859-1)))
                        :data (babel:string-to-octets
                               (format nil "GET / HTTP/1.1~c~%Host: ~a~0@*~c~%~0@*~c~%"
                                       #\return #1#)))

However, using cl+ssl directly does work:

(defun test-https-client (host &optional (port 443))
  (let* ((socket (usocket:socket-stream
                  (usocket:socket-connect host port
                                          :element-type '(unsigned-byte 8))))
         (https
          (flexi-streams:make-flexi-stream
            (cl+ssl:make-ssl-client-stream
             socket
             :hostname host
             :unwrap-stream-p t)
            :external-format :utf-8)))
    (unwind-protect (progn
                      (format https "GET / HTTP/1.0~c~%Host: ~a~0@*~c~%~0@*~c~%"
                              #\return host)
                      (force-output https)
                      (loop :for line = (read-line-crlf https nil)
                         :while line :do
                         (format t "HTTPS> ~a~%" line)))
      (close https))))
(test-https-client "api.ipify.org")
fiddlerwoaroof commented 7 years ago

I should mention that, the cl-async code does work with other SSL sites, such as en.wikipedia.org

fiddlerwoaroof commented 7 years ago

It looks to me like this has to do with SNI being setup correctly, I ran across this while trying to debug https://github.com/orthecreedence/carrier/issues/16

fiddlerwoaroof commented 7 years ago

I came up with a fix, although it's a hack, if I add the following lines just before https://github.com/orthecreedence/cl-async/blob/master/src/ssl/tcp.lisp#L337 , it works:

(cffi:with-foreign-string (host-f host)
  (cl+ssl::ssl-set-tlsext-host-name ssl host-f))
mtstickney commented 7 years ago

The attached patch adds the necessary definitions to make SNI work (use ssl-set-tlsext-host-name in place of the cl+ssl function in the previous comment). I haven't added anything to tcp-ssl-connect-new, because I wasn't sure if it needed a new option or extra checking (e.g. I'm not sure it's ok to set an IP address as an SNI host). Hopefully the patch just saves a little time and manual-reading.

fiddlerwoaroof commented 6 years ago

I think this one might be finished too?

vaartis commented 5 years ago

This still happens with some websites. While the OP site does work, e.g. https://safebooru.org (and most other sites that use the same old version of that engine) does not.