Async handler before SockJS handler breaks XhrTransport
SockJS XHR transport tries to register a body handler
(rc.request().bodyHandler(buff -> {})). This doesn't work when using an async
handler before the SockJS handler.
Fixes
package io.vertx.ext.web.handler.sockjs.impl;
+import static io.vertx.core.buffer.Buffer.buffer;
+
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
-import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.http.HttpVersion;
@@ -47,8 +48,6 @@ import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.sockjs.SockJSHandlerOptions;
import io.vertx.ext.web.handler.sockjs.SockJSSocket;
-import static io.vertx.core.buffer.Buffer.buffer;
-
/**
* @author <a href="http://tfox.org">Tim Fox</a>
*/
@@ -116,8 +115,21 @@ class XhrTransport extends BaseTransport {
}
private void handleSend(RoutingContext rc, SockJSSession session) {
- rc.request().bodyHandler(buff -> {
- String msgs = buff.toString();
+ Buffer body = rc.getBody();
+ if (body != null) {
+ handleSendMessage(rc, session, body);
+ } else if (rc.request().isEnded()) {
+ log.error("Request ended before SockJS handler could read the body. Do you have an asynchronous request "
+ + "handler before the SockJS handler? If so, add a BodyHandler before the SockJS handler "
+ + "(see the docs).");
+ rc.fail(500);
+ } else {
+ rc.request().bodyHandler(buff -> handleSendMessage(rc, session, buff));
+ }
+ }
+
+ private void handleSendMessage(RoutingContext rc, SockJSSession session, Buffer body) {
+ String msgs = body.toString();
if (msgs.equals("")) {
rc.response().setStatusCode(500);
rc.response().end("Payload expected.");
@@ -134,7 +146,6 @@ class XhrTransport extends BaseTransport {
rc.response().end();
}
if (log.isTraceEnabled()) log.trace("XHR send processed ok");
- });
}
private abstract class BaseXhrListener extends BaseListener {
