Correctly shutting down a websocket handler
by Robin Anil
When a client disconnects, I see that onClose is not being fired. The only
way this seems to be firing if client sents a close frame.
Is there any way to detect disconnection and immediately close all the
opened resources.
Robin
Robin Anil | Software Engineer
1 year, 3 months
Better logging for predicates
by Brad Wood
I've been using Tuckey Rewrites for a long time and one of my favorite
things about it is the very rich amount of debug and trace logging
information it has. There's not another rewrite engine out there I've seen
that makes it this easy to debug what's happening. The trace level logging
gives you a full blow-by-blow of each rule that's processed, what the input
was, and what the result of each condition was.
As much as I love Undertow's predicates and handlers, the logging is, well,
abysmal :) I'd like to do some work to improve what gets sent to the
request_logger for debugging the predicates and handlers that fire for a
request as part of the PredicatesHandler. My high-level approach is as
follows:
- Override the toString() method in each of the built-in predicates and
handlers to create a basic text representation of them that isn't too far
from the predicate language.
- Add logging at key points in the PredicatesHandler that captures each
predicate as it is evaluated as well as the result of that predicate and
the next handler to be invoked.
- I'd probably say a single debug log entry for every matched predicate
for basic high-level debugging of predicates that had some sort of effect
on the request.
- And then a trace log entry with all the juicy details of each
predicate whether it was matched or not for debugging why predicates aren't
working correctly
So again, I'm offering to work on this and contribute it to Undertow as a
pull, but I'd like some feedback on my idea and a general sanity check on
whether I'm wasting my time here. Well, honestly, I'll probably do the
work regardless because the user's of my Undertow-powered tool will need
it, but I'd like to know if these improvements would be welcomed into the
core.
Thanks!
~Brad
*Developer Advocate*
*Ortus Solutions, Corp *
E-mail: brad(a)coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com
4 years, 4 months
Building Undertow
by Brad Wood
I'm trying to build Undertow using the (sparse) instructions here and
having a heck of a time.
https://undertow.io/undertow-docs/undertow-docs-2.1.0/index.html
cd undertow && mvn install
So firstly, I'm not super familiar with Maven (not a full time java dev)
but when I skip the tests, the build fails. Here is the note in the docs,
which is confusing for a couple reasons:
If you attempt to build with -Dmaven.test.skip=true for your initial build
> the build will fail, as the core test jar will not be built and the Servlet
> module has a test scoped dependency on this jar. Either use -DskipTests,
> or just let the tests run the first time.
>
- First it says the build will fail if the tests are skipped, but then
seems to imply that I can work around this by setting some system
properties.
- What is the difference between the *maven.test.skip* property and the
*skiptests* property? Do I need both of them?
If I try to run the build like so (Using Maven 3.6.3 and java 11) using a
fresh clone of the Undertow repo with the "master" branch checked out:
mvn install -Dmaven.test.skip=true -DskipTests
I get this build failure still:
[ERROR] Failed to execute goal on project undertow-servlet: Could not
> resolve dependencies for project
> io.undertow:undertow-servlet:jar:2.1.4.Final-SN
> APSHOT: Could not find artifact
> io.undertow:undertow-core:jar:tests:2.1.4.Final-SNAPSHOT -> [Help 1]
>
So, I'm not sure what to do there. The docs state that setting those JVM
args is an alternative to running the tests but it doesn't work.
Now, the first thing I tried was actually just to let the tests run, but
this proved to be even more troublesome than skipping the tests! I get
tons of test failures and other errors and the behavior differs whether I'm
using Java 8 or Java 11 (fun!) and the tests usually just hang and won't
complete.
When I run the build (with tests) on Java 1.8.0_161 they hang on this test
and never finish.
[INFO] Running io.undertow.server.handlers.ReceiverTestCase
When I run the build (with tests) on Java 11.0.6, I get the following
errors:
[ERROR]
> testSpnegoSuccess(io.undertow.server.security.SpnegoDigestAuthenticationTestCase)
> Time elapsed: 0.01 s <<< FAILURE!
> java.lang.AssertionError: Expected header not found.
>
> [ERROR]
> testSpnegoSuccess(io.undertow.server.security.SpnegoBasicAuthenticationTestCase)
> Time elapsed: 0 s <<< FAILURE!
> java.lang.AssertionError: Expected header not found.
>
> [ERROR]
> testSpnegoSuccess(io.undertow.server.security.SpnegoAuthenticationTestCase)
> Time elapsed: 0 s <<< FAILURE!
> java.lang.AssertionError: expected:<401> but was:<403>
>
> [ERROR]
> testNonDefaultFileSystem(io.undertow.server.handlers.file.PathResourceManagerTestCase)
> Time elapsed: 0.042 s <<< FAILURE!
> java.lang.AssertionError: expected:</dir/resource.txt> but
> was:</dir/./resource.txt>
>
> [ERROR]
> testRegexPattern(io.undertow.server.handlers.SameSiteCookieHandlerTestCase)
> Time elapsed: 0.027 s <<< ERROR!
> javax.net.ssl.SSLException: Connection reset
>
And then it hangs on the same test case that Java 8 hangs on
(io.undertow.server.handlers.ReceiverTestCase)
What does it take to get a local build of Undertow working? If it matters,
I'm trying to build on a Windows 7 machine.
Thanks!
~Brad
*Developer Advocate*
*Ortus Solutions, Corp *
E-mail: brad(a)coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com
4 years, 5 months
transferFrom writes more than requested
by Nate
With the code below, the expected result and what I see on Windows 10 is:
position: 10, count: 20
result: 20
On Debian 10 I see:
position: 10, count: 20
result: 16364
I believe transferFrom should never return more than the count passed to
it, so this seems like a bug? I'm happy to give more information if needed.
Note the Undertow buffer size is 16364. Also, on Debian it really did write
16364 bytes to the output channel.
Cheers,
-Nate
int position = 10;
int count = 20;
StreamSinkChannel output = exchange.getResponseChannel();
FileChannel input = new RandomAccessFile(file, "r").getChannel();
while (count > 0) {
long result;
while (true) {
System.out.println("position: " + position + ", count: " + count);
result = output.transferFrom(input, position, count);
System.out.println("result: " + result); // expected: <= 20
if (result!= 0L) break;
try {
output.awaitWritable();
} catch (InterruptedIOException ignored) {
}
}
count -= result;
position += result;
}
4 years, 5 months
output buffering
by Nate
I have a request where I need to return a ~100MB file. I want to:
1) do this efficiently, and
2) limit concurrent downloads by IP (ie reject a request if concurrent
downloads by that IP == x).
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't know when the transfer
completes so I can't track concurrent downloads.
Next I tried getResponseChannel, eg:
StreamSinkChannel output = exchange.getResponseChannel();
try (var input = new FileInputStream(file)) {
Channels.transferBlocking(output, input.getChannel(), position, count);
}
Digging through the code it doesn't seem to be buffering, but it still
completes immediately. For example, I download the file at 10 bytes/sec:
curl --limit-rate 10 --output file https://example.com/my/file
How can transferBlocking finish right away when this slow transfer will
take ages? What is buffering the 100MB?
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.
Thanks for your help!
-Nate
4 years, 6 months
pass MDC to worker thread
by Мартынов Илья
Hello,
I've created a handler to fill MDC from incoming request header.
public class CorrelationHandler implements HttpHandler
{
private HttpHandler next;
public CorrelationHandler(HttpHandler next) {
this.next = next;
}
@Override
public void handleRequest(HttpServerExchange e) throws Exception {
String corr = e.getRequestHeaders().getFirst("IDP-CORR-ID");
MDC.put("corr", corr);
next.handleRequest(e);
}
}
But most of my processing is done in worker thread and mdc is not passed
threre. How to pass it?
4 years, 6 months