Example usage for java.util.zip GZIPOutputStream GZIPOutputStream

List of usage examples for java.util.zip GZIPOutputStream GZIPOutputStream

Introduction

In this page you can find the example usage for java.util.zip GZIPOutputStream GZIPOutputStream.

Prototype

public GZIPOutputStream(OutputStream out, boolean syncFlush) throws IOException 

Source Link

Document

Creates a new output stream with a default buffer size and the specified flush mode.

Usage

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

/**
 * Process the actual request./*from   ww  w .ja v  a2  s . 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.ucsd.library.dams.api.FileStoreServlet.java

/**
 * Process the actual request.//from  w w  w  .  j av 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.
 */
private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content)
        throws IOException {
    // Validate the requested file -------------------------------------

    // Get requested file by path info.
    /* start ucsd changes */

    // get object and file ids from path
    String objid = null;
    String cmpid = null;
    String fileid = null;
    try {
        // /bb1234567x/1.tif
        // /bb1234567x/1/2.tif
        String[] path = request.getPathInfo().split("/");
        if (path.length == 3) {
            objid = path[1];
            fileid = path[2];
        } else if (path.length == 4) {
            objid = path[1];
            cmpid = path[2];
            fileid = path[3];
        }
    } catch (Exception e) {
        String errorMessage = "Error parsing request pathInfo: " + request.getPathInfo();
        log.error(errorMessage, e);
        response.setContentType("text/plain");
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMessage);
        return;
    }

    // make sure required parameters are populated
    if (objid == null || objid.trim().length() == 0 || fileid == null || fileid.trim().length() == 0) {
        response.setContentType("text/plain");
        response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                "Subject and file must be specified in the request URI");
        return;
    }
    String fullFilename = objid + (StringUtils.isNotBlank(cmpid) ? "-" + cmpid : "") + "-" + fileid;

    // first load the FileStore (no point if this doesn't work)
    FileStore fs = null;
    long fsTime = 0;
    try {
        long start = System.currentTimeMillis();
        fs = FileStoreUtil.getFileStore(props, fsDefault);
        fsTime = System.currentTimeMillis() - start;
    } catch (Exception ex) {
        response.setContentType("text/plain");
        response.sendError(response.SC_INTERNAL_SERVER_ERROR, "Error initializing FileStore");
        ex.printStackTrace();
        return;
    }

    // check authorization attribute
    String restricted = null;
    String authorized = (String) request.getAttribute("edu.ucsd.library.dams.api.DAMSAPIServlet.authorized");
    if (authorized == null || !authorized.equals("true")) {
        log.warn("Illegal Access from IP " + request.getRemoteAddr() + " for file " + fullFilename);
        response.setContentType("text/plain");
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access without authorization.");
        return;
    } else {
        log.info("DAMS Access authorized for IP " + request.getRemoteAddr() + " for file " + fullFilename);
        restricted = (String) request.getAttribute("pas.restricted");
        //Disable browser caching for restricted objects.
        if (restricted != null && restricted.equals("1")) {
            String browser = request.getHeader("User-Agent");
            if (browser != null && browser.indexOf("MSIE") != -1) {
                response.addHeader("Cache-Control", "post-check=0, pre-check=0");
            } else {
                response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            }
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
        }
    }
    /* end ucsd changes */

    // load file metadata
    Map<String, String> meta = null;
    long metaTime = 0;
    try {
        long start = System.currentTimeMillis();
        meta = fs.meta(objid, cmpid, fileid);
        metaTime = System.currentTimeMillis() - start;
    } catch (Exception ex) {
        log.error("File " + fullFilename + " doesn't exist.", ex);
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Prepare some variables. The ETag is an unique identifier of the file
    String length = meta.get("Content-Length");
    String lastModStr = meta.get("Last-Modified");
    long lastModified = 0L;
    try {
        lastModified = df.parse(lastModStr).getTime();
    } catch (Exception ex) {
        // error parsing lastmod date... set to now
        lastModified = System.currentTimeMillis();
    }
    String eTag = meta.get("ETag");
    if (eTag == null) {
        eTag = fullFilename + "_" + length + "_" + lastModified;
    }

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

    // If-None-Match header should contain "*" or ETag. If so, 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;
    }

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

    // Get content type by file name and set default GZIP support and
    // content disposition.
    String contentType = getServletContext().getMimeType(fullFilename);
    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 UCSD download
    boolean download = request.getParameter("download") != null;
    if (download) {
        disposition = "attachment";
        contentType = "application/x-download";
    }
    // Else 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 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";
    }

    String sFileName = request.getParameter("name");
    if (sFileName == null || (sFileName = sFileName.trim()).length() == 0)
        sFileName = fullFilename;

    // Initialize response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setHeader("Content-Disposition", disposition + ";filename=\"" + sFileName + "\"");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    /* begin ucsd changes */
    if (restricted == null || !restricted.equals("1")) {
        response.setDateHeader("Expires", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);
    }
    /* end ucsd changes */

    // Send requested file to client ------------------------------------

    // Prepare streams.
    InputStream input = null;
    OutputStream output = null;
    long fileTime = 0;
    if (content) {
        try {
            long start = System.currentTimeMillis();
            // Open streams.
            input = fs.getInputStream(objid, cmpid, fileid);
            output = response.getOutputStream();
            response.setContentType(contentType);
            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", length);
            }

            // Copy full range.
            /* begin ucsd changes */
            FileStoreUtil.copy(input, output);
            fileTime = System.currentTimeMillis() - start;
            /* begin ucsd changes */
        } catch (Exception ex) {
            log.error("Error reading " + fullFilename, ex);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } finally {
            /* begin ucsd changes */
            log.info("Time in miliseconds to retrival file " + fullFilename + "(" + length + " bytes)"
                    + ": Total " + (fsTime + metaTime + fileTime) + "[FileStore initiation: " + fsTime
                    + "; Metadata query: " + metaTime + "; File download: " + fileTime + "]");
            /* begin ucsd changes */
            // Gently close streams.
            close(output);
            close(input);
        }
    }
}