jetty.project icon indicating copy to clipboard operation
jetty.project copied to clipboard

Fixes #8979 - Jetty 12 - HttpClientTransport network "modes".

Open sbordet opened this issue 1 year ago • 10 comments

  • Introduced oej.io.TransportProtocol as the abstraction for the low-level transport of high-level protocols. Now protocols such as HTTP/1.1 or HTTP/2 can be transported over QUIC, Unix-Domain, memory, and possibly over other low-level custom protocols too.
  • Introduced oej.client.Request.transportProtocol(TransportProtocol) to specify TransportProtocol for each request.
  • Introduced TransportProtocol to [HTTP2Client|HTTP3Client].connect(...) methods.
  • Introduced [Client|Server]QuicConfiguration so that it can be used in other Connectors such as MemoryConnector.
  • Introduced oej.server.MemoryConnector and EndPoint.Pipe for memory communication between peers, along with a MemoryTransportProtocol.
  • Introduced QuicTransportProtocol as a wrapper for other TransportProtocols, so that QUIC can now also be transported over memory.

sbordet avatar Feb 02 '24 09:02 sbordet

@sbordet Are there any instructions how to build this locally for testing? Local Maven build fails with the same errors than the CI.

marchof avatar Feb 06 '24 14:02 marchof

@marchof build locally with mvn clean install -DskipTests.

The CI failure is due to javadocs, I'm fixing it right now.

sbordet avatar Feb 06 '24 14:02 sbordet

@sbordet Thanks for this effort! Finally I got a super simple prototype running with a naive TransportProtocoland EndPoint implementation. I have to admit that my brain can hardly handle the abstractions used in these interfaces. But in the end I only needed to implement these methods (probably missing several corner cases):

  • TransportProtocol.connect()
  • EndPoint.fillInterested()
  • EndPoint.fill()
  • Endpoint.write()

marchof avatar Feb 06 '24 17:02 marchof

@marchof you should not be needing to implement a new TransportProtocol and EndPoint.

If you explain your use case in more details, perhaps we can help you save some unnecessary work.

sbordet avatar Feb 06 '24 17:02 sbordet

@sbordet Let me try to explain my use case: A proxy server which proxies incoming HTTPS requests over SSH tunnels to HTTP servers. The SSH server managing the tunnels itself is implemented in Java with Apache Mina.

So if implemented in Jetty I see the following flow:

  • A Jetty server accepts HTTPS requests and handles it with a ProxyServlet.
  • The ProxyServlet uses a HttpClient with a custom transport
  • The custom transport delegates to the Apache Mina API for ssh tunnels, which is basically writing/receiving byte[] chunks

marchof avatar Feb 06 '24 17:02 marchof

@marchof let me try to write a test case similar to your use case. I'll ping you when done.

sbordet avatar Feb 07 '24 14:02 sbordet

@marchof I need more information.

Are you using SSH port forwarding?

If so, then this is what I think it happens:

  • Mina sets up port forwarding; now you have localhost:1234 on your proxy server that forwards to the remote server.
  • A request arrives to the Servlet
  • You use HttpClient to send a request to localhost:1234 with the Servlet request information and you're done.

Does Mina allow you to bypass the connection to localhost:1234? Can you give Mina just a ByteBuffer, as if you have written it to localhost:1234 using a socket, therefore bypassing the whole network stack?

sbordet avatar Feb 07 '24 17:02 sbordet

@sbordet Yes, I'm using SSH port forwarding but without using sockets on the server side. This avoids the network stack and allows me to separate the forwards of different users. The forwarding between http hosts and ssh sockets is pure virtual and happens in memory. Therefore I cannot use a HTTP client which connects to a (local) TCP port.

Apache Mina supports this, you can basically implement your own forwarding endpoints. The use something similar to ByteBuffer called org.apache.sshd.common.util.buffer.Buffer, but in the end it's just passing around byte[]instances.

marchof avatar Feb 07 '24 21:02 marchof

@marchof thanks, we'll write a test case for this scenario.

sbordet avatar Feb 07 '24 21:02 sbordet

@marchof see CustomTransportProtocolTest in this PR. Should be almost identical to your use case.

sbordet avatar Feb 08 '24 16:02 sbordet