This is what our org.eclipse.jetty.proxy.AsyncProxyServlet already does.

https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/AsyncProxyServlet.java

Why write your own?


Joakim Erdfelt / [email protected]

On Tue, Sep 26, 2017 at 4:47 PM, Steven Schlansker <
[email protected]> wrote:

> Hi jetty-users,
>
> Still working on my http proxy :)
> Now I'm trying to make sure I've got the content proxying working correctly
> using both asynchronous servlet as well as NIO nonblocking writing.
>
> Because both the server and client are pushing notifications at me, I
> believe
> I need to implement some sort of transfer queue.  I was hoping that I'd
> end up
> in a push-pull situation but ServletOutputStream calls you via a
> WriteListener
> and Jetty-Client calls you via a Response.ContentListener.
>
> Unfortunately, this leaves me in a position where I don't know how to get
> flow
> control working.  The client pushes data at me and I don't have a way to
> push back.
>
> My current pesudocoded approach:
>
> Deque<Runnable> writes;
> volatile boolean complete = false;
>
> asyncCtx = httpResponse.startAsync();
> out = (HttpOutput) httpResponse.getOutputStream();
>
> writeListener = new WriteListener() {
>     synchronized void onWritePossible() { // avoid re-entrance with
> 'synchronized'
>         while(out.isReady()) {
>             pending = writes.removeFirst();
>             if (pending != null) {
>                 pending.run();
>             } else if (complete && writes.isEmpty()) {
>                 asyncCtx.complete();
>             } else {
>                 return;
>             }
>         }
>     }
> };
>
> out.setWriteListener(writeListener);
>
> proxyClientRequest.send(new Response.ContentListener() {
>     void onContent(ByteBuffer buf, Callback complete) {
>         writes.push(() -> {
>             out.write(buf);
>             complete.succeeded();
>         };
>         writeListener.onWritePossible();  // See if we can write it
> immediately
>     }
>
>     void onComplete() {
>         complete = true;
>         writeListener.onWritePossible();
>     }
> });
>
> This has the nice property where I don't copy buffers, just keep them in a
> queue
> of pending writes -- but I worry that in the case of a slow reader, Jetty
> Client
> will continue onContent-pushing buffers at me until I run out of memory.
>
> I could instead use the OutputStreamContentProvider and just read from it
> in the
> WriteListener, which might fix the flow control, but that seems likely to
> involve
> a number of byte[] copies that I was hoping to avoid.
>
> What's the right approach to wire up Jetty server to Jetty client with
> full NIO + Async
> content proxying, without introducing an intermediate transfer buffer that
> might grow
> without bound?  Am I on the right path or am I missing something?  Thanks
> for any guidance!
>
>
> _______________________________________________
> jetty-users mailing list
> [email protected]
> To change your delivery options, retrieve your password, or unsubscribe
> from this list, visit
> https://dev.eclipse.org/mailman/listinfo/jetty-users
>
_______________________________________________
jetty-users mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to