`GET /api/personer/47120999865 HTTP/2` > Host: ...
# http4k
c
GET /api/personer/47120999865 HTTP/2
Host: localhost:8443
User-Agent: curl/7.64.1
Accept: /
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)! * TLSv1.2 (IN), TLS alert, close notify (256): * Empty reply from server * Connection #0 to host localhost left intact curl: (52) Empty reply from server * Closing connection 0
s
Does your server have any restriction on http vs https? The TLS alert looks suspicious there.
c
I am using a custom Jetty server. I require a certificate. If I look on the logs on the server side it looks like the request passes the validation and the server send a 200 response back
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem CApath: none * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Request CERT (13): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Certificate (11): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS handshake, CERT verify (15): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 * ALPN, server accepted to use h2 * Server certificate: * subject: C=NO; O=BITS AS; CN=BITS AS TEST; serialNumber=916960190 * start date: Dec 20 075439 2019 GMT * expire date: Dec 20 225900 2022 GMT * issuer: C=NO; O=Buypass AS-983163327; CN=Buypass Class 3 Test4 CA 3 * SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x7fdfb480d600)
GET /api/personer/47120999865 HTTP/2
Host: localhost:8443
User-Agent: curl/7.64.1
Accept: /
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)! * TLSv1.2 (IN), TLS alert, close notify (256): * Empty reply from server * Connection #0 to host localhost left intact curl: (52) Empty reply from se
here is the whole request
everything looks identical if i compare with the result i get if I run the app from InteliJ, until “TLSv1.2 (IN), TLS alert, close notify (256):”
the last 3 lines are the ones that are different.
s
And you can curl the server if it runs directly from IntelliJ?
c
yes and get a 200 response.
s
Hmm what I’d check is any difference in the JVM options in both scenarios. If I had to bet at this stage I’d say it has to do with how the server ssl cert is being loaded/configured
c
ok, I will have a look
thanks for the tips.Is it ok if i ask again on this thread?
s
And are you sure you’re always using “https” in the request?
Sure, ask away and I’ll answer if I’m around
c
Yep, same request both times
s
If you’re able to produce an example (just a hello world server in a public git repo) we can try and help too
c
And just used the code that is here
i use http2 and not http
Copy code
http2(port,"src/main/resources/certificates/bits.jks", "pass"))
Like this.
And is still does not work.
This is the only code in the handler
Copy code
httpResponse = Response(Status.OK)
httpResponse
s
Does it work for http2 without https?
c
one sec.
Copy code
fun http2(http2Port: Int, keystorePath: String, keystorePassword: String): ConnectorBuilder =
    { server: Server ->
        ServerConnector(server,
            SslConnectionFactory(
                SslContextFactory.Server().apply {
                    keyStorePath = keystorePath
                    setKeyStorePassword(keystorePassword)
                    cipherComparator = COMPARATOR
                    provider = "Conscrypt"
                },
                "alpn"),
            ALPNServerConnectionFactory().apply {
                defaultProtocol = "h2"
            },
            HTTP2ServerConnectionFactory(HttpConfiguration().apply {
                sendServerVersion = false
                secureScheme = "https"
                securePort = http2Port
                addCustomizer(SecureRequestCustomizer())
            })).apply { port = http2Port }
    }
is it enough to set the secureScheme = “http”
?
s
Hmmm I’m not sure. I’ll try and reproduce it locally, but most likely will only get back to you later
c
ok, thank you so much.
I also updated all the libraries. Is there a working example of http2 using https that i could have a look on?
that can be build and run via maven.
s
Not that I’m aware of...
c
Any tips on how i can get then a https custom jetty implementation to work? Is this something that should work?
I am a bit stuck and not sure how to continue or even if it should work or not.
s
I've played with the code you provided and the problem seems to be neither http2 or ssl, is seems to be the
ALPNServerConnectionFactory
. This is enough to make it fail (even on IntelliJ for me):
Copy code
fun http2(http2Port: Int): ConnectorBuilder =
    { server: Server ->
        ServerConnector(server,
            ALPNServerConnectionFactory().apply {
                defaultProtocol = "h2"
            }
        ).apply { port = http2Port }
    }
d
There is a note in the jetty maven about ALPN:
Copy code
"org.mortbay.jetty.alpn:alpn-boot:8.1.12.v20180117" // this version depends on your version of JDK!
This was originally built against Java 8 - no idea if the switch to 11 has had an effect
c
Ok, I am confused so does this mean that this is not meant to work with Java 11?
s
Also, http2 works on its own if you try:
Copy code
fun http2(http2Port: Int): ConnectorBuilder =
    { server: Server ->
        ServerConnector(server,
            HTTP2ServerConnectionFactory(HttpConfiguration().apply {
                sendServerVersion = false
            })
        ).apply { port = http2Port }
    }
And the hitting it via
curl --http2-prior-knowledge -v <http://localhost:8081>
d
Ok, I am confused
This is standard with http2! 😂
c
😂
d
Have you tried Undertow? I seem to remember that http2 was easier to configure on that..
c
No, will have a look.
d
What is your deployment setup @Cosmin Victor Celea?
(we have definitely deployed Undertow in a secure configuration to prod in the past - I can't actually remember what prompted us adding the Jetty code TBH)
c
Since the project is still in a early phases, I was the only one working on it. So until now, I just ran everything locally from InteliJ. So i was planning to work now on a deployment script, when i saw that it crashes when i try to build it and run it via maven.
So i should try to move things to Undertow?
d
do you need to terminate SSL at the app server?
Normally I'd favour offloading that to something sitting in front.. (and sidestepping the entire problem! 😂 )
s
Yeah. Nowadays is unusual to have https managed directly at the service process.
c
So the idea is that we only allow requests that come from a certificate that is signed by a specific issuer and and we use the information from the certificate in our logic.
It was a requirement for the project.
s
You mean maTLS?
d
The way I've seen this done in the past is to fingerprint the cert at an outside proxy service (which specifically does just and only that). Then just forward that to the inner service.
c
Seems like I have some thinking to do.
👍 1