use of javax.servlet.AsyncListener in project jetty.project by eclipse.
the class HttpChannelState method startAsync.
public void startAsync(AsyncContextEvent event) {
final List<AsyncListener> lastAsyncListeners;
try (Locker.Lock lock = _locker.lock()) {
if (LOG.isDebugEnabled())
LOG.debug("startAsync {}", toStringLocked());
if (_state != State.DISPATCHED || _async != Async.NOT_ASYNC)
throw new IllegalStateException(this.getStatusStringLocked());
_async = Async.STARTED;
_event = event;
lastAsyncListeners = _asyncListeners;
_asyncListeners = null;
}
if (lastAsyncListeners != null) {
Runnable callback = new Runnable() {
@Override
public void run() {
for (AsyncListener listener : lastAsyncListeners) {
try {
listener.onStartAsync(event);
} catch (Throwable e) {
// TODO Async Dispatch Error
LOG.warn(e);
}
}
}
@Override
public String toString() {
return "startAsync";
}
};
runInContext(event, callback);
}
}
use of javax.servlet.AsyncListener in project jetty.project by eclipse.
the class AsyncContextListenersTest method testListenerClearedOnSecondRequest.
@SuppressWarnings("Duplicates")
@Test
public void testListenerClearedOnSecondRequest() throws Exception {
final AtomicReference<CountDownLatch> completes = new AtomicReference<>(new CountDownLatch(1));
String path = "/path";
prepare(path, new HttpServlet() {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync(request, response);
asyncContext.addListener(new AsyncListener() {
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
}
@Override
public void onComplete(AsyncEvent event) throws IOException {
completes.get().countDown();
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
}
@Override
public void onError(AsyncEvent event) throws IOException {
}
});
asyncContext.complete();
}
});
try (Socket socket = new Socket("localhost", _connector.getLocalPort())) {
OutputStream output = socket.getOutputStream();
String request = "" + "GET " + path + " HTTP/1.1\r\n" + "Host: localhost\r\n" + "\r\n";
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
HttpTester.Input input = HttpTester.from(socket.getInputStream());
HttpTester.Response response = HttpTester.parseResponse(input);
Assert.assertEquals(200, response.getStatus());
completes.get().await(10, TimeUnit.SECONDS);
// Send a second request
completes.set(new CountDownLatch(1));
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
response = HttpTester.parseResponse(input);
Assert.assertEquals(200, response.getStatus());
completes.get().await(10, TimeUnit.SECONDS);
}
}
use of javax.servlet.AsyncListener in project jetty.project by eclipse.
the class AsyncContextListenersTest method testAsyncDispatchAsyncCompletePreservesListener.
@Test
public void testAsyncDispatchAsyncCompletePreservesListener() throws Exception {
final AtomicReference<CountDownLatch> completes = new AtomicReference<>(new CountDownLatch(1));
final String path = "/path";
prepare(path + "/*", new HttpServlet() {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestURI = request.getRequestURI();
if (requestURI.endsWith("/one")) {
AsyncContext asyncContext = request.startAsync(request, response);
asyncContext.addListener(new AsyncListener() {
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
event.getAsyncContext().addListener(this);
}
@Override
public void onComplete(AsyncEvent event) throws IOException {
completes.get().countDown();
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
}
@Override
public void onError(AsyncEvent event) throws IOException {
}
});
// This dispatch() will call startAsync() again which will
// clear the previous listeners (as per the specification)
// but add a new listener from onStartAsync().
asyncContext.dispatch(path + "/two");
} else if (requestURI.endsWith("/two")) {
AsyncContext asyncContext = request.startAsync(request, response);
asyncContext.complete();
}
}
});
try (Socket socket = new Socket("localhost", _connector.getLocalPort())) {
OutputStream output = socket.getOutputStream();
String request = "" + "GET " + path + "/one HTTP/1.1\r\n" + "Host: localhost\r\n" + "\r\n";
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
HttpTester.Input input = HttpTester.from(socket.getInputStream());
HttpTester.Response response = HttpTester.parseResponse(input);
Assert.assertEquals(200, response.getStatus());
completes.get().await(10, TimeUnit.SECONDS);
// Send a second request
completes.set(new CountDownLatch(1));
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
response = HttpTester.parseResponse(input);
Assert.assertEquals(200, response.getStatus());
completes.get().await(10, TimeUnit.SECONDS);
}
}
use of javax.servlet.AsyncListener in project jetty.project by eclipse.
the class ProxyServletTest method testProxyLongPoll.
@Test
public void testProxyLongPoll() throws Exception {
final long timeout = 1000;
startServer(new HttpServlet() {
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
if (!request.isAsyncStarted()) {
final AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(timeout);
asyncContext.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent event) throws IOException {
}
@Override
public void onTimeout(AsyncEvent event) throws IOException {
if (request.getHeader("Via") != null)
response.addHeader(PROXIED_HEADER, "true");
asyncContext.complete();
}
@Override
public void onError(AsyncEvent event) throws IOException {
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
}
});
}
}
});
startProxy();
startClient();
Response response = client.newRequest("localhost", serverConnector.getLocalPort()).timeout(2 * timeout, TimeUnit.MILLISECONDS).send();
Assert.assertEquals(200, response.getStatus());
Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
}
use of javax.servlet.AsyncListener in project Openfire by igniterealtime.
the class HttpSession method createConnection.
/**
* Creates a new connection on this session. If a response is currently available for this
* session the connection is responded to immediately, otherwise it is queued awaiting a
* response.
*
* @param rid the request id related to the connection.
* @param isSecure true if the connection was secured using HTTPS.
* @return the created {@link org.jivesoftware.openfire.http.HttpConnection} which represents
* the connection.
*
* @throws HttpConnectionClosedException if the connection was closed before a response could be
* delivered.
* @throws HttpBindException if the connection has violated a facet of the HTTP binding
* protocol.
*/
synchronized HttpConnection createConnection(long rid, boolean isSecure, boolean isPoll, AsyncContext context) throws HttpConnectionClosedException, HttpBindException, IOException {
final HttpConnection connection = new HttpConnection(rid, isSecure, sslCertificates, context);
connection.setSession(this);
context.setTimeout(getWait() * JiveConstants.SECOND);
context.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent asyncEvent) throws IOException {
Log.debug("complete event " + asyncEvent);
connectionQueue.remove(connection);
fireConnectionClosed(connection);
}
@Override
public void onTimeout(AsyncEvent asyncEvent) throws IOException {
Log.debug("timeout event " + asyncEvent);
try {
// If onTimeout does not result in a complete(), the container falls back to default behavior.
// This is why this body is to be delivered in a non-async fashion.
connection.deliverBody(createEmptyBody(false), false);
setLastResponseEmpty(true);
// This connection timed out we need to increment the request count
if (connection.getRequestId() != lastRequestID + 1) {
throw new IOException("Unexpected RID error.");
}
lastRequestID = connection.getRequestId();
} catch (HttpConnectionClosedException e) {
Log.warn("Unexpected exception while processing connection timeout.", e);
}
// Note that 'onComplete' will be invoked.
}
@Override
public void onError(AsyncEvent asyncEvent) throws IOException {
Log.debug("error event " + asyncEvent);
Log.warn("Unhandled AsyncListener error: " + asyncEvent.getThrowable());
connectionQueue.remove(connection);
fireConnectionClosed(connection);
}
@Override
public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
}
});
if (rid <= lastRequestID) {
Delivered deliverable = retrieveDeliverable(rid);
if (deliverable == null) {
Log.warn("Deliverable unavailable for " + rid);
throw new HttpBindException("Unexpected RID error.", BoshBindingError.itemNotFound);
}
connection.deliverBody(createDeliverable(deliverable.deliverables), true);
addConnection(connection, isPoll);
return connection;
} else if (rid > (lastRequestID + maxRequests)) {
Log.warn("Request " + rid + " > " + (lastRequestID + maxRequests) + ", ending session.");
throw new HttpBindException("Unexpected RID error.", BoshBindingError.itemNotFound);
}
addConnection(connection, isPoll);
return connection;
}
Aggregations