<div dir="ltr"><div style="font-size:small" class="gmail_default"></div><div class="gmail_default" style="font-size:small">I have a request where I need to return a ~100MB file. I want to:</div><div class="gmail_default" style="font-size:small">1) do this efficiently, and</div><div class="gmail_default" style="font-size:small">2) limit concurrent downloads by IP (ie reject a request if concurrent downloads by that IP == x).<br></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">I dispatch to a worker thread, then read from the file using FileInputStream and write to exchange.getOutputStream(). However, I noticed that this writes all the bytes immediately.  Digging into why, 
exchange.getOutputStream() uses UndertowOutputStream which appears to buffer all the data given to it. 
Not only does this seem inefficient to copy 100MB for every request, it means I don&#39;t know when the transfer completes so I can&#39;t track concurrent downloads.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">Next I tried 
getResponseChannel, eg:</div><div class="gmail_default" style="font-size:small"></div><div class="gmail_default" style="font-size:small">StreamSinkChannel output = exchange.getResponseChannel();<br>try (var input = new FileInputStream(file)) {<br>            Channels.transferBlocking(output, input.getChannel(), position, count);<br>}<br></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">Digging through the code it doesn&#39;t seem to be buffering, but it still completes immediately. For example, I download the file at 10 bytes/sec:</div><div class="gmail_default" style="font-size:small">curl --limit-rate 10 --output file <a href="https://example.com/my/file">https://example.com/my/file</a></div><div class="gmail_default" style="font-size:small"></div><div class="gmail_default" style="font-size:small"></div><div class="gmail_default" style="font-size:small"></div><div class="gmail_default" style="font-size:small">
How can 
transferBlocking

finish right away when this slow transfer will take ages? What is buffering the 100MB?</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">How can my worker thread write response data one buffer at a time, blocking as needed for the client to receive the data, until the client has all the data? This would allow me to know when the transfer is complete so I can track concurrent downloads by IP.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">Thanks for your help!</div><div class="gmail_default" style="font-size:small">-Nate<br></div><div class="gmail_default" style="font-size:small"><br></div></div>