Search in sources :

Example 1 with HttpOutput

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);
}
Also used : ServletContext(javax.servlet.ServletContext) Interceptor(org.eclipse.jetty.server.HttpOutput.Interceptor) HttpOutput(org.eclipse.jetty.server.HttpOutput)

Example 2 with HttpOutput

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));
}
Also used : RandomAccessFile(java.io.RandomAccessFile) ServletOutputStream(javax.servlet.ServletOutputStream) InputStream(java.io.InputStream) AsyncContext(javax.servlet.AsyncContext) HttpOutput(org.eclipse.jetty.server.HttpOutput) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) ByteBuffer(java.nio.ByteBuffer)

Example 3 with HttpOutput

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));
}
Also used : InterruptedIOException(java.io.InterruptedIOException) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) WriteListener(javax.servlet.WriteListener) AsyncContext(javax.servlet.AsyncContext) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) Stream(org.eclipse.jetty.http2.api.Stream) ServletOutputStream(javax.servlet.ServletOutputStream) IStream(org.eclipse.jetty.http2.IStream) HttpServlet(javax.servlet.http.HttpServlet) HttpServletResponse(javax.servlet.http.HttpServletResponse) Charset(java.nio.charset.Charset) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) HttpOutput(org.eclipse.jetty.server.HttpOutput) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) Callback(org.eclipse.jetty.util.Callback) FutureCallback(org.eclipse.jetty.util.FutureCallback) ResetFrame(org.eclipse.jetty.http2.frames.ResetFrame) Session(org.eclipse.jetty.http2.api.Session) ISession(org.eclipse.jetty.http2.ISession) Test(org.junit.Test)

Example 4 with HttpOutput

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);
    }
}
Also used : HttpField(org.eclipse.jetty.http.HttpField) ServletContext(javax.servlet.ServletContext) HttpOutput(org.eclipse.jetty.server.HttpOutput) File(java.io.File)

Example 5 with HttpOutput

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());
}
Also used : ServletOutputStream(javax.servlet.ServletOutputStream) HttpOutput(org.eclipse.jetty.server.HttpOutput)

Aggregations

HttpOutput (org.eclipse.jetty.server.HttpOutput)7 ServletOutputStream (javax.servlet.ServletOutputStream)3 File (java.io.File)2 ByteBuffer (java.nio.ByteBuffer)2 AsyncContext (javax.servlet.AsyncContext)2 ServletContext (javax.servlet.ServletContext)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 InterruptedIOException (java.io.InterruptedIOException)1 RandomAccessFile (java.io.RandomAccessFile)1 Charset (java.nio.charset.Charset)1 Path (java.nio.file.Path)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ServletException (javax.servlet.ServletException)1 WriteListener (javax.servlet.WriteListener)1 HttpServlet (javax.servlet.http.HttpServlet)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 HttpField (org.eclipse.jetty.http.HttpField)1 HttpFields (org.eclipse.jetty.http.HttpFields)1