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:annis.gui.servlets.ResourceServlet.java

@Override
@SuppressWarnings("unchecked")
public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    OutputStream outStream = response.getOutputStream();

    String completePath = request.getPathInfo();

    if (completePath == null) {
        response.sendError(404, "must provide a valid and existing path with a vistype");
        return;/*from   w w w  .  jav a  2  s.c  o  m*/
    }

    // remove trailing /
    completePath = completePath.substring(1);

    String[] pathComponents = completePath.split("/");

    String vistype = pathComponents[0];

    if (pathComponents.length < 2) {
        response.sendError(404, "must provide a valid and existing path");
        return;
    }

    String path = StringUtils.join(Arrays.copyOfRange(pathComponents, 1, pathComponents.length), "/");

    // get the visualizer for this vistype
    ResourcePlugin vis = resourceRegistry.get(vistype);
    if (vis == null) {
        response.sendError(500, "There is no resource with the short name " + vistype);
    } else if (path.endsWith(".class")) {
        response.sendError(403, "illegal class path access");
    } else {
        URL resource = vis.getClass().getResource(path);
        if (resource == null) {
            response.sendError(404, path + " not found");
        } else {
            // check if it is new
            URLConnection resourceConnection = resource.openConnection();
            long resourceLastModified = resourceConnection.getLastModified();
            long requestLastModified = request.getDateHeader("If-Modified-Since");
            if (requestLastModified != -1 && resourceLastModified <= requestLastModified) {
                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            } else {
                response.addDateHeader("Last-Modified", resourceLastModified);
                if ("localhost".equals(request.getServerName())) {
                    // does always expire right now
                    response.addDateHeader("Expires", new Date().getTime());
                } else {
                    // expires in one minute per default
                    response.addDateHeader("Expires", new Date().getTime() + 60000);
                }
                // not in cache, stream out
                String mimeType = getServletContext().getMimeType(path);
                response.setContentType(mimeType);
                if (mimeType.startsWith("text/")) {
                    response.setCharacterEncoding("UTF-8");
                }
                OutputStream bufferedOut = new BufferedOutputStream(outStream);
                InputStream resourceInStream = new BufferedInputStream(resource.openStream());

                try {
                    int v = -1;
                    while ((v = resourceInStream.read()) != -1) {
                        bufferedOut.write(v);
                    }
                } finally {
                    resourceInStream.close();
                    bufferedOut.flush();
                    outStream.flush();
                }
            }
        }
    }

}

From source file:org.kurento.repository.internal.http.RepositoryHttpServlet.java

/**
 * Parse the range header./*from  w  ww.  j a  v  a2  s .  c o m*/
 *
 * @param request
 *          The servlet request we are processing
 * @param response
 *          The servlet response we are creating
 * @return Vector of ranges
 */
protected List<Range> parseRange(HttpServletRequest request, HttpServletResponse response,
        RepositoryItemAttributes resourceAttributes) throws IOException {

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

    if (headerValue != null) {

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

        String eTag = resourceAttributes.getETag();
        long lastModified = resourceAttributes.getLastModified();

        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 FULL;
            }

        } 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 FULL;
            }

        }
    }

    long fileLength = resourceAttributes.getContentLength();

    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(SC_REQUESTED_RANGE_NOT_SATISFIABLE);
        return null;
    }

    rangeHeader = rangeHeader.substring(6);

    // Vector which will contain all the ranges which are successfully
    // parsed.
    List<Range> result = new ArrayList<>();
    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(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(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(SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                return null;
            }

        }

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

        result.add(currentRange);
    }

    return result;
}

From source file:com.kurento.kmf.repository.internal.http.RepositoryHttpServlet.java

/**
 * Parse the range header./*w ww  .  ja v  a  2 s  .c o  m*/
 * 
 * @param request
 *            The servlet request we are processing
 * @param response
 *            The servlet response we are creating
 * @return Vector of ranges
 */
protected List<Range> parseRange(HttpServletRequest request, HttpServletResponse response,
        RepositoryItemAttributes resourceAttributes) throws IOException {

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

    if (headerValue != null) {

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

        String eTag = resourceAttributes.getETag();
        long lastModified = resourceAttributes.getLastModified();

        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 FULL;
            }

        } 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 FULL;
            }

        }
    }

    long fileLength = resourceAttributes.getContentLength();

    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(SC_REQUESTED_RANGE_NOT_SATISFIABLE);
        return null;
    }

    rangeHeader = rangeHeader.substring(6);

    // Vector which will contain all the ranges which are successfully
    // parsed.
    List<Range> result = new ArrayList<>();
    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(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(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(SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                return null;
            }

        }

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

        result.add(currentRange);
    }

    return result;
}

From source file:net.yacy.http.servlets.YaCyDefaultServlet.java

protected boolean passConditionalHeaders(HttpServletRequest request, HttpServletResponse response,
        Resource resource) throws IOException {
    try {/*from  w ww .  j a v a  2 s. c o  m*/
        if (!request.getMethod().equals(HttpMethod.HEAD.asString())) {

            String ifms = request.getHeader(HttpHeader.IF_MODIFIED_SINCE.asString());
            if (ifms != null) {

                long ifmsl = request.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString());
                if (ifmsl != -1) {
                    if (resource.lastModified() / 1000 <= ifmsl / 1000) {
                        response.reset();
                        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                        response.flushBuffer();
                        return false;
                    }
                }
            }

            // Parse the if[un]modified dates and compare to resource
            long date = request.getDateHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString());

            if (date != -1) {
                if (resource.lastModified() / 1000 > date / 1000) {
                    response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
                    return false;
                }
            }
        }
    } catch (IllegalArgumentException iae) {
        if (!response.isCommitted()) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, iae.getMessage());
            return false;
        }
        throw iae;
    }
    return true;
}

From source file:org.openbravo.erpCommon.utility.ImageUtils.java

/**
 * Outputs the image/content to the response
 *//* ww  w.  jav  a  2 s  . co  m*/
public static void outputImageResource(final HttpServletRequest req, final HttpServletResponse resp,
        final String imageType) throws IOException, ServletException {
    try {
        OBContext.setAdminMode(true);

        // enforce cache validation/checks every time
        resp.addHeader(RESPONSE_HEADER_CACHE_CONTROL, RESPONSE_NO_CACHE);
        VariablesSecureApp vars = new VariablesSecureApp(req);

        Image img = null;
        if (imageType == "logo") {
            String logo = vars.getStringParameter("logo");
            String org = vars.getStringParameter("orgId");
            img = Utility.getImageLogoObject(logo, org);
            if (img == null) {
                byte[] imageFileContent = Utility.getImageLogo(logo, org);
                String mimeType = MimeTypeUtil.getInstance().getMimeTypeName(imageFileContent);
                resp.setContentType(mimeType);
                OutputStream out = resp.getOutputStream();
                resp.setContentLength(imageFileContent.length);
                out.write(imageFileContent);
                out.close();
                return;
            }
        } else {
            img = Utility.getImageObject(vars.getStringParameter("id"));
        }

        if (img != null) {
            String imageID = "IMGTAG" + img.getUpdated().toString();

            if (ImageUtils.isImageResponseRequired(req, resp, imageID)) {

                // read the image data
                byte[] imgByte = img.getBindaryData();

                // write the mimetype
                String mimeType = img.getMimetype();// write the mimetype
                if (mimeType == null) {
                    mimeType = MimeTypeUtil.getInstance().getMimeTypeName(img.getBindaryData());
                    if (img != null) {
                        // If there is an OBContext, we attempt to save the MIME type of the image
                        updateMimeType(img.getId(), mimeType);
                    }
                }

                if (!mimeType.equals("")) {
                    resp.setContentType(mimeType);
                }

                // write the image
                OutputStream out = resp.getOutputStream();
                resp.setContentLength(imgByte.length);
                out.write(imgByte);
                out.close();

            } else {
                resp.sendError(HttpServletResponse.SC_NOT_MODIFIED);
                resp.setDateHeader(RESPONSE_HEADER_LASTMODIFIED,
                        req.getDateHeader(REQUEST_HEADER_IFMODIFIEDSINCE));

            }

        }
    } finally {
        OBContext.restorePreviousMode();
    }

}

From source file:net.sourceforge.subsonic.controller.RESTController.java

public ModelAndView download(HttpServletRequest request, HttpServletResponse response) throws Exception {
    request = wrapRequest(request);//from   ww  w . j av  a2  s .c  o  m
    User user = securityService.getCurrentUser(request);
    if (!user.isDownloadRole()) {
        error(request, response, ErrorCode.NOT_AUTHORIZED,
                user.getUsername() + " is not authorized to download files.");
        return null;
    }

    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    long lastModified = downloadController.getLastModified(request);

    if (ifModifiedSince != -1 && lastModified != -1 && lastModified <= ifModifiedSince) {
        response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
        return null;
    }

    if (lastModified != -1) {
        response.setDateHeader("Last-Modified", lastModified);
    }

    return downloadController.handleRequest(request, response);
}

From source file:org.olat.commons.servlets.StaticsLegacyDispatcher.java

/**
 * Serve the requested resource.//from  www  .  j  a  va 2 s . co  m
 * 
 * @param request
 * @param response
 * @param copyContent
 * @return False if serving the resource failed/was aborted.
 * @throws IOException
 */
private boolean serveResource(HttpServletRequest request, HttpServletResponse response, boolean copyContent)
        throws IOException {
    // just another internal forward or even a direct call
    String path = getRelativePath(request);
    if (path.indexOf("/secstatic/") == 0) {
        path = path.substring(10, path.length());
    }
    PathHandler handler = null;
    String relPath = null;
    String handlerName = null;
    long start = 0;

    boolean logDebug = log.isDebug();
    if (logDebug)
        start = System.currentTimeMillis();
    try {
        relPath = path.substring(1);
        int index = relPath.indexOf('/');
        if (index != -1) {
            handlerName = relPath.substring(0, index);
            relPath = relPath.substring(index);
        }

        if (handlerName != null) {
            handler = StaticsModule.getInstance(handlerName);
        }
    } catch (IndexOutOfBoundsException e) {
        // if some problem with the url, we assign no handler
    }

    if (handler == null || relPath == null) {
        // no handler found or relPath incomplete
        response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI());
        return false;
    }

    ResourceDescriptor rd = handler.getResourceDescriptor(request, relPath);
    if (rd == null) {
        // no handler found or relPath incomplete
        response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI());
        return false;
    }

    // check if modified since
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    long lastMod = rd.getLastModified();
    if (lastMod != -1L && ifModifiedSince >= lastMod) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return false;
    }

    // server the resource
    if (copyContent) {
        InputStream is = handler.getInputStream(request, rd);
        if (is == null) {
            // resource not found or access denied
            response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI());
            return false;
        }
        StaticMediaResource smr = new StaticMediaResource(is, rd);
        ServletUtil.serveResource(request, response, smr);
        if (logDebug) {
            long stop = System.currentTimeMillis();
            log.debug("Serving resource '" + relPath + "' (" + rd.getSize() + " bytes) in " + (stop - start)
                    + "ms with handler '" + handlerName + "'.");
        }
    }
    return true;
}

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

private static void handleBlobMetadata(HttpServletRequest request, HttpServletResponse response,
        BlobStore blobStore, String containerName, String blobName) throws IOException, S3Exception {
    BlobMetadata metadata = blobStore.blobMetadata(containerName, blobName);
    if (metadata == null) {
        throw new S3Exception(S3ErrorCode.NO_SUCH_KEY);
    }//w  w  w.j  a  v a  2  s  . c om

    // BlobStore.blobMetadata does not support GetOptions so we emulate
    // conditional requests.
    String ifMatch = request.getHeader(HttpHeaders.IF_MATCH);
    String ifNoneMatch = request.getHeader(HttpHeaders.IF_NONE_MATCH);
    long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
    long ifUnmodifiedSince = request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);

    String eTag = metadata.getETag();
    if (eTag != null) {
        eTag = maybeQuoteETag(eTag);
        if (ifMatch != null && !ifMatch.equals(eTag)) {
            throw new S3Exception(S3ErrorCode.PRECONDITION_FAILED);
        }
        if (ifNoneMatch != null && ifNoneMatch.equals(eTag)) {
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return;
        }
    }

    Date lastModified = metadata.getLastModified();
    if (lastModified != null) {
        if (ifModifiedSince != -1 && lastModified.compareTo(new Date(ifModifiedSince)) <= 0) {
            throw new S3Exception(S3ErrorCode.PRECONDITION_FAILED);
        }
        if (ifUnmodifiedSince != -1 && lastModified.compareTo(new Date(ifUnmodifiedSince)) >= 0) {
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return;
        }
    }

    response.setStatus(HttpServletResponse.SC_OK);
    addMetadataToResponse(request, response, metadata);
}

From source file:net.dorokhov.pony.web.server.common.StreamingViewRenderer.java

@Override
protected void renderMergedOutputModel(Map objectMap, HttpServletRequest request, HttpServletResponse response)
        throws Exception {

    InputStream dataStream = (InputStream) objectMap.get(DownloadConstants.INPUT_STREAM);

    if (dataStream == null) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;/*from ww w .j  a  v  a  2s  . co  m*/
    }
    long length = (Long) objectMap.get(DownloadConstants.CONTENT_LENGTH);
    String fileName = (String) objectMap.get(DownloadConstants.FILENAME);
    Date lastModifiedObj = (Date) objectMap.get(DownloadConstants.LAST_MODIFIED);

    if (StringUtils.isEmpty(fileName) || lastModifiedObj == null) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    long lastModified = lastModifiedObj.getTime();
    String contentType = (String) objectMap.get(DownloadConstants.CONTENT_TYPE);

    // 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, fileName)) {
        response.setHeader("ETag", fileName); // 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", fileName); // 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, fileName)) {
        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;
        }

        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(fileName)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                if (ifRangeTime != -1) {
                    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 content disposition.
    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";
    } else if (!contentType.startsWith("image")) {
        // 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.
        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", fileName);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);

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

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

    try {
        // Open streams.
        input = new BufferedInputStream(dataStream);
        output = response.getOutputStream();

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

            // Return full file.
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + full.start + "-" + full.end + "/" + full.total);
            response.setHeader("Content-Length", String.valueOf(full.length));
            copy(input, output, length, full.start, full.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.

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

        } else {

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

            // 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, length, r.start, r.length);
            }

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

}

From source file:com.harrywu.springweb.common.StreamingViewRenderer.java

@Override
public void renderMergedOutputModel(Map<String, Object> objectMap, HttpServletRequest request,
        HttpServletResponse response) throws Exception {

    InputStream dataStream = (InputStream) objectMap.get(INPUT_STREAM);

    if (dataStream == null) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;//from  ww  w  .j a v a 2 s .c o  m
    }
    long length = (Long) objectMap.get(CONTENT_LENGTH);
    String fileName = (String) objectMap.get(FILENAME);
    Date lastModifiedObj = (Date) objectMap.get(LAST_MODIFIED);

    if (StringUtils.isEmpty(fileName) || lastModifiedObj == null) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }
    long lastModified = lastModifiedObj.getTime();
    String contentType = (String) objectMap.get(CONTENT_TYPE);

    // 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, fileName)) {
        response.setHeader("ETag", fileName); // 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", fileName); // 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, fileName)) {
        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;
        }

        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(fileName)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws
                                                                      // IAE
                                                                      // if
                                                                      // invalid.
                if (ifRangeTime != -1) {
                    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 content disposition.
    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";
    } else if (!contentType.startsWith("image")) {
        // 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.
        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", fileName);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);

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

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

    try {
        // Open streams.
        input = new BufferedInputStream(dataStream);
        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);
            response.setHeader("Content-Length", String.valueOf(r.length));
            copy(input, output, length, 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.

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

        } else {

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

            // 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, length, r.start, r.length);
            }

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

}