use of org.eclipse.jetty.server.HttpOutput in project jetty.project by eclipse.
the class BufferedResponseHandler method handle.
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
ServletContext context = baseRequest.getServletContext();
String path = context == null ? baseRequest.getRequestURI() : URIUtil.addPaths(baseRequest.getServletPath(), baseRequest.getPathInfo());
LOG.debug("{} handle {} in {}", this, baseRequest, context);
HttpOutput out = baseRequest.getResponse().getHttpOutput();
// Are we already being gzipped?
HttpOutput.Interceptor interceptor = out.getInterceptor();
while (interceptor != null) {
if (interceptor instanceof BufferedInterceptor) {
LOG.debug("{} already intercepting {}", this, request);
_handler.handle(target, baseRequest, request, response);
return;
}
interceptor = interceptor.getNextInterceptor();
}
// If not a supported method - no Vary because no matter what client, this URI is always excluded
if (!_methods.test(baseRequest.getMethod())) {
LOG.debug("{} excluded by method {}", this, request);
_handler.handle(target, baseRequest, request, response);
return;
}
// Use pathInfo because this is be
if (!isPathBufferable(path)) {
LOG.debug("{} excluded by path {}", this, request);
_handler.handle(target, baseRequest, request, response);
return;
}
// If the mime type is known from the path, then apply mime type filtering
String mimeType = context == null ? MimeTypes.getDefaultMimeByExtension(path) : context.getMimeType(path);
if (mimeType != null) {
mimeType = MimeTypes.getContentTypeWithoutCharset(mimeType);
if (!isMimeTypeBufferable(mimeType)) {
LOG.debug("{} excluded by path suffix mime type {}", this, request);
// handle normally without setting vary header
_handler.handle(target, baseRequest, request, response);
return;
}
}
// install interceptor and handle
out.setInterceptor(new BufferedInterceptor(baseRequest.getHttpChannel(), out.getInterceptor()));
if (_handler != null)
_handler.handle(target, baseRequest, request, response);
}
use of org.eclipse.jetty.server.HttpOutput in project jetty.project by eclipse.
the class DataRateLimitedServlet method doGet.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Get the path of the static resource to serve.
String info = request.getPathInfo();
// We don't handle directories
if (info.endsWith("/")) {
response.sendError(503, "directories not supported");
return;
}
// Set the mime type of the response
String content_type = getServletContext().getMimeType(info);
response.setContentType(content_type == null ? "application/x-data" : content_type);
// Look for a matching file path
String path = request.getPathTranslated();
// If we have a file path and this is a jetty response, we can use the JettyStream impl
ServletOutputStream out = response.getOutputStream();
if (path != null && out instanceof HttpOutput) {
// If the file exists
File file = new File(path);
if (file.exists() && file.canRead()) {
// Set the content length
response.setContentLengthLong(file.length());
// Look for a file mapped buffer in the cache
ByteBuffer mapped = cache.get(path);
// Handle cache miss
if (mapped == null) {
// TODO implement LRU cache flush
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
ByteBuffer buf = raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length());
mapped = cache.putIfAbsent(path, buf);
if (mapped == null)
mapped = buf;
}
}
// start async request handling
AsyncContext async = request.startAsync();
// Set a JettyStream as the write listener to write the content asynchronously.
out.setWriteListener(new JettyDataStream(mapped, async, out));
return;
}
}
// Jetty API was not used, so lets try the standards approach
// Can we find the content as an input stream
InputStream content = getServletContext().getResourceAsStream(info);
if (content == null) {
response.sendError(404);
return;
}
// Set a StandardStream as he write listener to write the content asynchronously
out.setWriteListener(new StandardDataStream(content, request.startAsync(), out));
}
use of org.eclipse.jetty.server.HttpOutput in project jetty.project by eclipse.
the class StreamResetTest method testAsyncWriteAfterStreamReceivingReset.
@Test
public void testAsyncWriteAfterStreamReceivingReset() throws Exception {
final CountDownLatch resetLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1);
start(new HttpServlet() {
@Override
protected void doGet(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
Charset charset = StandardCharsets.UTF_8;
final ByteBuffer data = ByteBuffer.wrap("AFTER RESET".getBytes(charset));
response.setStatus(200);
response.setContentType("text/plain;charset=" + charset.name());
response.setContentLength(data.remaining());
response.flushBuffer();
try {
// Wait for the reset to happen.
Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
// Wait for the reset to arrive to the server and be processed.
Thread.sleep(1000);
} catch (InterruptedException x) {
throw new InterruptedIOException();
}
// Write some content asynchronously after the stream has been reset.
final AsyncContext context = request.startAsync();
new Thread() {
@Override
public void run() {
try {
// Wait for the request thread to exit
// doGet() so this is really asynchronous.
Thread.sleep(1000);
HttpOutput output = (HttpOutput) response.getOutputStream();
output.sendContent(data, new Callback() {
@Override
public void failed(Throwable x) {
context.complete();
dataLatch.countDown();
}
});
} catch (Throwable x) {
x.printStackTrace();
}
}
}.start();
}
});
Session client = newClient(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", new HttpFields());
HeadersFrame frame = new HeadersFrame(request, null, true);
client.newStream(frame, new FuturePromise<>(), new Stream.Listener.Adapter() {
@Override
public void onHeaders(Stream stream, HeadersFrame frame) {
stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
resetLatch.countDown();
}
});
Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
}
use of org.eclipse.jetty.server.HttpOutput in project jetty.project by eclipse.
the class GzipHandler method handle.
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
ServletContext context = baseRequest.getServletContext();
String path = context == null ? baseRequest.getRequestURI() : URIUtil.addPaths(baseRequest.getServletPath(), baseRequest.getPathInfo());
LOG.debug("{} handle {} in {}", this, baseRequest, context);
if (!_dispatchers.contains(baseRequest.getDispatcherType())) {
LOG.debug("{} excluded by dispatcherType {}", this, baseRequest.getDispatcherType());
_handler.handle(target, baseRequest, request, response);
return;
}
// Handle request inflation
if (_inflateBufferSize > 0) {
HttpField ce = baseRequest.getHttpFields().getField(HttpHeader.CONTENT_ENCODING);
if (ce != null && "gzip".equalsIgnoreCase(ce.getValue())) {
// TODO should check ce.contains and then remove just the gzip encoding
baseRequest.getHttpFields().remove(HttpHeader.CONTENT_ENCODING);
baseRequest.getHttpFields().add(new HttpField("X-Content-Encoding", ce.getValue()));
baseRequest.getHttpInput().addInterceptor(new GzipHttpInputInterceptor(baseRequest.getHttpChannel().getByteBufferPool(), _inflateBufferSize));
}
}
// Are we already being gzipped?
HttpOutput out = baseRequest.getResponse().getHttpOutput();
HttpOutput.Interceptor interceptor = out.getInterceptor();
while (interceptor != null) {
if (interceptor instanceof GzipHttpOutputInterceptor) {
LOG.debug("{} already intercepting {}", this, request);
_handler.handle(target, baseRequest, request, response);
return;
}
interceptor = interceptor.getNextInterceptor();
}
// If not a supported method - no Vary because no matter what client, this URI is always excluded
if (!_methods.test(baseRequest.getMethod())) {
LOG.debug("{} excluded by method {}", this, request);
_handler.handle(target, baseRequest, request, response);
return;
}
// Use pathInfo because this is be
if (!isPathGzipable(path)) {
LOG.debug("{} excluded by path {}", this, request);
_handler.handle(target, baseRequest, request, response);
return;
}
// Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded
String mimeType = context == null ? MimeTypes.getDefaultMimeByExtension(path) : context.getMimeType(path);
if (mimeType != null) {
mimeType = MimeTypes.getContentTypeWithoutCharset(mimeType);
if (!isMimeTypeGzipable(mimeType)) {
LOG.debug("{} excluded by path suffix mime type {}", this, request);
// handle normally without setting vary header
_handler.handle(target, baseRequest, request, response);
return;
}
}
if (_checkGzExists && context != null) {
String realpath = request.getServletContext().getRealPath(path);
if (realpath != null) {
File gz = new File(realpath + ".gz");
if (gz.exists()) {
LOG.debug("{} gzip exists {}", this, request);
// allow default servlet to handle
_handler.handle(target, baseRequest, request, response);
return;
}
}
}
// Special handling for etags
String etag = baseRequest.getHttpFields().get(HttpHeader.IF_NONE_MATCH);
if (etag != null) {
int i = etag.indexOf(CompressedContentFormat.GZIP._etagQuote);
if (i > 0) {
baseRequest.setAttribute("o.e.j.s.h.gzip.GzipHandler.etag", etag);
while (i >= 0) {
etag = etag.substring(0, i) + etag.substring(i + CompressedContentFormat.GZIP._etag.length());
i = etag.indexOf(CompressedContentFormat.GZIP._etagQuote, i);
}
baseRequest.getHttpFields().put(new HttpField(HttpHeader.IF_NONE_MATCH, etag));
}
}
HttpOutput.Interceptor orig_interceptor = out.getInterceptor();
try {
// install interceptor and handle
out.setInterceptor(new GzipHttpOutputInterceptor(this, getVaryField(), baseRequest.getHttpChannel(), orig_interceptor, isSyncFlush()));
if (_handler != null)
_handler.handle(target, baseRequest, request, response);
} finally {
// reset interceptor if request not handled
if (!baseRequest.isHandled() && !baseRequest.isAsyncStarted())
out.setInterceptor(orig_interceptor);
}
}
use of org.eclipse.jetty.server.HttpOutput in project jetty.project by eclipse.
the class TestServletBufferTypeLengthWrite method doGet.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getServletPath();
byte[] dataBytes = loadContentFileBytes(fileName);
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);
response.setContentLength(dataBytes.length);
((HttpOutput) out).write(ByteBuffer.wrap(dataBytes).asReadOnlyBuffer());
}
Aggregations