List of usage examples for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED
int SC_NOT_MODIFIED
To view the source code for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED.
Click Source Link
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); } }