use of javax.servlet.AsyncContext in project jetty.project by eclipse.
the class QoSFilter method doFilter.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
boolean accepted = false;
try {
Boolean suspended = (Boolean) request.getAttribute(_suspended);
if (suspended == null) {
accepted = _passes.tryAcquire(getWaitMs(), TimeUnit.MILLISECONDS);
if (accepted) {
request.setAttribute(_suspended, Boolean.FALSE);
if (LOG.isDebugEnabled())
LOG.debug("Accepted {}", request);
} else {
request.setAttribute(_suspended, Boolean.TRUE);
int priority = getPriority(request);
AsyncContext asyncContext = request.startAsync();
long suspendMs = getSuspendMs();
if (suspendMs > 0)
asyncContext.setTimeout(suspendMs);
asyncContext.addListener(_listeners[priority]);
_queues[priority].add(asyncContext);
if (LOG.isDebugEnabled())
LOG.debug("Suspended {}", request);
return;
}
} else {
if (suspended) {
request.setAttribute(_suspended, Boolean.FALSE);
Boolean resumed = (Boolean) request.getAttribute(_resumed);
if (resumed == Boolean.TRUE) {
_passes.acquire();
accepted = true;
if (LOG.isDebugEnabled())
LOG.debug("Resumed {}", request);
} else {
// Timeout! try 1 more time.
accepted = _passes.tryAcquire(getWaitMs(), TimeUnit.MILLISECONDS);
if (LOG.isDebugEnabled())
LOG.debug("Timeout {}", request);
}
} else {
// Pass through resume of previously accepted request.
_passes.acquire();
accepted = true;
if (LOG.isDebugEnabled())
LOG.debug("Passthrough {}", request);
}
}
if (accepted) {
chain.doFilter(request, response);
} else {
if (LOG.isDebugEnabled())
LOG.debug("Rejected {}", request);
((HttpServletResponse) response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
} catch (InterruptedException e) {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
} finally {
if (accepted) {
for (int p = _queues.length - 1; p >= 0; --p) {
AsyncContext asyncContext = _queues[p].poll();
if (asyncContext != null) {
ServletRequest candidate = asyncContext.getRequest();
Boolean suspended = (Boolean) candidate.getAttribute(_suspended);
if (suspended == Boolean.TRUE) {
candidate.setAttribute(_resumed, Boolean.TRUE);
asyncContext.dispatch();
break;
}
}
}
_passes.release();
}
}
}
use of javax.servlet.AsyncContext in project jetty.project by eclipse.
the class AsyncScheduledDispatchWrite method doGet.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Boolean suspended = (Boolean) request.getAttribute("SUSPENDED");
if (suspended == null || !suspended) {
request.setAttribute("SUSPENDED", Boolean.TRUE);
AsyncContext ctx;
if (originalReqResp) {
// Use Original Request & Response
ctx = request.startAsync();
} else {
// Pass Request & Response
ctx = request.startAsync(request, response);
}
ctx.setTimeout(0);
scheduler.schedule(new DispatchBack(ctx), 500, TimeUnit.MILLISECONDS);
} else {
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
response.setContentLength(dataBytes.length);
ServletOutputStream out = response.getOutputStream();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag", "W/etag-" + fileName);
out.write(dataBytes);
}
}
use of javax.servlet.AsyncContext in project jetty.project by eclipse.
the class AsyncTimeoutDispatchWrite method doGet.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext ctx = (AsyncContext) request.getAttribute(AsyncContext.class.getName());
if (ctx == null) {
// First pass through
if (originalReqResp) {
// Use Original Request & Response
ctx = request.startAsync();
} else {
// Pass Request & Response
ctx = request.startAsync(request, response);
}
ctx.addListener(this);
ctx.setTimeout(200);
request.setAttribute(AsyncContext.class.getName(), ctx);
} else {
// second pass through, as result of timeout -> dispatch
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
response.setContentLength(dataBytes.length);
ServletOutputStream out = response.getOutputStream();
if (fileName.endsWith("txt"))
response.setContentType("text/plain");
else if (fileName.endsWith("mp3"))
response.setContentType("audio/mpeg");
response.setHeader("ETag", "W/etag-" + fileName);
out.write(dataBytes);
// no need to call AsyncContext.complete() from here
// in fact, it will cause an IllegalStateException if we do
// ctx.complete();
}
}
use of javax.servlet.AsyncContext in project jetty.project by eclipse.
the class AsyncIOServletTest method testAsyncReadThrows.
private void testAsyncReadThrows(Throwable throwable) throws Exception {
CountDownLatch latch = new CountDownLatch(1);
start(new HttpServlet() {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
assertScope();
AsyncContext asyncContext = request.startAsync(request, response);
request.getInputStream().setReadListener(new ReadListener() {
@Override
public void onDataAvailable() throws IOException {
assertScope();
if (throwable instanceof RuntimeException)
throw (RuntimeException) throwable;
if (throwable instanceof Error)
throw (Error) throwable;
throw new IOException(throwable);
}
@Override
public void onAllDataRead() throws IOException {
assertScope();
}
@Override
public void onError(Throwable t) {
assertScope();
Assert.assertThat("onError type", t, instanceOf(throwable.getClass()));
Assert.assertThat("onError message", t.getMessage(), is(throwable.getMessage()));
latch.countDown();
response.setStatus(500);
asyncContext.complete();
}
});
}
});
ContentResponse response = client.newRequest(newURI()).method(HttpMethod.POST).path(servletPath).content(new StringContentProvider("0123456789")).timeout(5, TimeUnit.SECONDS).send();
assertTrue(latch.await(5, TimeUnit.SECONDS));
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, response.getStatus());
}
use of javax.servlet.AsyncContext in project jetty.project by eclipse.
the class AsyncIOServletTest method testAsyncWriteLessThanContentLengthFlushed.
@Test
public void testAsyncWriteLessThanContentLengthFlushed() throws Exception {
CountDownLatch complete = new CountDownLatch(1);
start(new HttpServlet() {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentLength(10);
AsyncContext async = request.startAsync();
ServletOutputStream out = response.getOutputStream();
AtomicInteger state = new AtomicInteger(0);
out.setWriteListener(new WriteListener() {
@Override
public void onWritePossible() throws IOException {
while (true) {
if (!out.isReady())
return;
switch(state.get()) {
case 0:
state.incrementAndGet();
WriteListener listener = this;
new Thread(() -> {
try {
Thread.sleep(50);
listener.onWritePossible();
} catch (Exception e) {
}
}).start();
return;
case 1:
state.incrementAndGet();
out.flush();
break;
case 2:
state.incrementAndGet();
out.write("12345".getBytes());
break;
case 3:
async.complete();
complete.countDown();
return;
}
}
}
@Override
public void onError(Throwable t) {
}
});
}
});
AtomicBoolean failed = new AtomicBoolean(false);
CountDownLatch clientLatch = new CountDownLatch(3);
client.newRequest(newURI()).path(servletPath).onResponseHeaders(response -> {
if (response.getStatus() == HttpStatus.OK_200)
clientLatch.countDown();
}).onResponseContent(new Response.ContentListener() {
@Override
public void onContent(Response response, ByteBuffer content) {
// System.err.println("Content: "+BufferUtil.toDetailString(content));
}
}).onResponseFailure(new Response.FailureListener() {
@Override
public void onFailure(Response response, Throwable failure) {
clientLatch.countDown();
}
}).send(result -> {
failed.set(result.isFailed());
clientLatch.countDown();
clientLatch.countDown();
clientLatch.countDown();
});
assertTrue(complete.await(10, TimeUnit.SECONDS));
assertTrue(clientLatch.await(10, TimeUnit.SECONDS));
assertTrue(failed.get());
}
Aggregations