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, 2 months
Re: [undertow-dev] Proxying WebSockets
by Hicks, Matt
Stuart, is there anything else you need from me to look into this further?
On Mon, May 23, 2016 at 11:29 AM Hicks, Matt <matt(a)matthicks.com> wrote:
Yes, I do. You can run the example code and it runs against hyperscala.org . If you go to http://hyperscala.org/ example/realtime/chat.html or http://localhost:8080/example/ realtime/chat.html you can test the Chat example that uses WebSockets. If you connect directly it
works fine, if you connect via the Proxy it doesn't.
On Mon, May 23, 2016, 11:17 AM Stuart Douglas < sdouglas(a)redhat.com > wrote:
Do you have a reproduce I can run (complete with JS etc so I can see exactly
what is going on)?
Stuart
On Mon, May 23, 2016 at 3:24 PM, Hicks, Matt < matt(a)matthicks.com > wrote:
Stuart, I created a ticket with all the information I know to provide:
[UNDERTOW-714] Broken WebSocket Proxying Support - JBoss Issue Tracker I have been attempting to write a test proxy server to proxy explicitly to
another server. issues.jboss.org
I'm not positive which side is closing the connection, but looking at the
JavaScript console it's showing the connection is being closed almost
immediately after any message is sent from the browser to the server.
On Mon, May 23, 2016 at 2:48 AM Stuart Douglas < sdouglas(a)redhat.com > wrote:
When you say it does not work exactly what behaviour are you seeing? Does the
connection get established? If it gets established and then fails which side
drops the connection?
We have extensive tests for this in the test suite, as web socket tests are run
through the proxy server, we need more info to see why it is not working for
you.
Stuart
On Fri, May 20, 2016 at 1:18 AM, Hicks, Matt < matt(a)matthicks.com > wrote:
I did some additional testing with 2.0.0.Alpha1 and got the exact same results.
If there is some way to accomplish proper proxying with Undertow I'm not seeing
it.
Should I file a bug report?
______________________________ _________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/ mailman/listinfo/undertow-dev
8 years, 5 months
Websocket messages : should we start a new Thread to handle them?
by electrotype
Hi,
I'm quite new to Undertow, so please let me know if this is not the right place to ask those
questions! Maybe Stack Overflow is preferred?
Undertow is the default server of a new framework I'm the main developer, Spincast :
https://www.spincast.org . Everything works very well, but Spincast is still in beta, we haven't
really do performance testing yet. I'm not totally sure if we use Undertow properly... But, for now,
everything works well.
By the way, we use "Undertow 1.2.12.Final" because Spincast is Java 7 compatible. Also, we do not
use the Servlet API.
We're currently trying to use Undertow for /Websocket//s/ in addition to HTTP. Our first tests work
very well here too. But here's my question:
Spincast is a /synchronous/ Java framework. If I understand correctly, the first thing to do, when
Undertow is used in such synchronous environments, is to call, in the main handler:
----------------------------------------------
/if(exchange.isInIoThread()) {//
// exchange.dispatch(this);//
// return;//
//}
/----------------------------------------------
This is what we do.
But what about Websocket messages handling?
Our Webssocket server code currently looks something like this:
----------------------------------------------
/WebSocketChannel channel = ...//
//
//channel.getReceiveSetter().set(new AbstractReceiveListener() {//
//
// @Override//
// protected void onFullTextMessage(final WebSocketChannel channel,//
// BufferedTextMessage bufferedTextMessage) throws IOException {//
//
// String message = bufferedTextMessage.getData();//
//
// applicationHandlingOfTheMessage(message);//
// }//
//
// //...//
//}//
//channel.resumeReceives();/
----------------------------------------------
Here, is it correct to say that the /applicationHandlingOfTheMessage(message)/ method shouldn't
block? This code is executed in an NIO Thread, right? So we /have/ to start a new Thread to call
/applicationHandlingOfTheMessage(message)/, is that correct? We have no idea how the application
will actually handle the message.
Pretty much all the code examples I found of handling such Websocket messages with Undertow are
simple echos, where blocking code is not an issue.
Thanks in advance!
Julien
8 years, 5 months
Undertow statistics
by Sven Kubiak
I saw that Undetow can collect statistics. I have set the appropriate Untertow option (ENABLE_STATISTICS). However, how do I access the raw statistic data programmatically??
Cheers,
Sven
8 years, 5 months
Proxying WebSockets
by Hicks, Matt
I did some additional testing with 2.0.0.Alpha1 and got the exact same results.
If there is some way to accomplish proper proxying with Undertow I'm not seeing
it.
Should I file a bug report?
8 years, 6 months
Proxy Server with WebSocket Support?
by Hicks, Matt
How difficult would it be to write a proxy server that proxies to a web server
that takes advantage of WebSockets? I've been looking through the documentation
and though there is easy access to proxying and direct support for WebSockets, I
can't see a clear path to integrate the two to create a proxy server that
proxies to a web server that utilizes WebSockets.
Any examples, tutorials, links, sample code, etc. is greatly appreciated.
Thanks,
Matt Hicks
8 years, 6 months
receiveFullBytes callbacks never called
by Oliver Dain
I've got a case where I can call receiveFullBytes but neither the success
nor the error handler is ever called. My code looks like this:
public static CompletableFuture<ByteSource>
getCompleteBody(HttpServerExchange exchange) {
log.debug("In getCompleteBody.");
CompletableFuture<ByteSource> finalResult = new CompletableFuture<>();
try {
log.debug("Calling receiveFullBytes.");
exchange.getRequestReceiver().receiveFullBytes(
// Success case.
(HttpServerExchange excng, byte[] bytes) -> {
log.debug("getFullBytes completed with success.");
finalResult.complete(ByteSource.wrap(bytes));
},
// Error case
(HttpServerExchange exchng, IOException t) -> {
log.warn("getFullBytes completed with an error:", t);
finalResult.completeExceptionally(t);
}
);
} catch (Throwable t) {
log.warn("receiveFullBytes threw an exception:", t);
finalResult.completeExceptionally(t);
}
return finalResult;
}
I've got a unit test that opens a socket, starts sending data, and
then, intentionally throws an exception. The test then ensures that
the CompletableFuture above completes with an exception. Except, it
never completes.. the test just hangs forever. You can see that the
"log.debug("Calling receiveFullBytes.")" line does get called and that
the neither of the log lines in either callback is ever called. The
full test looks like this:
@Test
public void getCompleteBodyCompletesWithExceptionOnBodyFailure()
throws Exception {
AtomicBoolean futureRedeemedWithError = new AtomicBoolean(false);
CountDownLatch waitForInputToFail = new CountDownLatch(1);
HttpHandler handler = new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
log.info("Handler called.");
exchange.dispatch();
log.info("Calling getCompleteBody");
UndertowUtils.getCompleteBody(exchange).exceptionally((Throwable t) -> {
log.debug("As expected, received an exception:", t);
futureRedeemedWithError.set(true);
waitForInputToFail.countDown();
return null;
});
}
};
UndertowTestUtils.RunningServer server =
UndertowTestUtils.startUndertowOnFreePort(handler);
// A Body() implementation that will return a few chunks of data but the fail
Body failingRequestBody = new Body() {
private AtomicInteger readCalls = new AtomicInteger(0);
@Override
public long getContentLength() {
return 1000;
}
@Override
public long read(ByteBuffer buffer) throws IOException {
if (readCalls.getAndIncrement() < 2) {
byte[] toSend = "some data".getBytes(Charsets.UTF_8);
buffer.put(toSend);
return toSend.length;
} else {
throw new RuntimeException("Fake error on sending data.");
}
}
@Override
public void close() throws IOException {
}
};
// A body generator using the above, busted Body.
BodyGenerator failingBodyGenerator = new BodyGenerator() {
@Override
public Body createBody() throws IOException {
return failingRequestBody;
}
};
// This will start sending data so our handler gets invoked but it
will then fail partway through.
SimpleAsyncHttpClient client = new SimpleAsyncHttpClient.Builder()
.setUrl(String.format("http://localhost:%s", server.getPort()))
.build();
client.post(failingBodyGenerator);
// Test hangs here forever
waitForInputToFail.await();
assertThat(futureRedeemedWithError.get()).isTrue();
}
This feels like a bug. I'd expect the contract of "receiveFullBytes" to be
that either the success or failure handler gets called exactly once. Is
this a bug? If not, what am I doing wrong?
Thanks,
Oliver
--
CTO, Analytic Spot
44 West Broadway #222
Eugene, OR 97401
analyticspot.com • 425-296-6556
www.linkedin.com/in/oliverdain
8 years, 6 months
java.lang.IllegalStateException: UT000124: renegotiation timed out
by Brian Call
Hi Guys,
First off, I’m trying to figure out whether or not I’m dealing with a bug or a user error on this one, so my apologies for spamming everyone. There is scant information pertaining to this error anywhere that I found as google only returned a single result, and that was to the messages class containing the message code.
I’m seeing this exception on TLS negotiation using client certs and I just can’t figure out what’s being renegotiated or why there would be a timeout. It’s all happening in milliseconds so I’m very confused, especially since it seems to happen intermittently and under varying circumstances. I’ve examined the source code for the wildly-10 version undertow that I’m using and I just can’t figure it out. Any hints in the right direction would be greatly appreciated.
Blessings,
Brian
Here’s the stack trace:
2016-05-11 20:27:51,766 ERROR [io.undertow.request] (default task-7) UT005023: Exception handling request to /ppi/whoami: java.lang.IllegalStateException: UT000124: renegotiation timed out
at io.undertow.server.ConnectionSSLSessionInfo.renegotiateNoRequest(ConnectionSSLSessionInfo.java:175)
at io.undertow.server.ConnectionSSLSessionInfo.renegotiate(ConnectionSSLSessionInfo.java:89)
at io.undertow.security.impl.ClientCertAuthenticationMechanism.getPeerCertificates(ClientCertAuthenticationMechanism.java:125)
at io.undertow.security.impl.ClientCertAuthenticationMechanism.authenticate(ClientCertAuthenticationMechanism.java:92)
at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:233)
at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:250)
at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:219)
at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:121)
at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:96)
at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:89)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
8 years, 6 months
create session in handler
by Harris, Carl
In a handler that is part of my servlet extension, I want to be able to create a session using SessionManager.
Looks like I could get the relevant manager from the HttpExchange using the attachment key declared in the SessionManager interface. I'm not quite sure what to pass as the SessionConfig argument to createSession. It looks like there are two implementations of SessionConfig; one that uses the JSESSIONID cookie, and another that uses the SSL session.
The SslSessionConfig takes a fallback config, and so it looks like this might be the right thing to do:
SessionConfig sessionConfig = new SslSessionConfig(new SessionCookieConfig(), sessionManager);
Just looking for confirmation or correction.
Thanks,
carl
8 years, 6 months