Example usage for javax.servlet.http HttpServletResponse SC_PRECONDITION_FAILED

List of usage examples for javax.servlet.http HttpServletResponse SC_PRECONDITION_FAILED

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletResponse SC_PRECONDITION_FAILED.

Prototype

int SC_PRECONDITION_FAILED

To view the source code for javax.servlet.http HttpServletResponse SC_PRECONDITION_FAILED.

Click Source Link

Document

Status code (412) indicating that the precondition given in one or more of the request-header fields evaluated to false when it was tested on the server.

Usage

From source file:com.github.zhanhb.ckfinder.download.PathPartial.java

/**
 * Check if the if-unmodified-since condition is satisfied.
 *
 * @param request The servlet request we are processing
 * @param attr File attributes//w w  w  .jav  a2 s  . c  om
 */
private void checkIfUnmodifiedSince(HttpServletRequest request, BasicFileAttributes attr) {
    if (request.getHeader(HttpHeaders.IF_MATCH) == null) {
        try {
            long lastModified = attr.lastModifiedTime().toMillis();
            long headerValue = request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
            if (headerValue != -1 && lastModified >= headerValue + 1000) {
                // The entity has not been modified since the date
                // specified by the client. This is not an error case.
                throw new UncheckException(HttpServletResponse.SC_PRECONDITION_FAILED);
            }
        } catch (IllegalArgumentException ex) {
            throw new UncheckException(HttpServletResponse.SC_PRECONDITION_FAILED);
        }
    }
}

From source file:com.enonic.cms.server.service.webdav.DavResourceImpl.java

public void unlock(String lockToken) throws DavException {
    ActiveLock lock = getLock(Type.WRITE, Scope.EXCLUSIVE);
    if (lock == null) {
        throw new DavException(HttpServletResponse.SC_PRECONDITION_FAILED);
    } else if (lock.isLockedByToken(lockToken)) {
        lockManager.releaseLock(lockToken, this);
    } else {/*  w  ww . jav a2s  . c o m*/
        throw new DavException(DavServletResponse.SC_LOCKED);
    }
}

From source file:ch.entwine.weblounge.common.impl.request.Http11ProtocolHandler.java

/**
 * Method generateHeaders./*from   w  w  w .  j  a va  2 s  .c om*/
 * 
 * @param resp
 * @param type
 */
public static void generateHeaders(HttpServletResponse resp, Http11ResponseType type) {

    /* generate headers only once! */
    if (type.headers)
        return;
    type.headers = true;

    /* adjust the statistics */
    ++stats[STATS_HEADER_GENERATED];
    incResponseStats(type.type, headerStats);

    /* set the date header */
    resp.setDateHeader(HEADER_DATE, type.time);

    /* check expires */
    if (type.expires > type.time + MS_PER_YEAR) {
        type.expires = type.time + MS_PER_YEAR;
        log.warn("Expiration date too far in the future. Adjusting.");
    }

    /* set the standard headers and status code */
    switch (type.type) {
    case RESPONSE_PARTIAL_CONTENT:
        if (type.expires > type.time)
            resp.setDateHeader(HEADER_EXPIRES, type.expires);
        if (type.modified > 0) {
            resp.setHeader(HEADER_ETAG, Http11Utils.calcETag(type.modified));
            resp.setDateHeader(HEADER_LAST_MODIFIED, type.modified);
        }
        if (type.size < 0 || type.from < 0 || type.to < 0 || type.from > type.to || type.to > type.size) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            break;
        }
        resp.setContentLength((int) type.size);
        resp.setHeader(HEADER_CONTENT_RANGE, "bytes " + type.from + "-" + type.to + "/" + type.size);
        resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        break;

    case RESPONSE_OK:
        if (type.expires > type.time) {
            resp.setDateHeader(HEADER_EXPIRES, type.expires);
        } else if (type.expires == 0) {
            resp.setHeader(HEADER_CACHE_CONTROL, "no-cache");
            resp.setHeader(HEADER_PRAGMA, "no-cache");
            resp.setDateHeader(HEADER_EXPIRES, 0);
        }
        if (type.modified > 0) {
            resp.setHeader(HEADER_ETAG, Http11Utils.calcETag(type.modified));
            resp.setDateHeader(HEADER_LAST_MODIFIED, type.modified);
        }
        if (type.size >= 0)
            resp.setContentLength((int) type.size);
        resp.setStatus(HttpServletResponse.SC_OK);
        break;

    case RESPONSE_NOT_MODIFIED:
        if (type.expires > type.time)
            resp.setDateHeader(HEADER_EXPIRES, type.expires);
        if (type.modified > 0)
            resp.setHeader(HEADER_ETAG, Http11Utils.calcETag(type.modified));
        resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        break;

    case RESPONSE_METHOD_NOT_ALLOWED:
        resp.setHeader(HEADER_ALLOW, "GET, POST, HEAD");
        resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        break;

    case RESPONSE_PRECONDITION_FAILED:
        if (type.expires > type.time)
            resp.setDateHeader(HEADER_EXPIRES, type.expires);
        if (type.modified > 0) {
            resp.setHeader(HEADER_ETAG, Http11Utils.calcETag(type.modified));
            resp.setDateHeader(HEADER_LAST_MODIFIED, type.modified);
        }
        resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
        break;

    case RESPONSE_REQUESTED_RANGE_NOT_SATISFIABLE:
        if (type.expires > type.time)
            resp.setDateHeader(HEADER_EXPIRES, type.expires);
        if (type.modified > 0) {
            resp.setHeader(HEADER_ETAG, Http11Utils.calcETag(type.modified));
            resp.setDateHeader(HEADER_LAST_MODIFIED, type.modified);
        }
        if (type.size >= 0)
            resp.setHeader(HEADER_CONTENT_RANGE, "*/" + type.size);
        break;

    case RESPONSE_INTERNAL_SERVER_ERROR:
    default:
        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
}

From source file:org.apache.archiva.webdav.ArchivaDavResource.java

@Override
public void unlock(String lockToken) throws DavException {
    ActiveLock lock = getLock(Type.WRITE, Scope.EXCLUSIVE);
    if (lock == null) {
        throw new DavException(HttpServletResponse.SC_PRECONDITION_FAILED);
    } else if (lock.isLockedByToken(lockToken)) {
        lockManager.releaseLock(lockToken, this);
    } else {//  ww  w.j  av  a  2  s.  co  m
        throw new DavException(DavServletResponse.SC_LOCKED);
    }
}

From source file:de.digitalcollections.streaming.euphoria.controller.StreamingController.java

/**
 * Create response for the request.// www  .j  ava  2  s  . c om
 *
 * @param id The id of requested content.
 * @param extension The (target) file extension/format of requested content.
 * @param request The request to be responded to.
 * @param response The response to the request.
 * @param head "true" if response body should be written (GET) or "false" if not (HEAD).
 * @throws IOException If something fails at I/O level.
 */
private void respond(String id, String extension, HttpServletRequest request, HttpServletResponse response,
        boolean head) throws IOException {
    logRequestHeaders(request);

    response.reset();

    // try to get access to resource
    Resource resource;
    try {
        resource = getResource(id, extension);
    } catch (ResourceIOException ex) {
        LOGGER.warn("*** Response {}: Error referencing streaming resource with id {} and extension {}",
                HttpServletResponse.SC_NOT_FOUND, id, extension);
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // get resource metadata
    ResourceInfo resourceInfo = new ResourceInfo(id, resource);
    if (resourceInfo.length <= 0) {
        LOGGER.warn("*** Response {}: Error streaming resource with id {} and extension {}: not found/no size",
                HttpServletResponse.SC_NOT_FOUND, id, extension);
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    if (preconditionFailed(request, resourceInfo)) {
        LOGGER.warn(
                "*** Response {}: Precondition If-Match/If-Unmodified-Since failed for resource with id {} and extension {}.",
                HttpServletResponse.SC_PRECONDITION_FAILED, id, extension);
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    setCacheHeaders(response, resourceInfo);

    if (notModified(request, resourceInfo)) {
        LOGGER.debug("*** Response {}: 'Not modified'-response for resource with id {} and extension {}.",
                HttpServletResponse.SC_NOT_MODIFIED, id, extension);
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;
    }

    List<Range> ranges = getRanges(request, resourceInfo);

    if (ranges == null) {
        response.setHeader("Content-Range", "bytes */" + resourceInfo.length);
        LOGGER.warn("Response {}: Header Range for resource with id {} and extension {} not satisfiable",
                HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, id, extension);
        response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
        return;
    }

    if (!ranges.isEmpty()) {
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    } else {
        ranges.add(new Range(0, resourceInfo.length - 1)); // Full content.
    }

    String contentType = setContentHeaders(request, response, resourceInfo, ranges);
    boolean acceptsGzip = false;
    // 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 && accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    }

    if (head) {
        return;
    }

    writeContent(response, resource, resourceInfo, ranges, contentType, acceptsGzip);
    LOGGER.debug("*** RESPONSE FINISHED ***");
}

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 av a 2  s  .c om
        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:jp.aegif.alfresco.online_webdav.WebDAVMethod.java

/**
 * Parses "If" header of the request./*from ww w  . j  a  v a2  s  .  c  o m*/
 * Stores conditions that should be checked.
 * Parses both No-tag-list and Tagged-list formats
 * See "10.4.2 Syntax" paragraph of the WebDAV specification for "If" header format.
 * 
 */
protected void parseIfHeader() throws WebDAVServerException {
    //String strLockToken = null;

    String strIf = m_request.getHeader(WebDAV.HEADER_IF);

    if (logger.isDebugEnabled())
        logger.debug("Parsing If header: " + strIf);

    if (strIf != null && strIf.length() > 0) {
        if (strIf.startsWith("<")) {
            m_resourceTag = strIf.substring(1, strIf.indexOf(">"));
            strIf = strIf.substring(m_resourceTag.length() + 3);
        }

        m_conditions = new LinkedList<Condition>();
        String[] parts = strIf.split("\\) \\(");
        for (int i = 0; i < parts.length; i++) {

            String partString = parts[i].replaceAll("\\(", "").replaceAll("\\)", "");

            Condition c = new Condition();
            String[] conditions = partString.split(" ");

            for (int j = 0; j < conditions.length; j++) {
                boolean fNot = false;
                String eTag = null;
                String lockToken = null;

                if (WebDAV.HEADER_KEY_NOT.equals(conditions[j])) {
                    // Check if Not keyword followed by State-token or entity-tag
                    if (j == (conditions.length - 1)) {
                        throw new WebDAVServerException(HttpServletResponse.SC_PRECONDITION_FAILED);
                    }
                    fNot = true;
                    j++;
                }

                // read State-token
                int index = conditions[j].indexOf('<');
                if (index != -1) {
                    try {
                        String s = conditions[j].substring(index + 1, conditions[j].indexOf(">"));
                        if (!s.startsWith(WebDAV.OPAQUE_LOCK_TOKEN)) {
                            if (!fNot) {
                                throw new WebDAVServerException(HttpServletResponse.SC_PRECONDITION_FAILED);
                            }
                        } else {
                            lockToken = s;
                            c.addLockTocken(lockToken, fNot);
                        }
                    } catch (IndexOutOfBoundsException e) {
                        throw new WebDAVServerException(HttpServletResponse.SC_PRECONDITION_FAILED);
                    }
                }

                // read entity-tag
                index = conditions[j].indexOf("[\"");
                if (index != -1) {
                    // TODO: implement parsing of weak ETags: W/"123..".
                    int index2 = conditions[j].indexOf("]");
                    if (index2 == -1) {
                        logger.warn("No closing ']': " + conditions[j]);
                        index2 = conditions[j].length();
                    }
                    eTag = conditions[j].substring(index + 1, index2);
                    c.addETag(eTag, fNot);
                }

            }
            m_conditions.add(c);
        }
    }
}

From source file:org.openhab.ui.cometvisu.servlet.CometVisuServlet.java

/**
 * Process the actual request.//from   w w  w .ja  v a  2 s. 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.
 *
 * @author BalusC
 * @link
 *       http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and
 *       .html
 */
private void processStaticRequest(File file, HttpServletRequest request, HttpServletResponse response,
        boolean content) throws IOException {
    // Validate the requested file
    // ------------------------------------------------------------

    if (file == null) {
        // 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 = new File(rootFolder, URLDecoder.decode(requestedFile, "UTF-8"));
    }
    // 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() + 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 (!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 = "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 = 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);
    }
}

From source file:org.openhab.ui.cometvisu.internal.servlet.CometVisuServlet.java

/**
 * Process the actual request.//from   w  w  w  .jav 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.
 *
 * @author BalusC
 * @link
 *       http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and
 *       .html
 */
private void processStaticRequest(File file, HttpServletRequest request, HttpServletResponse response,
        boolean content) throws IOException {
    // Validate the requested file
    // ------------------------------------------------------------
    if (file == null) {
        // 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 = new File(rootFolder, URLDecoder.decode(requestedFile, "UTF-8"));
    }
    if (file.equals(rootFolder) || (file.exists() && file.isDirectory())) {
        file = new File(file, "index.html");
    }

    // Check if file actually exists in filesystem.
    if (!file.exists()) {
        // show installation hints if the CometVisu-Clients main index.html is requested but cannot be found
        if (file.getParentFile().equals(rootFolder)
                && (file.getName().equalsIgnoreCase("index.html") || file.getName().length() == 0)) {
            // looking for CometVisu clients index.html file
            String path = null;
            File folder = file.isDirectory() ? file : file.getParentFile();
            if (folder.exists()) {
                File index = ClientInstaller.findClientRoot(folder, "index.html");
                path = index.exists() ? index.getPath().replaceFirst(rootFolder.getPath() + "/", "") : null;
            }
            if (path != null) {
                // forward to position
                response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
                response.setHeader("Location", path + "?" + request.getQueryString());
            } else {
                showInstallationHint(request, response);
            }
        } else {
            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 (!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 = "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 = 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";
    }

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

From source file:org.sakaiproject.sdata.tool.JCRHandler.java

/**
 * Evaluate pre-conditions, based on the request, as per the http rfc.
 *
 * @param request// w w w .  j a v  a 2  s.  c  o  m
 * @param response
 * @return
 * @throws IOException
 */
private boolean checkPreconditions(HttpServletRequest request, HttpServletResponse response,
        long lastModifiedTime, String currentEtag) throws IOException {
    lastModifiedTime = lastModifiedTime - (lastModifiedTime % 1000);
    long ifUnmodifiedSince = request.getDateHeader("if-unmodified-since");
    if (ifUnmodifiedSince > 0 && (lastModifiedTime >= ifUnmodifiedSince)) {
        response.reset();
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return false;
    }

    String ifMatch = request.getHeader("if-match");
    if (ifMatch != null && ifMatch.indexOf(currentEtag) < 0) {
        // ifMatch was present, but the currentEtag didnt match
        response.reset();
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return false;
    }
    String ifNoneMatch = request.getHeader("if-none-match");
    if (ifNoneMatch != null && ifNoneMatch.indexOf(currentEtag) >= 0) {
        if ("GET|HEAD".indexOf(request.getMethod()) >= 0) {
            response.reset();
            response.sendError(HttpServletResponse.SC_NOT_MODIFIED);

        } else {
            // ifMatch was present, but the currentEtag didnt match
            response.reset();
            response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        }
        return false;
    }
    long ifModifiedSince = request.getDateHeader("if-modified-since");
    if ((ifModifiedSince > 0) && (lastModifiedTime <= ifModifiedSince)) {
        response.reset();
        response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
        return false;
    }
    return true;
}