[tech] tls user_canceled issue with Java server + Go client

Alan gemini at bunburya.eu
Sun Apr 18 15:41:13 BST 2021


Hi Gary,

That solved it, thanks! A simple fix but you're right, I couldn't find 
anything about it. Good to know there is a solution.

Thanks,

Alan

On 18/04/2021 01:04, Gary Johnson wrote:
> Alan<gemini at bunburya.eu>  writes:
>
>> When using the Amfora browser, I was unable to view "20" responses,
>> getting instead the following error: "/Issuing creating page: remote
>> error: tls: user//canceled/". Unusually, every other response is
>> displayed fine.
> Hi Alan,
>
> I'm the author of Space-Age, a Gemini server written in Clojure.
>
> =>https://gitlab.com/lambdatronic/space-age/
>
> The tls_user_canceled issue you are running into is coming from the Java
> side. It also mystified me last year when I was writing my server since
> I was constantly getting that error in elpher (the Emacs Gemini client)
> whenever I tried to browse pages from my capsule.
>
> You have to force your SSLSocket to send the tls_close_notify alert to
> the client before closing the socket. This is exceptionally poorly
> documented in the JSSE Reference Guide, but I eventually figured out the
> solution through trial and error.
>
> All you need to do is to make sure you call socket.shutdownOutput()
> immediately before calling socket.close().
>
> Here's my function for writing a Gemini response back to the client for reference:
>
> ```
> (defn- write-socket! [^SSLSocket socket {:keys [status meta body]}]
>    (doto (io/writer socket)
>      (.write (str status " " meta "\r\n"))
>      (.flush))
>    (when body
>      (with-open [in-stream (io/input-stream (if (string? body)
>                                               (.getBytes ^String body)
>                                               body))]
>        (let [out-stream (io/output-stream socket)]
>          (.transferTo in-stream out-stream)
>          (.flush out-stream))))
>    (.shutdownOutput socket))
> ```
>
> This is called from another function that then calls socket.close() to
> terminate the connection.
>
> Here is my full Gemini server implementation for further reference:
>
> =>https://gitlab.com/lambdatronic/space-age/-/blob/master/src/space_age/server.clj
>
> Happy hacking!
>    Gary
>


More information about the Gemini mailing list