Java Code Examples for io.undertow.util.ETagUtils#handleIfNoneMatch()

The following examples show how to use io.undertow.util.ETagUtils#handleIfNoneMatch() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DirectoryUtils.java    From quarkus-http with Apache License 2.0 5 votes vote down vote up
/**
 * Serve static resource for the directory listing
 *
 * @param exchange The exchange
 * @return true if resources were served
 */
public static boolean sendRequestedBlobs(HttpServerExchange exchange) {
    ByteBuf buffer = null;
    String type = null;
    String etag = null;
    String quotedEtag = null;
    if ("css".equals(exchange.getQueryString())) {
        buffer = Blobs.FILE_CSS_BUFFER.duplicate();
        type = "text/css";
        etag = Blobs.FILE_CSS_ETAG;
        quotedEtag = Blobs.FILE_CSS_ETAG_QUOTED;
    } else if ("js".equals(exchange.getQueryString())) {
        buffer = Blobs.FILE_JS_BUFFER.duplicate();
        type = "application/javascript";
        etag = Blobs.FILE_JS_ETAG;
        quotedEtag = Blobs.FILE_JS_ETAG_QUOTED;
    }

    if (buffer != null) {

        if (!ETagUtils.handleIfNoneMatch(exchange, new ETag(false, etag), false)) {
            exchange.setStatusCode(StatusCodes.NOT_MODIFIED);
            return true;
        }

        exchange.setResponseHeader(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(buffer.readableBytes()));
        exchange.setResponseHeader(HttpHeaderNames.CONTENT_TYPE, type);
        exchange.setResponseHeader(HttpHeaderNames.ETAG, quotedEtag);
        if (HttpMethodNames.HEAD.equals(exchange.getRequestMethod())) {
            exchange.endExchange();
            return true;
        }
        exchange.writeAsync(buffer.duplicate(), true, IoCallback.END_EXCHANGE, null);

        return true;
    }

    return false;
}
 
Example 2
Source File: DirectoryUtils.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Serve static resource for the directory listing
 *
 * @param exchange The exchange
 * @return true if resources were served
 */
public static boolean sendRequestedBlobs(HttpServerExchange exchange) {
    ByteBuffer buffer = null;
    String type = null;
    String etag = null;
    String quotedEtag = null;
    if ("css".equals(exchange.getQueryString())) {
        buffer = Blobs.FILE_CSS_BUFFER.duplicate();
        type = "text/css";
        etag = Blobs.FILE_CSS_ETAG;
        quotedEtag = Blobs.FILE_CSS_ETAG_QUOTED;
    } else if ("js".equals(exchange.getQueryString())) {
        buffer = Blobs.FILE_JS_BUFFER.duplicate();
        type = "application/javascript";
        etag = Blobs.FILE_JS_ETAG;
        quotedEtag = Blobs.FILE_JS_ETAG_QUOTED;
    }

    if (buffer != null) {

        if(!ETagUtils.handleIfNoneMatch(exchange, new ETag(false, etag), false)) {
            exchange.setStatusCode(StatusCodes.NOT_MODIFIED);
            return true;
        }

        exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, String.valueOf(buffer.limit()));
        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, type);
        exchange.getResponseHeaders().put(Headers.ETAG, quotedEtag);
        if (Methods.HEAD.equals(exchange.getRequestMethod())) {
            exchange.endExchange();
            return true;
        }
        exchange.getResponseSender().send(buffer);

        return true;
    }

    return false;
}
 
Example 3
Source File: ClientSideCookieEventHandler.java    From divolte-collector with Apache License 2.0 5 votes vote down vote up
@Override
public void handleRequest(final HttpServerExchange exchange) {
    final InetSocketAddress sourceAddress = captureAndPersistSourceAddress(exchange);

    /*
     * Set up the headers that we always send as a response, irrespective of what type it
     * will be. Note that the client is responsible for ensuring that ensures that each request
     * is unique.
     * The cache-related headers are intended to prevent spurious reloads for an event.
     * (Being a GET request, agents are free to re-issue the request at will. We don't want this.)
     * As a last resort, we try to detect duplicates via the ETag header.
     */
    exchange.getResponseHeaders()
            .put(Headers.CONTENT_TYPE, "image/gif")
            .put(Headers.ETAG, SENTINEL_ETAG_VALUE)
            .put(Headers.CACHE_CONTROL, "private, no-cache, proxy-revalidate")
            .put(Headers.PRAGMA, "no-cache")
            .put(Headers.EXPIRES, "Fri, 14 Apr 1995 11:30:00 GMT");

    // If an ETag is present, this is a duplicate event.
    if (ETagUtils.handleIfNoneMatch(exchange, SENTINEL_ETAG, true)) {
        // Default status code what we want: 200 OK.
        // Sending the response before logging the event!
        exchange.getResponseSender().send(transparentImage.slice());

        try {
            logEvent(exchange);
        } catch (final IncompleteRequestException ire) {
            // improper request, could be anything
            logger.debug("Improper request received from {}.", Optional.ofNullable(exchange.getSourceAddress()).map(InetSocketAddress::getHostString).orElse("<UNKNOWN HOST>"));
        }
    } else {
        if (logger.isDebugEnabled()) {
            logger.debug("Ignoring duplicate event from {}: {}", sourceAddress, getFullUrl(exchange));
        }
        exchange.setStatusCode(StatusCodes.NOT_MODIFIED);
        exchange.endExchange();
    }
}
 
Example 4
Source File: DefaultServlet.java    From quarkus-http with Apache License 2.0 4 votes vote down vote up
private void serveFileBlocking(final HttpServletRequest req, final HttpServletResponse resp, final Resource resource, HttpServerExchange exchange) throws IOException {
    final ETag etag = resource.getETag();
    final Date lastModified = resource.getLastModified();
    if (req.getDispatcherType() != DispatcherType.INCLUDE) {
        if (!ETagUtils.handleIfMatch(req.getHeader(HttpHeaderNames.IF_MATCH), etag, false) ||
                !DateUtils.handleIfUnmodifiedSince(req.getHeader(HttpHeaderNames.IF_UNMODIFIED_SINCE), lastModified)) {
            resp.setStatus(StatusCodes.PRECONDITION_FAILED);
            return;
        }
        if (!ETagUtils.handleIfNoneMatch(req.getHeader(HttpHeaderNames.IF_NONE_MATCH), etag, true) ||
                !DateUtils.handleIfModifiedSince(req.getHeader(HttpHeaderNames.IF_MODIFIED_SINCE), lastModified)) {
            if (req.getMethod().equals(HttpMethodNames.GET) || req.getMethod().equals(HttpMethodNames.HEAD)) {
                resp.setStatus(StatusCodes.NOT_MODIFIED);
            } else {
                resp.setStatus(StatusCodes.PRECONDITION_FAILED);
            }
            return;
        }
    }

    //we are going to proceed. Set the appropriate headers
    if (resp.getContentType() == null) {
        if (!resource.isDirectory()) {
            final String contentType = deployment.getServletContext().getMimeType(resource.getName());
            if (contentType != null) {
                resp.setContentType(contentType);
            } else {
                resp.setContentType("application/octet-stream");
            }
        }
    }
    if (lastModified != null) {
        resp.setHeader(HttpHeaderNames.LAST_MODIFIED, resource.getLastModifiedString());
    }
    if (etag != null) {
        resp.setHeader(HttpHeaderNames.ETAG, etag.toString());
    }
    ByteRange.RangeResponseResult rangeResponse = null;
    long start = -1, end = -1;
    try {
        //only set the content length if we are using a stream
        //if we are using a writer who knows what the length will end up being
        //todo: if someone installs a filter this can cause problems
        //not sure how best to deal with this
        //we also can't deal with range requests if a writer is in use
        Long contentLength = resource.getContentLength();
        if (contentLength != null) {
            resp.getOutputStream();
            if (contentLength > Integer.MAX_VALUE) {
                resp.setContentLengthLong(contentLength);
            } else {
                resp.setContentLength(contentLength.intValue());
            }
            if (resource instanceof RangeAwareResource && ((RangeAwareResource) resource).isRangeSupported() && resource.getContentLength() != null) {
                resp.setHeader(HttpHeaderNames.ACCEPT_RANGES, "bytes");
                //TODO: figure out what to do with the content encoded resource manager
                final ByteRange range = ByteRange.parse(req.getHeader(HttpHeaderNames.RANGE));
                if (range != null) {
                    rangeResponse = range.getResponseResult(resource.getContentLength(), req.getHeader(HttpHeaderNames.IF_RANGE), resource.getLastModified(), resource.getETag() == null ? null : resource.getETag().getTag());
                    if (rangeResponse != null) {
                        start = rangeResponse.getStart();
                        end = rangeResponse.getEnd();
                        resp.setStatus(rangeResponse.getStatusCode());
                        resp.setHeader(HttpHeaderNames.CONTENT_RANGE, rangeResponse.getContentRange());
                        long length = rangeResponse.getContentLength();
                        if (length > Integer.MAX_VALUE) {
                            resp.setContentLengthLong(length);
                        } else {
                            resp.setContentLength((int) length);
                        }
                        if (rangeResponse.getStatusCode() == StatusCodes.REQUEST_RANGE_NOT_SATISFIABLE) {
                            return;
                        }
                    }
                }
            }
        }
    } catch (IllegalStateException e) {

    }
    final boolean include = req.getDispatcherType() == DispatcherType.INCLUDE;
    if (!req.getMethod().equals(HttpMethodNames.HEAD)) {
        if (rangeResponse == null) {
            resource.serveBlocking(exchange.getOutputStream(), exchange);
        } else {
            ((RangeAwareResource) resource).serveRangeBlocking(exchange.getOutputStream(), exchange, start, end);
        }
    }
}
 
Example 5
Source File: DefaultServlet.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
private void serveFileBlocking(final HttpServletRequest req, final HttpServletResponse resp, final Resource resource, HttpServerExchange exchange) throws IOException {
    final ETag etag = resource.getETag();
    final Date lastModified = resource.getLastModified();
    if(req.getDispatcherType() != DispatcherType.INCLUDE) {
        if (!ETagUtils.handleIfMatch(req.getHeader(Headers.IF_MATCH_STRING), etag, false) ||
                !DateUtils.handleIfUnmodifiedSince(req.getHeader(Headers.IF_UNMODIFIED_SINCE_STRING), lastModified)) {
            resp.setStatus(StatusCodes.PRECONDITION_FAILED);
            return;
        }
        if (!ETagUtils.handleIfNoneMatch(req.getHeader(Headers.IF_NONE_MATCH_STRING), etag, true) ||
                !DateUtils.handleIfModifiedSince(req.getHeader(Headers.IF_MODIFIED_SINCE_STRING), lastModified)) {
            if(req.getMethod().equals(Methods.GET_STRING) || req.getMethod().equals(Methods.HEAD_STRING)) {
                resp.setStatus(StatusCodes.NOT_MODIFIED);
            } else {
                resp.setStatus(StatusCodes.PRECONDITION_FAILED);
            }
            return;
        }
    }

    //we are going to proceed. Set the appropriate headers
    if(resp.getContentType() == null) {
        if(!resource.isDirectory()) {
            final String contentType = deployment.getServletContext().getMimeType(resource.getName());
            if (contentType != null) {
                resp.setContentType(contentType);
            } else {
                resp.setContentType("application/octet-stream");
            }
        }
    }
    if (lastModified != null) {
        resp.setHeader(Headers.LAST_MODIFIED_STRING, resource.getLastModifiedString());
    }
    if (etag != null) {
        resp.setHeader(Headers.ETAG_STRING, etag.toString());
    }
    ByteRange.RangeResponseResult rangeResponse = null;
    long start = -1, end = -1;
    try {
        //only set the content length if we are using a stream
        //if we are using a writer who knows what the length will end up being
        //todo: if someone installs a filter this can cause problems
        //not sure how best to deal with this
        //we also can't deal with range requests if a writer is in use
        Long contentLength = resource.getContentLength();
        if (contentLength != null) {
            resp.getOutputStream();
            if(contentLength > Integer.MAX_VALUE) {
                resp.setContentLengthLong(contentLength);
            } else {
                resp.setContentLength(contentLength.intValue());
            }
            if(resource instanceof RangeAwareResource && ((RangeAwareResource)resource).isRangeSupported() && resource.getContentLength() != null) {
                resp.setHeader(Headers.ACCEPT_RANGES_STRING, "bytes");
                //TODO: figure out what to do with the content encoded resource manager
                final ByteRange range = ByteRange.parse(req.getHeader(Headers.RANGE_STRING));
                if(range != null) {
                    rangeResponse = range.getResponseResult(resource.getContentLength(), req.getHeader(Headers.IF_RANGE_STRING), resource.getLastModified(), resource.getETag() == null ? null : resource.getETag().getTag());
                    if(rangeResponse != null){
                        start = rangeResponse.getStart();
                        end = rangeResponse.getEnd();
                        resp.setStatus(rangeResponse.getStatusCode());
                        resp.setHeader(Headers.CONTENT_RANGE_STRING, rangeResponse.getContentRange());
                        long length = rangeResponse.getContentLength();
                        if(length > Integer.MAX_VALUE) {
                            resp.setContentLengthLong(length);
                        } else {
                            resp.setContentLength((int) length);
                        }
                        if(rangeResponse.getStatusCode() == StatusCodes.REQUEST_RANGE_NOT_SATISFIABLE) {
                            return;
                        }
                    }
                }
            }
        }
    } catch (IllegalStateException e) {

    }
    final boolean include = req.getDispatcherType() == DispatcherType.INCLUDE;
    if (!req.getMethod().equals(Methods.HEAD_STRING)) {
        if(rangeResponse == null) {
            resource.serve(exchange.getResponseSender(), exchange, completionCallback(include));
        } else {
            ((RangeAwareResource)resource).serveRange(exchange.getResponseSender(), exchange, start, end, completionCallback(include));
        }
    }
}
 
Example 6
Source File: JavaScriptHandler.java    From divolte-collector with Apache License 2.0 4 votes vote down vote up
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if (logger.isDebugEnabled()) {
        logger.debug("Requested received for {} from {}",
                     resource.getResourceName(), exchange.getSourceAddress().getHostString());
    }
    // Start with headers that we always set the same way.
    final HeaderMap responseHeaders = exchange.getResponseHeaders();
    responseHeaders.put(Headers.CACHE_CONTROL, CACHE_CONTROL_HEADER_VALUE);

    // Figure out if we possibly need to deal with a compressed response,
    // based on client capability.
    final GzippableHttpBody uncompressedBody = resource.getEntityBody();
    final Optional<HttpBody> gzippedBody = uncompressedBody.getGzippedBody();
    final HttpBody bodyToSend;
    if (gzippedBody.isPresent()) {
        /*
         * Compressed responses can use Content-Encoding and/or Transfer-Encoding.
         * The semantics differ slightly, but it is suffice to say that most user
         * agents don't advertise their Transfer-Encoding support.
         * So for now we only support the Content-Encoding mechanism.
         * Some other notes:
         *  - Some clients implement 'deflate' incorrectly. Hence we only support 'gzip',
         *    despite it having slightly more overhead.
         *  - We don't use Undertow's built-in compression support because we've
         *    pre-calculated the compressed response and expect to serve it up
         *    repeatedly, instead of calculating it on-the-fly for every request.
         */
        responseHeaders.put(Headers.VARY, Headers.ACCEPT_ENCODING_STRING);
        final HeaderValues acceptEncoding =
                exchange.getRequestHeaders().get(Headers.ACCEPT_ENCODING);
        if (null != acceptEncoding &&
                acceptEncoding.stream()
                              .anyMatch((header) -> Iterables.contains(HEADER_SPLITTER.split(header), "gzip"))) {
            responseHeaders.put(Headers.CONTENT_ENCODING, "gzip");
            bodyToSend = gzippedBody.get();
        } else {
            bodyToSend = uncompressedBody;
        }
    } else {
        bodyToSend = uncompressedBody;
    }

    // Now we know which version of the entity is visible to this user-agent,
    // figure out if the client already has the current version or not.
    final ETag eTag = bodyToSend.getETag();
    responseHeaders.put(Headers.ETAG, eTag.toString());
    if (ETagUtils.handleIfNoneMatch(exchange, eTag, true)) {
        final ByteBuffer entityBody = bodyToSend.getBody();
        responseHeaders.put(Headers.CONTENT_TYPE, "application/javascript");
        exchange.getResponseSender().send(entityBody);
    } else {
        exchange.setStatusCode(StatusCodes.NOT_MODIFIED);
        exchange.endExchange();
    }
}