Example usage for javax.servlet.http HttpServletRequest getDateHeader

List of usage examples for javax.servlet.http HttpServletRequest getDateHeader

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletRequest getDateHeader.

Prototype

public long getDateHeader(String name);

Source Link

Document

Returns the value of the specified request header as a long value that represents a Date object.

Usage

From source file:eionet.gdem.web.FileDownloadServlet.java

/**
 * Process the actual request.//from  w w w .  ja  v  a 2s .  co  m
 *
 * @param request
 *            The request to be processed.
 * @param response
 *            The response to be created.
 * @param content
 *            Whether the request body should be written (GET) or not (HEAD).
 * @throws IOException
 *             If something fails at I/O level.
 * @throws ServletException If an error occurs.
 */
private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content)
        throws IOException, ServletException {

    String urlPath = URLDecoder
            .decode(StringUtils.substringAfter(request.getRequestURI(), request.getContextPath()), "UTF-8");
    String filePath = Properties.appRootFolder + urlPath;

    String securityMessage = checkPermissions(request, urlPath);
    if (securityMessage != null) {
        handleNotAuthorised(securityMessage, request, response);
        return;
    }

    // Get the file object from the file store
    File file = new File(filePath);

    // If file was not found, send 404.
    if (file == null || !file.exists() || !file.isFile()) {
        handleFileNotFound("Could not find file by the following URI: " + request.getRequestURI(), request,
                response);
        return;
    }

    // Prepare some variables. The ETag is an unique identifier of the file.
    String fileName = file.getName();
    long length = file.length();
    long lastModified = file.lastModified();
    String eTag = fileName + "_" + length + "_" + lastModified;

    // Validate request headers for caching ---------------------------------------------------

    // If-None-Match header should contain "*" or ETag. If so, then return 304.
    String ifNoneMatch = request.getHeader("If-None-Match");
    if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
        response.setHeader("ETag", eTag); // Required in 304.
        response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
        return;
    }

    // If-Modified-Since header should be greater than LastModified. If so, then return 304.
    // This header is ignored if any If-None-Match header is specified.
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
        response.setHeader("ETag", eTag); // Required in 304.
        response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
        return;
    }

    // Validate request headers for resume ----------------------------------------------------

    // If-Match header should contain "*" or ETag. If not, then return 412.
    String ifMatch = request.getHeader("If-Match");
    if (ifMatch != null && !matches(ifMatch, eTag)) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // If-Unmodified-Since header should be greater than LastModified. If not, then return 412.
    long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
    if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // Validate and process range -------------------------------------------------------------

    // Prepare some variables. The full Range represents the complete file.
    Range full = new Range(0, length - 1, length);
    List<Range> ranges = new ArrayList<Range>();

    // Validate and process Range and If-Range headers.
    String range = request.getHeader("Range");
    if (range != null) {

        // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416.
        if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
            response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }

        // If-Range header should either match ETag or be greater then LastModified. If not,
        // then return full file.
        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(eTag)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
                    ranges.add(full);
                }
            } catch (IllegalArgumentException ignore) {
                ranges.add(full);
            }
        }

        // If any valid If-Range header, then process each part of byte range.
        if (ranges.isEmpty()) {
            for (String part : range.substring(6).split(",")) {
                // Assuming a file with length of 100, the following examples returns bytes at:
                // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100).
                long start = sublong(part, 0, part.indexOf("-"));
                long end = sublong(part, part.indexOf("-") + 1, part.length());

                if (start == -1) {
                    start = length - end;
                    end = length - 1;
                } else if (end == -1 || end > length - 1) {
                    end = length - 1;
                }

                // Check if Range is syntactically valid. If not, then return 416.
                if (start > end) {
                    response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                    return;
                }

                // Add range.
                ranges.add(new Range(start, end, length));
            }
        }
    }

    // Prepare and initialize response --------------------------------------------------------

    // Get content type by file name and set default GZIP support and content disposition.
    String contentType = getServletContext().getMimeType(fileName);
    boolean acceptsGzip = false;
    String disposition = "inline";

    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "text/plain";
    }

    // If content type is text, then determine whether GZIP content encoding is supported by
    // the browser and expand content type with the one and right character encoding.
    // Else, expect for images, determine content disposition. If content type is supported by
    // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
    if (contentType.startsWith("text")) {
        String acceptEncoding = request.getHeader("Accept-Encoding");
        acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    } else if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment";
    }

    // Initialize response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);

    // Send requested file (part(s)) to client ------------------------------------------------

    // Prepare streams.
    RandomAccessFile input = null;
    OutputStream output = null;

    try {
        // Open streams.
        input = new RandomAccessFile(file, "r");
        output = response.getOutputStream();

        if (ranges.isEmpty() || ranges.get(0) == full) {

            // Return full file.
            Range r = full;
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);

            if (content) {
                if (acceptsGzip) {
                    // The browser accepts GZIP, so GZIP the content.
                    response.setHeader("Content-Encoding", "gzip");
                    output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE);
                } else {
                    // Content length is not directly predictable in case of GZIP.
                    // So only add it if there is no means of GZIP, else browser will hang.
                    response.setHeader("Content-Length", String.valueOf(r.length));
                }

                // Copy full range.
                copy(input, output, r.start, r.length);
            }

        } else if (ranges.size() == 1) {

            // Return single part of file.
            Range r = ranges.get(0);
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            response.setHeader("Content-Length", String.valueOf(r.length));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Copy single part range.
                copy(input, output, r.start, r.length);
            }

        } else {

            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Cast back to ServletOutputStream to get the easy println methods.
                ServletOutputStream sos = (ServletOutputStream) output;

                // Copy multi part range.
                for (Range r : ranges) {
                    // Add multipart boundary and header fields for every range.
                    sos.println();
                    sos.println("--" + MULTIPART_BOUNDARY);
                    sos.println("Content-Type: " + contentType);
                    sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);

                    // Copy single part range of multi part range.
                    copy(input, output, r.start, r.length);
                }

                // End with multipart boundary.
                sos.println();
                sos.println("--" + MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        close(output);
        close(input);
    }
}

From source file:edu.chalmers.dat076.moviefinder.controller.FileController.java

/**
 * Process the actual request.//from  w ww.  j a  v  a 2s .c  o  m
 *
 * @param request The request to be processed.
 * @param response The response to be created.
 * @param content Whether the request body should be written (GET) or not
 * (HEAD).
 * @throws IOException If something fails at I/O level.
 */
private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content,
        String path, String defaultContentType) throws IOException {
    // Validate the requested file ------------------------------------------------------------

    // URL-decode the file name (might contain spaces and on) and prepare file object.
    File file = new File(path);

    // Check if file actually exists in filesystem.
    if (!file.exists()) {
        // Do your thing if the file appears to be non-existing.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Prepare some variables. The ETag is an unique identifier of the file.
    String fileName = file.getName();
    long length = file.length();
    long lastModified = file.lastModified();
    String eTag = fileName + "_" + length + "_" + lastModified;
    long expires = System.currentTimeMillis() + FileControllerUtils.DEFAULT_EXPIRE_TIME;

    // Validate request headers for caching ---------------------------------------------------
    // If-None-Match header should contain "*" or ETag. If so, then return 304.
    String ifNoneMatch = request.getHeader("If-None-Match");
    if (ifNoneMatch != null && FileControllerUtils.matches(ifNoneMatch, eTag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        return;
    }

    // If-Modified-Since header should be greater than LastModified. If so, then return 304.
    // This header is ignored if any If-None-Match header is specified.
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        return;
    }

    // Validate request headers for resume ----------------------------------------------------
    // If-Match header should contain "*" or ETag. If not, then return 412.
    String ifMatch = request.getHeader("If-Match");
    if (ifMatch != null && !FileControllerUtils.matches(ifMatch, eTag)) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // If-Unmodified-Since header should be greater than LastModified. If not, then return 412.
    long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
    if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // Validate and process range -------------------------------------------------------------
    // Prepare some variables. The full Range represents the complete file.
    Range full = new Range(0, length - 1, length);
    List<Range> ranges = new ArrayList<>();

    // Validate and process Range and If-Range headers.
    String range = request.getHeader("Range");
    if (range != null) {

        // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416.
        if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
            response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }

        // If-Range header should either match ETag or be greater then LastModified. If not,
        // then return full file.
        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(eTag)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
                    ranges.add(full);
                }
            } catch (IllegalArgumentException ignore) {
                ranges.add(full);
            }
        }

        // If any valid If-Range header, then process each part of byte range.
        if (ranges.isEmpty()) {
            for (String part : range.substring(6).split(",")) {
                // Assuming a file with length of 100, the following examples returns bytes at:
                // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100).
                long start = FileControllerUtils.sublong(part, 0, part.indexOf("-"));
                long end = FileControllerUtils.sublong(part, part.indexOf("-") + 1, part.length());

                if (start == -1) {
                    start = length - end;
                    end = length - 1;
                } else if (end == -1 || end > length - 1) {
                    end = length - 1;
                }

                // Check if Range is syntactically valid. If not, then return 416.
                if (start > end) {
                    response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                    return;
                }

                // Add range.
                ranges.add(new Range(start, end, length));
            }
        }
    }

    // Prepare and initialize response --------------------------------------------------------
    // Get content type by file name and set default GZIP support and content disposition.
    String contentType = request.getServletContext().getMimeType(fileName);
    boolean acceptsGzip = false;
    String disposition = "inline";

    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    //if (contentType == null) {
    contentType = defaultContentType;
    //}

    // If content type is text, then determine whether GZIP content encoding is supported by
    // the browser and expand content type with the one and right character encoding.
    if (contentType.startsWith("text")) {
        String acceptEncoding = request.getHeader("Accept-Encoding");
        acceptsGzip = acceptEncoding != null && FileControllerUtils.accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    } // Else, expect for images, determine content disposition. If content type is supported by
      // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
    else if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && FileControllerUtils.accepts(accept, contentType) ? "inline"
                : "attachment";
    }

    // Initialize response.
    response.reset();
    response.setBufferSize(FileControllerUtils.DEFAULT_BUFFER_SIZE);
    //response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", expires);

    // Send requested file (part(s)) to client ------------------------------------------------
    // Prepare streams.
    RandomAccessFile input = null;
    OutputStream output = null;

    try {
        // Open streams.
        input = new RandomAccessFile(file, "r");
        output = response.getOutputStream();

        if (ranges.isEmpty() || ranges.get(0) == full) {

            // Return full file.
            Range r = full;
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);

            if (content) {
                if (acceptsGzip) {
                    // The browser accepts GZIP, so GZIP the content.
                    response.setHeader("Content-Encoding", "gzip");
                    output = new GZIPOutputStream(output, FileControllerUtils.DEFAULT_BUFFER_SIZE);
                } else {
                    // Content length is not directly predictable in case of GZIP.
                    // So only add it if there is no means of GZIP, else browser will hang.
                    response.setHeader("Content-Length", String.valueOf(r.length));
                }

                // Copy full range.
                FileControllerUtils.copy(input, output, r.start, r.length);
            }

        } else if (ranges.size() == 1) {

            // Return single part of file.
            Range r = ranges.get(0);
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            response.setHeader("Content-Length", String.valueOf(r.length));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Copy single part range.
                FileControllerUtils.copy(input, output, r.start, r.length);
            }

        } else {

            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + FileControllerUtils.MULTIPART_BOUNDARY);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Cast back to ServletOutputStream to get the easy println methods.
                ServletOutputStream sos = (ServletOutputStream) output;

                // Copy multi part range.
                for (Range r : ranges) {
                    // Add multipart boundary and header fields for every range.
                    sos.println();
                    sos.println("--" + FileControllerUtils.MULTIPART_BOUNDARY);
                    sos.println("Content-Type: " + contentType);
                    sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);

                    // Copy single part range of multi part range.
                    FileControllerUtils.copy(input, output, r.start, r.length);
                }

                // End with multipart boundary.
                sos.println();
                sos.println("--" + FileControllerUtils.MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        FileControllerUtils.close(output);
        FileControllerUtils.close(input);
    }
}

From source file:org.apache.catalina.servlets.DefaultServlet.java

/**
 * Check if the if-modified-since condition is satisfied.
 *
 * @param request      The servlet request we are processing
 * @param response     The servlet response we are creating
 * @param resourceInfo File object/*from ww w  . j  a v a 2  s .  com*/
 * @return boolean true if the resource meets the specified condition,
 *         and false if the condition is not satisfied, in which case request
 *         processing is stopped
 * @throws IOException Description of the Exception
 */
private boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response,
        ResourceInfo resourceInfo) throws IOException {
    try {
        long headerValue = request.getDateHeader("If-Modified-Since");
        long lastModified = resourceInfo.date;
        if (headerValue != -1) {

            // If an If-None-Match header has been specified, if modified since
            // is ignored.
            if ((request.getHeader("If-None-Match") == null) && (lastModified <= headerValue + 1000)) {
                // The entity has not been modified since the date
                // specified by the client. This is not an error case.
                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                return false;
            }
        }
    } catch (IllegalArgumentException illegalArgument) {
        return true;
    }
    return true;
}

From source file:org.apache.catalina.servlets.DefaultServlet.java

/**
 * Check if the if-unmodified-since condition is satisfied.
 *
 * @param request      The servlet request we are processing
 * @param response     The servlet response we are creating
 * @param resourceInfo File object/*from w  ww .  ja  v  a 2s.  c  o m*/
 * @return boolean true if the resource meets the specified condition,
 *         and false if the condition is not satisfied, in which case request
 *         processing is stopped
 * @throws IOException Description of the Exception
 */
private boolean checkIfUnmodifiedSince(HttpServletRequest request, HttpServletResponse response,
        ResourceInfo resourceInfo) throws IOException {
    try {
        long lastModified = resourceInfo.date;
        long headerValue = request.getDateHeader("If-Unmodified-Since");
        if (headerValue != -1) {
            if (lastModified > (headerValue + 1000)) {
                // The entity has not been modified since the date
                // specified by the client. This is not an error case.
                response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
                return false;
            }
        }
    } catch (IllegalArgumentException illegalArgument) {
        return true;
    }
    return true;
}

From source file:org.wso2.carbon.registry.app.ResourceServlet.java

/**
 * Logic that will be executed for a get request.
 *
 * @param request  the HTTP Servlet request.
 * @param response the HTTP Servlet response.
 *
 * @throws IOException if an error occurred.
 *//* w ww  . ja  v a  2s.  c om*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    try {
        String uri = request.getRequestURI();
        int idx = uri.indexOf("resource");
        String path = uri.substring(idx + 8);
        if (path == null) {
            String msg = "Could not get the resource content. Path is not specified.";
            log.error(msg);
            response.setStatus(HttpURLConnection.HTTP_BAD_REQUEST);
            return;
        }

        Resource resource;
        try {
            UserRegistry registry = Utils.getRegistry(request);
            try {
                path = new URI(path).normalize().toString();
            } catch (URISyntaxException e) {
                log.error("Unable to normalize requested resource path: " + path, e);
            }
            String decodedPath = URLDecoder.decode(path, RegistryConstants.DEFAULT_CHARSET_ENCODING);

            CurrentSession.setUserRealm(registry.getUserRealm());
            CurrentSession.setUser(registry.getUserName());
            try {
                if (!AuthorizationUtils.authorize(
                        RegistryUtils.getAbsolutePath(registry.getRegistryContext(), decodedPath),
                        ActionConstants.GET)) {
                    response.setStatus(HttpURLConnection.HTTP_UNAUTHORIZED);
                    response.setHeader("WWW-Authenticate", "Basic realm=\"WSO2-Registry\"");
                    return;
                }
                resource = registry.get(decodedPath);
            } finally {
                CurrentSession.removeUserRealm();
                CurrentSession.removeUser();
            }
        } catch (AuthorizationFailedException e) {
            log.error(e.getMessage());
            response.setStatus(HttpURLConnection.HTTP_UNAUTHORIZED);
            response.setHeader("WWW-Authenticate", "Basic realm=\"WSO2-Registry\"");
            return;
        } catch (RegistryException e) {
            String msg = "Error retrieving the resource " + path + ". " + e.getMessage();
            log.error(msg, e);
            throw e;
        }

        if (resource instanceof Collection) {
            String msg = "Could not get the resource content. Path " + path + " refers to a collection.";
            log.error(msg);
            response.setStatus(HttpURLConnection.HTTP_NOT_IMPLEMENTED);
            return;
        }

        // date based conditional get
        long ifModifiedSinceValue = request.getDateHeader("If-Modified-Since");
        long lastModifiedValue = resource.getLastModified().getTime();
        if (ifModifiedSinceValue > 0) {
            // convert the time values from milliseconds to seconds
            ifModifiedSinceValue /= 1000;
            lastModifiedValue /= 1000;

            /* condition to check we have latest updates in terms of dates */
            if (ifModifiedSinceValue >= lastModifiedValue) {
                /* no need to response with data */
                response.setStatus(HttpURLConnection.HTTP_NOT_MODIFIED);
                return;
            }
        }
        response.setDateHeader("Last-Modified", lastModifiedValue);

        // eTag based conditional get
        String ifNonMatchValue = request.getHeader("if-none-match");
        String currentETag = Utils.calculateEntityTag(resource);
        if (ifNonMatchValue != null) {
            if (ifNonMatchValue.equals(currentETag)) {
                /* the version is not modified */
                response.setStatus(HttpURLConnection.HTTP_NOT_MODIFIED);
                return;
            }
        }
        response.setHeader("ETag", currentETag);

        if (resource.getMediaType() != null && resource.getMediaType().length() > 0) {
            response.setContentType(resource.getMediaType());
        } else {
            response.setHeader("Content-Disposition",
                    "attachment; filename=" + RegistryUtils.getResourceName(path));
            response.setContentType("application/download");
        }

        InputStream contentStream = null;
        if (resource.getContent() != null) {
            contentStream = resource.getContentStream();
        }
        if (contentStream != null) {

            try {
                ServletOutputStream servletOutputStream = response.getOutputStream();
                byte[] contentChunk = new byte[RegistryConstants.DEFAULT_BUFFER_SIZE];
                int byteCount;
                while ((byteCount = contentStream.read(contentChunk)) != -1) {
                    servletOutputStream.write(contentChunk, 0, byteCount);
                }

                response.flushBuffer();
                servletOutputStream.flush();

            } finally {
                contentStream.close();
            }

        } else {
            Object content = resource.getContent();
            if (content != null) {

                if (content instanceof byte[]) {
                    ServletOutputStream servletOutputStream = response.getOutputStream();
                    servletOutputStream.write((byte[]) content);
                    response.flushBuffer();
                    servletOutputStream.flush();
                } else {
                    PrintWriter writer = response.getWriter();
                    writer.write(content.toString());
                    writer.flush();
                }
            }
        }

        resource.discard();

    } catch (RegistryException e) {
        String msg = "Failed to get resource content. " + e.getMessage();
        log.error(msg, e);
        response.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR);
    }
}

From source file:org.apache.catalina.servlets.DefaultServlet.java

/**
 * Parse the range header.//from  w w  w . ja va  2s  .c  o  m
 *
 * @param request      The servlet request we are processing
 * @param response     The servlet response we are creating
 * @param resourceInfo Description of the Parameter
 * @return Vector of ranges
 * @throws IOException Description of the Exception
 */
protected Vector parseRange(HttpServletRequest request, HttpServletResponse response, ResourceInfo resourceInfo)
        throws IOException {

    // Checking If-Range
    String headerValue = request.getHeader("If-Range");

    if (headerValue != null) {

        long headerValueTime = (-1L);
        try {
            headerValueTime = request.getDateHeader("If-Range");
        } catch (Exception e) {
            ;
        }

        String eTag = getETag(resourceInfo);
        long lastModified = resourceInfo.date;

        if (headerValueTime == (-1L)) {

            // If the ETag the client gave does not match the entity
            // etag, then the entire entity is returned.
            if (!eTag.equals(headerValue.trim())) {
                return null;
            }
        } else {

            // If the timestamp of the entity the client got is older than
            // the last modification date of the entity, the entire entity
            // is returned.
            if (lastModified > (headerValueTime + 1000)) {
                return null;
            }
        }

    }

    long fileLength = resourceInfo.length;

    if (fileLength == 0) {
        return null;
    }

    // Retrieving the range header (if any is specified
    String rangeHeader = request.getHeader("Range");

    if (rangeHeader == null) {
        return null;
    }
    // bytes is the only range unit supported (and I don't see the point
    // of adding new ones).
    if (!rangeHeader.startsWith("bytes")) {
        response.addHeader("Content-Range", "bytes */" + fileLength);
        response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
        return null;
    }

    rangeHeader = rangeHeader.substring(6);

    // Vector which will contain all the ranges which are successfully
    // parsed.
    Vector result = new Vector();
    StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ",");

    // Parsing the range list
    while (commaTokenizer.hasMoreTokens()) {
        String rangeDefinition = commaTokenizer.nextToken().trim();

        Range currentRange = new Range();
        currentRange.length = fileLength;

        int dashPos = rangeDefinition.indexOf('-');

        if (dashPos == -1) {
            response.addHeader("Content-Range", "bytes */" + fileLength);
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return null;
        }

        if (dashPos == 0) {

            try {
                long offset = Long.parseLong(rangeDefinition);
                currentRange.start = fileLength + offset;
                currentRange.end = fileLength - 1;
            } catch (NumberFormatException e) {
                response.addHeader("Content-Range", "bytes */" + fileLength);
                response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                return null;
            }

        } else {

            try {
                currentRange.start = Long.parseLong(rangeDefinition.substring(0, dashPos));
                if (dashPos < rangeDefinition.length() - 1) {
                    currentRange.end = Long
                            .parseLong(rangeDefinition.substring(dashPos + 1, rangeDefinition.length()));
                } else {
                    currentRange.end = fileLength - 1;
                }
            } catch (NumberFormatException e) {
                response.addHeader("Content-Range", "bytes */" + fileLength);
                response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                return null;
            }

        }

        if (!currentRange.validate()) {
            response.addHeader("Content-Range", "bytes */" + fileLength);
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return null;
        }

        result.addElement(currentRange);
    }

    return result;
}

From source file:org.gaul.s3proxy.S3ProxyHandler.java

private void handleGetBlob(HttpServletRequest request, HttpServletResponse response, BlobStore blobStore,
        String containerName, String blobName) throws IOException, S3Exception {
    int status = HttpServletResponse.SC_OK;
    GetOptions options = new GetOptions();

    String ifMatch = request.getHeader(HttpHeaders.IF_MATCH);
    if (ifMatch != null) {
        options.ifETagMatches(ifMatch);//from  w w w. jav a2 s  . c  o  m
    }

    String ifNoneMatch = request.getHeader(HttpHeaders.IF_NONE_MATCH);
    if (ifNoneMatch != null) {
        options.ifETagDoesntMatch(ifNoneMatch);
    }

    long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
    if (ifModifiedSince != -1) {
        options.ifModifiedSince(new Date(ifModifiedSince));
    }

    long ifUnmodifiedSince = request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
    if (ifUnmodifiedSince != -1) {
        options.ifUnmodifiedSince(new Date(ifUnmodifiedSince));
    }

    String range = request.getHeader(HttpHeaders.RANGE);
    if (range != null && range.startsWith("bytes=") &&
    // ignore multiple ranges
            range.indexOf(',') == -1) {
        range = range.substring("bytes=".length());
        String[] ranges = range.split("-", 2);
        if (ranges[0].isEmpty()) {
            options.tail(Long.parseLong(ranges[1]));
        } else if (ranges[1].isEmpty()) {
            options.startAt(Long.parseLong(ranges[0]));
        } else {
            options.range(Long.parseLong(ranges[0]), Long.parseLong(ranges[1]));
        }
        status = HttpServletResponse.SC_PARTIAL_CONTENT;
    }

    Blob blob;
    try {
        blob = blobStore.getBlob(containerName, blobName, options);
    } catch (IllegalArgumentException iae) {
        // TODO: correct mapping?
        throw new S3Exception(S3ErrorCode.INVALID_RANGE, iae);
    }
    if (blob == null) {
        throw new S3Exception(S3ErrorCode.NO_SUCH_KEY);
    }

    response.setStatus(status);

    if (corsAllowAll) {
        response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
    }

    addMetadataToResponse(request, response, blob.getMetadata());
    // TODO: handles only a single range due to jclouds limitations
    Collection<String> contentRanges = blob.getAllHeaders().get(HttpHeaders.CONTENT_RANGE);
    if (!contentRanges.isEmpty()) {
        response.addHeader(HttpHeaders.CONTENT_RANGE, contentRanges.iterator().next());
        response.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
    }

    try (InputStream is = blob.getPayload().openStream(); OutputStream os = response.getOutputStream()) {
        ByteStreams.copy(is, os);
        os.flush();
    }
}

From source file:com.ibm.jaggr.service.impl.AggregatorImpl.java

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
    if (log.isLoggable(Level.FINEST))
        log.finest("doGet: URL=" + req.getRequestURI()); //$NON-NLS-1$

    req.setAttribute(AGGREGATOR_REQATTRNAME, this);
    ConcurrentMap<String, Object> concurrentMap = new ConcurrentHashMap<String, Object>();
    req.setAttribute(CONCURRENTMAP_REQATTRNAME, concurrentMap);

    try {/*from  ww w  .j a v  a2 s.c  o  m*/
        // Validate config last-modified if development mode is enabled
        if (getOptions().isDevelopmentMode()) {
            long lastModified = -1;
            URI configUri = getConfig().getConfigUri();
            if (configUri != null) {
                lastModified = configUri.toURL().openConnection().getLastModified();
            }
            if (lastModified > getConfig().lastModified()) {
                if (reloadConfig()) {
                    // If the config has been modified, then dependencies will be revalidated
                    // asynchronously.  Rather than forcing the current request to wait, return
                    // a response that will display an alert informing the user of what is 
                    // happening and asking them to reload the page.
                    String content = "alert('" + //$NON-NLS-1$ 
                            StringUtil.escapeForJavaScript(Messages.ConfigModified) + "');"; //$NON-NLS-1$
                    resp.addHeader("Cache-control", "no-store"); //$NON-NLS-1$ //$NON-NLS-2$
                    CopyUtil.copy(new StringReader(content), resp.getOutputStream());
                    return;
                }
            }
        }

        getTransport().decorateRequest(req);
        notifyRequestListeners(RequestNotifierAction.start, req, resp);

        ILayer layer = getLayer(req);
        long modifiedSince = req.getDateHeader("If-Modified-Since"); //$NON-NLS-1$
        long lastModified = (Math.max(getCacheManager().getCache().getCreated(), layer.getLastModified(req))
                / 1000) * 1000;
        if (modifiedSince >= lastModified) {
            if (log.isLoggable(Level.FINER)) {
                log.finer("Returning Not Modified response for layer in servlet" + //$NON-NLS-1$
                        getName() + ":" //$NON-NLS-1$
                        + req.getAttribute(IHttpTransport.REQUESTEDMODULES_REQATTRNAME).toString());
            }
            resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        } else {
            // Get the InputStream for the response.  This call sets the Content-Type,
            // Content-Length and Content-Encoding headers in the response.
            InputStream in = layer.getInputStream(req, resp);
            // if any of the readers included an error response, then don't cache the layer.
            if (req.getAttribute(ILayer.NOCACHE_RESPONSE_REQATTRNAME) != null) {
                resp.addHeader("Cache-Control", "no-store"); //$NON-NLS-1$ //$NON-NLS-2$
            } else {
                resp.setDateHeader("Last-Modified", lastModified); //$NON-NLS-1$
                int expires = getConfig().getExpires();
                if (expires > 0) {
                    resp.addHeader("Cache-Control", "max-age=" + expires); //$NON-NLS-1$ //$NON-NLS-2$
                }
            }
            CopyUtil.copy(in, resp.getOutputStream());
        }
        notifyRequestListeners(RequestNotifierAction.end, req, resp);
    } catch (DependencyVerificationException e) {
        // clear the cache now even though it will be cleared when validateDeps has 
        // finished (asynchronously) so that any new requests will be forced to wait
        // until dependencies have been validated.
        getCacheManager().clearCache();
        getDependencies().validateDeps(false);

        resp.addHeader("Cache-control", "no-store"); //$NON-NLS-1$ //$NON-NLS-2$
        if (getOptions().isDevelopmentMode()) {
            String msg = StringUtil.escapeForJavaScript(MessageFormat.format(Messages.DepVerificationFailed,
                    new Object[] { e.getMessage(), AggregatorCommandProvider.EYECATCHER + " " + //$NON-NLS-1$
                            AggregatorCommandProvider.CMD_VALIDATEDEPS + " " + //$NON-NLS-1$
                            getName() + " " + //$NON-NLS-1$
                            AggregatorCommandProvider.PARAM_CLEAN,
                            getWorkingDirectory().toString().replace("\\", "\\\\") //$NON-NLS-1$ //$NON-NLS-2$
                    }));
            String content = "alert('" + msg + "');"; //$NON-NLS-1$ //$NON-NLS-2$
            try {
                CopyUtil.copy(new StringReader(content), resp.getOutputStream());
            } catch (IOException e1) {
                if (log.isLoggable(Level.SEVERE)) {
                    log.log(Level.SEVERE, e1.getMessage(), e1);
                }
                resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        } else {
            resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
        }
    } catch (ProcessingDependenciesException e) {
        resp.addHeader("Cache-control", "no-store"); //$NON-NLS-1$ //$NON-NLS-2$
        if (getOptions().isDevelopmentMode()) {
            String content = "alert('" + StringUtil.escapeForJavaScript(Messages.Busy) + "');"; //$NON-NLS-1$ //$NON-NLS-2$
            try {
                CopyUtil.copy(new StringReader(content), resp.getOutputStream());
            } catch (IOException e1) {
                if (log.isLoggable(Level.SEVERE)) {
                    log.log(Level.SEVERE, e1.getMessage(), e1);
                }
                resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        } else {
            resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
        }
    } catch (BadRequestException e) {
        exceptionResponse(req, resp, e, HttpServletResponse.SC_BAD_REQUEST);
    } catch (NotFoundException e) {
        exceptionResponse(req, resp, e, HttpServletResponse.SC_NOT_FOUND);
    } catch (Exception e) {
        exceptionResponse(req, resp, e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } finally {
        concurrentMap.clear();
    }
}

From source file:org.jahia.services.content.files.StaticFileServlet.java

/**
 * Process the actual request.//w w w  .j a v a  2 s .  c  om
 *
 * @param request  The request to be processed.
 * @param response The response to be created.
 * @param content  Whether the request body should be written (GET) or not (HEAD).
 * @throws IOException If something fails at I/O level.
 */
private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content)
        throws IOException {

    // Validate the requested file ------------------------------------------------------------

    // Get requested file by path info.
    String requestedFile = request.getPathInfo();

    // Check if file is actually supplied to the request URL.
    if (requestedFile == null) {
        // Do your thing if the file is not supplied to the request URL.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // URL-decode the file name (might contain spaces and on) and prepare file object.
    File file = new File(basePath, URLDecoder.decode(requestedFile, "UTF-8"));

    // Check if file actually exists in filesystem.
    if (!file.exists() || !file.isFile()) {
        // Do your thing if the file appears to be non-existing.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Verify the file requested is a descendant of the base directory.
    if (!file.getCanonicalPath().startsWith(basePath)) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Prepare some variables. The ETag is an unique identifier of the file.
    String fileName = file.getName();
    long length = file.length();
    long lastModified = file.lastModified();
    String eTag = fileName + "_" + length + "_" + lastModified;
    long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME;

    // Validate request headers for caching ---------------------------------------------------

    // If-None-Match header should contain "*" or ETag. If so, then return 304.
    String ifNoneMatch = request.getHeader("If-None-Match");
    if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        return;
    }

    // If-Modified-Since header should be greater than LastModified. If so, then return 304.
    // This header is ignored if any If-None-Match header is specified.
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        return;
    }

    // Validate request headers for resume ----------------------------------------------------

    // If-Match header should contain "*" or ETag. If not, then return 412.
    String ifMatch = request.getHeader("If-Match");
    if (ifMatch != null && !matches(ifMatch, eTag)) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // If-Unmodified-Since header should be greater than LastModified. If not, then return 412.
    long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
    if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // Validate and process range -------------------------------------------------------------

    // Prepare some variables. The full Range represents the complete file.
    Range full = new Range(0, length - 1, length);
    List<Range> ranges = new ArrayList<Range>();

    // Validate and process Range and If-Range headers.
    String range = request.getHeader("Range");
    if (range != null) {

        // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416.
        if (!PATTERN_RANGE.matcher(range).matches()) {
            response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }

        // If-Range header should either match ETag or be greater then LastModified. If not,
        // then return full file.
        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(eTag)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
                    ranges.add(full);
                }
            } catch (IllegalArgumentException ignore) {
                ranges.add(full);
            }
        }

        // If any valid If-Range header, then process each part of byte range.
        if (ranges.isEmpty()) {
            for (String part : Patterns.COMMA.split(range.substring(6))) {
                // Assuming a file with length of 100, the following examples returns bytes at:
                // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100).
                long start = sublong(part, 0, part.indexOf("-"));
                long end = sublong(part, part.indexOf("-") + 1, part.length());

                if (start == -1) {
                    start = length - end;
                    end = length - 1;
                } else if (end == -1 || end > length - 1) {
                    end = length - 1;
                }

                // Check if Range is syntactically valid. If not, then return 416.
                if (start > end) {
                    response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                    return;
                }

                // Add range.
                ranges.add(new Range(start, end, length));
            }
        }
    }

    // Prepare and initialize response --------------------------------------------------------

    // Get content type by file name and set default GZIP support and content disposition.
    String contentType = getServletContext().getMimeType(fileName);
    boolean acceptsGzip = false;
    String disposition = "inline";

    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "application/octet-stream";
    }

    // If content type is text, then determine whether GZIP content encoding is supported by
    // the browser and expand content type with the one and right character encoding.
    if (contentType.startsWith("text")) {
        String acceptEncoding = request.getHeader("Accept-Encoding");
        acceptsGzip = enableGzip && acceptEncoding != null && accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    }

    // Else, expect for images, determine content disposition. If content type is supported by
    // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
    else if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment";
    }

    // Initialize response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", expires);

    // Send requested file (part(s)) to client ------------------------------------------------

    // Prepare streams.
    RandomAccessFile input = null;
    OutputStream output = null;

    try {
        // Open streams.
        input = new RandomAccessFile(file, "r");
        output = response.getOutputStream();

        if (ranges.isEmpty() || ranges.get(0) == full) {

            // Return full file.
            Range r = full;
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);

            if (content) {
                if (acceptsGzip) {
                    // The browser accepts GZIP, so GZIP the content.
                    response.setHeader("Content-Encoding", "gzip");
                    output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE);
                } else {
                    // Content length is not directly predictable in case of GZIP.
                    // So only add it if there is no means of GZIP, else browser will hang.
                    response.setHeader("Content-Length", String.valueOf(r.length));
                }

                // Copy full range.
                copy(input, output, r.start, r.length);
            }

        } else if (ranges.size() == 1) {

            // Return single part of file.
            Range r = ranges.get(0);
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            response.setHeader("Content-Length", String.valueOf(r.length));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Copy single part range.
                copy(input, output, r.start, r.length);
            }

        } else {

            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Cast back to ServletOutputStream to get the easy println methods.
                ServletOutputStream sos = (ServletOutputStream) output;

                // Copy multi part range.
                for (Range r : ranges) {
                    // Add multipart boundary and header fields for every range.
                    sos.println();
                    sos.println("--" + MULTIPART_BOUNDARY);
                    sos.println("Content-Type: " + contentType);
                    sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);

                    // Copy single part range of multi part range.
                    copy(input, output, r.start, r.length);
                }

                // End with multipart boundary.
                sos.println();
                sos.println("--" + MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        close(output);
        close(input);
    }
}