Example usage for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED

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

Introduction

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

Prototype

int SC_NOT_MODIFIED

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

Click Source Link

Document

Status code (304) indicating that a conditional GET operation found that the resource was available and not modified.

Usage

From source file:org.brutusin.rpc.http.RpcServlet.java

/**
 *
 * @param reqEtag//from  www  .j av  a  2 s  . c o  m
 * @param req
 * @param resp
 * @param resultStream
 * @param cachingInfo
 * @throws IOException
 */
private void serviceStream(String reqEtag, HttpServletRequest req, HttpServletResponse resp,
        StreamResult resultStream, CachingInfo cachingInfo) throws IOException {
    String eTag = null;
    if (cachingInfo != null && resultStream.getStream().getLastModified() != null) {
        eTag = CryptoUtils.getHashMD5(String.valueOf(resultStream.getStream().getLastModified()));
    }
    addCacheHeaders(req, resp, cachingInfo, eTag);

    MetaDataInputStream stream = null;

    if (resultStream != null && resultStream.getStream() != null) {
        stream = resultStream.getStream();
        if (stream.getLength() != null) {
            resp.setHeader("Content-Length", String.valueOf(stream.getLength()));
        }
        if (stream.getName() != null) {
            resp.setContentType("application/octet-stream");
            resp.setHeader("Content-Disposition", "attachment; filename=" + stream.getName());
        } else {
            if (stream.getContentType() != null) {
                resp.setContentType(stream.getContentType());
            } else {
                resp.setContentType("application/octet-stream");
            }
        }
    }
    if (reqEtag != null && reqEtag.equals(eTag)) {
        resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
    } else if (stream != null) {
        Miscellaneous.pipeSynchronously(stream, resp.getOutputStream());
    }
}

From source file:org.nuxeo.ecm.core.opencmis.impl.CmisSuiteSession.java

@Test
public void testContentStream() throws Exception {
    Document file = (Document) session.getObjectByPath("/testfolder1/testfile1");

    // check Cache Response Headers (eTag and Last-Modified)
    if (isAtomPub || isBrowser) {
        RepositoryInfo ri = session.getRepositoryInfo();
        String uri = ri.getThinClientUri() + ri.getId() + "/";
        uri += isAtomPub ? "content?id=" : "root?objectId=";
        uri += file.getId();//from  w w w.java  2  s  . c  o  m
        String eTag = file.getPropertyValue("nuxeo:contentStreamDigest");
        GregorianCalendar lastModifiedCalendar = file.getPropertyValue("dc:modified");
        String lastModified = DateUtil.formatDate(lastModifiedCalendar.getTime());
        String encoding = Base64.encodeBytes(new String(USERNAME + ":" + PASSWORD).getBytes());
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(uri);
        HttpResponse response = null;
        request.setHeader("Authorization", "Basic " + encoding);
        try {
            request.setHeader("If-None-Match", eTag);
            response = client.execute(request);
            assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response.getStatusLine().getStatusCode());
            request.removeHeaders("If-None-Match");
            request.setHeader("If-Modified-Since", lastModified);
            response = client.execute(request);
            String debug = "lastModified=" + lastModifiedCalendar.getTimeInMillis() + " If-Modified-Since="
                    + lastModified + " NuxeoContentStream last=" + NuxeoContentStream.LAST_MODIFIED;
            // TODO NXP-16198 there are still timezone issues here
            // @Ignore
            // assertEquals(debug, HttpServletResponse.SC_NOT_MODIFIED, response.getStatusLine().getStatusCode());
        } finally {
            client.getConnectionManager().shutdown();
        }
    }

    // get stream
    ContentStream cs = file.getContentStream();
    assertNotNull(cs);
    assertEquals("text/plain", cs.getMimeType());
    assertEquals("testfile.txt", cs.getFileName());
    if (!(isAtomPub || isBrowser)) {
        // TODO fix AtomPub/Browser case where the length is unknown
        // (streaming)
        assertEquals(Helper.FILE1_CONTENT.length(), cs.getLength());
    }
    assertEquals(Helper.FILE1_CONTENT, Helper.read(cs.getStream(), "UTF-8"));

    // set stream
    // TODO convenience constructors for ContentStreamImpl
    byte[] streamBytes = STREAM_CONTENT.getBytes("UTF-8");
    ByteArrayInputStream stream = new ByteArrayInputStream(streamBytes);
    cs = new ContentStreamImpl("foo.txt", BigInteger.valueOf(streamBytes.length), "text/plain; charset=UTF-8",
            stream);
    file.setContentStream(cs, true);

    // refetch stream
    file = (Document) session.getObject(file);
    cs = file.getContentStream();
    assertNotNull(cs);
    // AtomPub lowercases charset -> TODO proper mime type comparison
    String mimeType = cs.getMimeType().toLowerCase().replace(" ", "");
    assertEquals("text/plain;charset=utf-8", mimeType);
    // TODO fix AtomPub case where the filename is null
    assertEquals("foo.txt", cs.getFileName());
    if (!(isAtomPub || isBrowser)) {
        // TODO fix AtomPub/Browser case where the length is unknown
        // (streaming)
        assertEquals(streamBytes.length, cs.getLength());
    }
    assertEquals(STREAM_CONTENT, Helper.read(cs.getStream(), "UTF-8"));

    // delete
    file.deleteContentStream();
    file.refresh();
    assertEquals(null, file.getContentStream());
}

From source file:org.geowebcache.GeoWebCacheDispatcher.java

/**
 * Happy ending, sets the headers and writes the response back to the client.
 *///from   w w w.  jav  a 2s. c o m
private void writeData(ConveyorTile tile) throws IOException {
    HttpServletResponse servletResp = tile.servletResp;
    final HttpServletRequest servletReq = tile.servletReq;

    final CacheResult cacheResult = tile.getCacheResult();
    int httpCode = HttpServletResponse.SC_OK;
    String mimeType = tile.getMimeType().getMimeType();
    Resource blob = tile.getBlob();

    servletResp.setHeader("geowebcache-cache-result", String.valueOf(cacheResult));
    servletResp.setHeader("geowebcache-tile-index", Arrays.toString(tile.getTileIndex()));
    long[] tileIndex = tile.getTileIndex();
    TileLayer layer = tile.getLayer();
    GridSubset gridSubset = layer.getGridSubset(tile.getGridSetId());
    BoundingBox tileBounds = gridSubset.boundsFromIndex(tileIndex);
    servletResp.setHeader("geowebcache-tile-bounds", tileBounds.toString());
    servletResp.setHeader("geowebcache-gridset", gridSubset.getName());
    servletResp.setHeader("geowebcache-crs", gridSubset.getSRS().toString());

    final long tileTimeStamp = tile.getTSCreated();
    final String ifModSinceHeader = servletReq.getHeader("If-Modified-Since");
    // commons-httpclient's DateUtil can encode and decode timestamps formatted as per RFC-1123,
    // which is one of the three formats allowed for Last-Modified and If-Modified-Since headers
    // (e.g. 'Sun, 06 Nov 1994 08:49:37 GMT'). See
    // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1

    final String lastModified = org.apache.commons.httpclient.util.DateUtil.formatDate(new Date(tileTimeStamp));
    servletResp.setHeader("Last-Modified", lastModified);

    final Date ifModifiedSince;
    if (ifModSinceHeader != null && ifModSinceHeader.length() > 0) {
        try {
            ifModifiedSince = DateUtil.parseDate(ifModSinceHeader);
            // the HTTP header has second precision
            long ifModSinceSeconds = 1000 * (ifModifiedSince.getTime() / 1000);
            long tileTimeStampSeconds = 1000 * (tileTimeStamp / 1000);
            if (ifModSinceSeconds >= tileTimeStampSeconds) {
                httpCode = HttpServletResponse.SC_NOT_MODIFIED;
                blob = null;
            }
        } catch (DateParseException e) {
            if (log.isDebugEnabled()) {
                log.debug("Can't parse client's If-Modified-Since header: '" + ifModSinceHeader + "'");
            }
        }
    }

    if (httpCode == HttpServletResponse.SC_OK && tile.getLayer().useETags()) {
        String ifNoneMatch = servletReq.getHeader("If-None-Match");
        String hexTag = Long.toHexString(tileTimeStamp);

        if (ifNoneMatch != null) {
            if (ifNoneMatch.equals(hexTag)) {
                httpCode = HttpServletResponse.SC_NOT_MODIFIED;
                blob = null;
            }
        }

        // If we get here, we want ETags but the client did not have the tile.
        servletResp.setHeader("ETag", hexTag);
    }

    int contentLength = (int) (blob == null ? -1 : blob.getSize());
    writeFixedResponse(servletResp, httpCode, mimeType, blob, cacheResult, contentLength);
}

From source file:org.opencastproject.scheduler.impl.SchedulerServiceImplTest.java

@Test
public void testCalendarNotModified() throws Exception {
    HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
    EasyMock.replay(request);/*from  w w  w.  j a  v  a  2  s  .com*/

    SchedulerRestService restService = new SchedulerRestService();
    restService.setService(schedSvc);
    restService.setDublinCoreService(dcSvc);

    String device = "Test Device";

    // Store an event
    final DublinCoreCatalog event = generateEvent(device, new Date(),
            new Date(System.currentTimeMillis() + 60000));
    final long eventId = schedSvc.addEvent(event, wfProperties);

    // Request the calendar without specifying an etag. We should get a 200 with the icalendar in the response body
    Response response = restService.getCalendar(device, null, null, request);
    Assert.assertNotNull(response.getEntity());
    assertEquals(HttpServletResponse.SC_OK, response.getStatus());
    final String etag = (String) response.getMetadata().getFirst(HttpHeaders.ETAG);

    EasyMock.reset(request);
    EasyMock.expect(request.getHeader("If-None-Match")).andAnswer(new IAnswer<String>() {
        @Override
        public String answer() throws Throwable {
            return etag;
        }
    }).anyTimes();
    EasyMock.replay(request);

    // Request using the etag from the first response. We should get a 304 (not modified)
    response = restService.getCalendar(device, null, null, request);
    assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response.getStatus());
    Assert.assertNull(response.getEntity());

    // Update the event
    schedSvc.updateEvent(eventId, event, wfPropertiesUpdated);

    // Try using the same old etag. We should get a 200, since the event has changed
    response = restService.getCalendar(device, null, null, request);
    assertEquals(HttpServletResponse.SC_OK, response.getStatus());
    Assert.assertNotNull(response.getEntity());
    String secondEtag = (String) response.getMetadata().getFirst(HttpHeaders.ETAG);

    Assert.assertNotNull(secondEtag);
    Assert.assertFalse(etag.equals(secondEtag));
}

From source file:org.dspace.app.xmlui.cocoon.StatsBitstreamReader.java

/**
* Write the actual data out to the response.
* 
 * Some implementation notes://w  ww.  jav a 2  s.c  o m
* 
* 1) We set a short expiration time just in the hopes of preventing someone
* from overloading the server by clicking reload a bunch of times. I
 * Realize that this is nowhere near 100% effective but it may help in some
* cases and shouldn't hurt anything.
* 
* 2) We accept partial downloads, thus if you lose a connection half way
* through most web browser will enable you to resume downloading the
* bitstream.
*/
public void generate() throws IOException, SAXException, ProcessingException {
    if (this.bitstreamInputStream == null) {
        return;
    }

    // Only allow If-Modified-Since protocol if request is from a spider
    // since response headers would encourage a browser to cache results
    // that might change with different authentication.
    if (isSpider) {
        // Check for if-modified-since header -- ONLY if not authenticated
        long modSince = request.getDateHeader("If-Modified-Since");
        if (modSince != -1 && item != null && item.getLastModified().getTime() < modSince) {
            // Item has not been modified since requested date,
            // hence bitstream has not been, either; return 304
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return;
        }
    }

    // Only set Last-Modified: header for spiders or anonymous
    // access, since it might encourage browse to cache the result
    // which might leave a result only available to authenticated
    // users in the cache for a response later to anonymous user.
    try {
        if (item != null && (isSpider || ContextUtil.obtainContext(request).getCurrentUser() == null)) {
            // TODO:  Currently just borrow the date of the item, since
            // we don't have last-mod dates for Bitstreams
            response.setDateHeader("Last-Modified", item.getLastModified().getTime());
        }
    } catch (SQLException e) {
        throw new ProcessingException(e);
    }

    byte[] buffer = new byte[BUFFER_SIZE];
    int length = -1;

    // Only encourage caching if this is not a restricted resource, i.e.
    // if it is accessed anonymously or is readable by Anonymous:
    if (isAnonymouslyReadable) {
        response.setDateHeader("Expires", System.currentTimeMillis() + expires);
    }

    // If this is a large bitstream then tell the browser it should treat it as a download.
    int threshold = ConfigurationManager.getIntProperty("xmlui.content_disposition_threshold");
    if (bitstreamSize > threshold && threshold != 0) {
        String name = bitstreamName;

        // Try and make the download file name formatted for each browser.
        try {
            String agent = request.getHeader("USER-AGENT");
            if (agent != null && agent.contains("MSIE")) {
                name = URLEncoder.encode(name, "UTF8");
            } else if (agent != null && agent.contains("Mozilla")) {
                name = MimeUtility.encodeText(name, "UTF8", "B");
            }
        } catch (UnsupportedEncodingException see) {
            // do nothing
        }
        response.setHeader("Content-Disposition", "attachment;filename=" + '"' + name + '"');
    }

    ByteRange byteRange = null;

    // Turn off partial downloads, they cause problems
    // and are only rarely used. Specifically some windows pdf
    // viewers are incapable of handling this request. You can
    // uncomment the following lines to turn this feature back on.

    // response.setHeader("Accept-Ranges", "bytes");
    // String ranges = request.getHeader("Range");
    //        if (ranges != null)
    //        {
    //            try
    //            {
    //                ranges = ranges.substring(ranges.indexOf('=') + 1);
    //                byteRange = new ByteRange(ranges);
    //            }
    //            catch (NumberFormatException e)
    //            {
    //                byteRange = null;
    //                if (response instanceof HttpResponse)
    //                {
    //                    // Respond with status 416 (Request range not
    //                    // satisfiable)
    //                    response.setStatus(416);
    //                }
    //            }
    //        }

    try {
        if (byteRange != null) {
            String entityLength;
            String entityRange;
            if (this.bitstreamSize != -1) {
                entityLength = "" + this.bitstreamSize;
                entityRange = byteRange.intersection(new ByteRange(0, this.bitstreamSize)).toString();
            } else {
                entityLength = "*";
                entityRange = byteRange.toString();
            }

            response.setHeader("Content-Range", entityRange + "/" + entityLength);
            if (response instanceof HttpResponse) {
                // Response with status 206 (Partial content)
                response.setStatus(206);
            }

            int pos = 0;
            int posEnd;
            while ((length = this.bitstreamInputStream.read(buffer)) > -1) {
                posEnd = pos + length - 1;
                ByteRange intersection = byteRange.intersection(new ByteRange(pos, posEnd));
                if (intersection != null) {
                    out.write(buffer, (int) intersection.getStart() - pos, (int) intersection.length());
                }
                pos += length;
            }
        } else {
            response.setHeader("Content-Length", String.valueOf(this.bitstreamSize));

            while ((length = this.bitstreamInputStream.read(buffer)) > -1) {
                out.write(buffer, 0, length);
            }
            out.flush();
        }
    } finally {
        try {
            // Close the bitstream input stream so that we don't leak a file descriptor
            this.bitstreamInputStream.close();

            // Close the output stream as per Cocoon docs: http://cocoon.apache.org/2.2/core-modules/core/2.2/681_1_1.html
            out.close();
        } catch (IOException ioe) {
            // Closing the stream threw an IOException but do we want this to propagate up to Cocoon?
            // No point since the user has already got the bitstream contents.
            log.warn("Caught IO exception when closing a stream: " + ioe.getMessage());
        }
    }

}

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

/**
 * Process the actual request./*from  ww  w  . j a  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.apache.ranger.biz.AssetMgr.java

public XXPolicyExportAudit createPolicyAudit(final XXPolicyExportAudit xXPolicyExportAudit) {

    XXPolicyExportAudit ret = null;// w  w  w  .j  ava 2s  . c  om
    if (xXPolicyExportAudit.getHttpRetCode() == HttpServletResponse.SC_NOT_MODIFIED) {
        boolean logNotModified = PropertiesUtil.getBooleanProperty("ranger.log.SC_NOT_MODIFIED", false);
        if (!logNotModified) {
            logger.debug("Not logging HttpServletResponse." + "SC_NOT_MODIFIED, to enable, update "
                    + ": ranger.log.SC_NOT_MODIFIED");
        } else {
            // Create PolicyExportAudit record after transaction is completed. If it is created in-line here
            // then the TransactionManager will roll-back the changes because the HTTP return code is
            // HttpServletResponse.SC_NOT_MODIFIED
            Runnable commitWork = new Runnable() {
                @Override
                public void run() {
                    rangerDaoManager.getXXPolicyExportAudit().create(xXPolicyExportAudit);

                }
            };
            activityLogger.commitAfterTransactionComplete(commitWork);
        }
    } else {
        ret = rangerDaoManager.getXXPolicyExportAudit().create(xXPolicyExportAudit);
    }

    return ret;
}

From source file:org.opencms.staticexport.CmsStaticExportManager.java

/**
 * Exports the requested uri and at the same time writes the uri to the response output stream
 * if required.<p>/*from  ww  w.ja  v  a  2s .c o  m*/
 * 
 * @param req the current request
 * @param res the current response
 * @param cms an initialised cms context (should be initialised with the "Guest" user only)
 * @param data the static export data set
 * 
 * @return status code of the export operation, status codes are the same as http status codes (200,303,304)
 * 
 * @throws CmsException in case of errors accessing the VFS
 * @throws ServletException in case of errors accessing the servlet 
 * @throws IOException in case of errors writing to the export output stream
 * @throws CmsStaticExportException if static export is disabled
 */
public int export(HttpServletRequest req, HttpServletResponse res, CmsObject cms, CmsStaticExportData data)
        throws CmsException, IOException, ServletException, CmsStaticExportException {

    CmsResource resource = data.getResource();
    String vfsName = data.getVfsName();
    String rfsName;
    if (data.getParameters() != null) {
        rfsName = data.getRfsName();
    } else {
        rfsName = addDefaultFileNameToFolder(data.getRfsName(), resource.isFolder());
    }

    // cut the site root from the vfsName and switch to the correct site
    String siteRoot = OpenCms.getSiteManager().getSiteRoot(vfsName);

    CmsI18nInfo i18nInfo = OpenCms.getLocaleManager().getI18nInfo(req, cms.getRequestContext().getCurrentUser(),
            cms.getRequestContext().getCurrentProject(), vfsName);

    String remoteAddr = m_remoteAddr;
    if (remoteAddr == null) {
        remoteAddr = CmsContextInfo.LOCALHOST;
    }

    if (siteRoot != null) {
        vfsName = vfsName.substring(siteRoot.length());
    } else {
        siteRoot = "/";
    }

    if (LOG.isDebugEnabled()) {
        LOG.debug(Messages.get().getBundle().key(Messages.LOG_STATIC_EXPORT_SITE_ROOT_2, siteRoot, vfsName));
    }

    CmsContextInfo contextInfo = new CmsContextInfo(cms.getRequestContext().getCurrentUser(),
            cms.getRequestContext().getCurrentProject(), vfsName, siteRoot, i18nInfo.getLocale(),
            i18nInfo.getEncoding(), remoteAddr, CmsContextInfo.CURRENT_TIME,
            cms.getRequestContext().getOuFqn());
    CmsObject exportCms = OpenCms.initCmsObject(null, contextInfo);

    // only export those resources where the export property is set
    if (!isExportLink(exportCms, exportCms.getRequestContext().removeSiteRoot(data.getVfsName()))) {
        // the resource was not used for export, so return HttpServletResponse.SC_SEE_OTHER
        // as a signal for not exported resource
        return HttpServletResponse.SC_SEE_OTHER;
    }

    // this flag signals if the export method is used for "on demand" or "after publish". 
    // if no request and result stream are available, it was called during "export on publish"
    boolean exportOnDemand = ((req != null) && (res != null));
    CmsStaticExportResponseWrapper wrapRes = null;
    if (res != null) {
        wrapRes = new CmsStaticExportResponseWrapper(res);
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug(Messages.get().getBundle().key(Messages.LOG_SE_RESOURCE_START_1, data));
    }

    CmsFile file = exportCms.readFile(OpenCms.initResource(exportCms, vfsName, req, wrapRes));
    vfsName = exportCms.getSitePath(file);

    // check loader id for resource
    I_CmsResourceLoader loader = OpenCms.getResourceManager().getLoader(file);
    if ((loader == null) || (!loader.isStaticExportEnabled())) {
        Object[] arguments = new Object[] { vfsName, new Integer(file.getTypeId()) };
        throw new CmsStaticExportException(
                Messages.get().container(Messages.ERR_EXPORT_NOT_SUPPORTED_2, arguments));
    }

    // ensure we have exactly the same setup as if called "the usual way"
    // we only have to do this in case of the static export on demand
    if (exportOnDemand) {
        String mimetype = OpenCms.getResourceManager().getMimeType(file.getName(),
                exportCms.getRequestContext().getEncoding());
        if (wrapRes != null) {
            wrapRes.setContentType(mimetype);
        }
        exportCms.getRequestContext().setUri(vfsName);
    }

    // do the export
    int status = -1;
    List<Locale> locales = OpenCms.getLocaleManager().getDefaultLocales(exportCms, vfsName);
    boolean exported = false;
    boolean matched = false;
    // iterate over all rules
    Iterator<CmsStaticExportRfsRule> it = getRfsRules().iterator();
    while (it.hasNext()) {
        CmsStaticExportRfsRule rule = it.next();
        // normal case
        boolean export = rule.getSource().matcher(siteRoot + vfsName).matches();
        matched |= export;
        // system folder case
        export |= (vfsName.startsWith(CmsWorkplace.VFS_PATH_SYSTEM) && rule.match(vfsName));
        if (export) {
            // the resource has to exported for this rule
            CmsObject locCms = exportCms;
            Locale locale = CmsLocaleManager.getLocale(rule.getName());
            if (locales.contains(locale)) {
                // if the locale is in the default locales for the resource
                // so adjust the locale to use for exporting
                CmsContextInfo ctxInfo = new CmsContextInfo(exportCms.getRequestContext());
                ctxInfo.setLocale(locale);
                locCms = OpenCms.initCmsObject(exportCms, ctxInfo);
            }
            // read the content in the matching locale
            byte[] content = loader.export(locCms, file, req, wrapRes);
            if (content != null) {
                // write to rfs
                exported = true;
                String locRfsName = rfsName;
                if (locales.contains(locale)) {
                    locRfsName = rule.getLocalizedRfsName(rfsName, "/");
                }
                writeResource(req, rule.getExportPath(), locRfsName, resource, content);
            }
        }
    }
    if (!matched) {
        // no rule matched
        String exportPath = getExportPath(siteRoot + vfsName);
        byte[] content = loader.export(exportCms, file, req, wrapRes);
        if (content != null) {
            exported = true;
            writeResource(req, exportPath, rfsName, resource, content);
        }
    }

    if (exported) {
        // get the wrapper status that was set
        status = (wrapRes != null) ? wrapRes.getStatus() : -1;
        if (status < 0) {
            // the status was not set, assume everything is o.k.
            status = HttpServletResponse.SC_OK;
        }
    } else {
        // the resource was not written because it was not modified. 
        // set the status to not modified
        status = HttpServletResponse.SC_NOT_MODIFIED;
    }

    return status;
}

From source file:org.jtalks.jcommune.plugin.questionsandanswers.controller.QuestionsAndAnswersController.java

/**
 * Writes icon to response and set apropriate response headers
 *
 * @param request HttpServletRequest/*from  w  w w.j  a  va2  s.  c om*/
 * @param response HttpServletResponse
 * @param iconPath path to icon to be writed
 *
 * @throws IOException if icon not found
 */
private void processIconRequest(HttpServletRequest request, HttpServletResponse response, String iconPath)
        throws IOException {
    if (request.getHeader(IF_MODIFIED_SINCE_HEADER) != null) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;
    }
    byte[] icon = ByteStreams.toByteArray(getClass().getResourceAsStream(iconPath));
    response.setContentType("image/png");
    response.setContentLength(icon.length);
    response.getOutputStream().write(icon);
    response.setHeader("Pragma", "public");
    response.setHeader("Cache-Control", "public");
    response.addHeader("Cache-Control", "must-revalidate");
    response.addHeader("Cache-Control", "max-age=0");
    String formattedDateExpires = DateFormatUtils.format(new Date(), HTTP_HEADER_DATETIME_PATTERN, Locale.US);
    response.setHeader("Expires", formattedDateExpires);
    Date lastModificationDate = new Date(0);
    response.setHeader("Last-Modified",
            DateFormatUtils.format(lastModificationDate, HTTP_HEADER_DATETIME_PATTERN, Locale.US));
}

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

/**
 * Process the actual request./*from   w w w.j  ava  2s. c  om*/
 *
 * @param request
 *            The request to be processed.
 * @param response
 *            The response to be created.
 * @param content
 *            Whether the request body should be written (GET) or not
 *            (HEAD).
 * @throws IOException
 *             If something fails at I/O level.
 *
 * @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);
    }
}