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:fi.hoski.web.auth.LoginServlet.java
@Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); String email = request.getParameter("email"); String activationKey = request.getParameter("activationKey"); try {/*ww w. j ava 2 s. c o m*/ if (email != null && activationKey != null) { Map<String, Object> user = userDirectory.useActivationKey(email, activationKey); if (user != null) { HttpSession session = request.getSession(true); session.setAttribute(USER, user); } // redirect always, if user is not logged in, // there will be a login screen response.sendRedirect("/member"); //TODO target make configurable } else { HttpSession session = request.getSession(false); String etag = request.getHeader("If-None-Match"); @SuppressWarnings("unchecked") Map<String, Object> user = (session != null) ? (Map<String, Object>) session.getAttribute(USER) : null; String userEtag = getEtag(user); if (etag != null && etag.equals(userEtag)) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } else { response.setHeader("ETag", userEtag); response.setHeader("Cache-Control", "private"); response.setHeader("Vary", "Cookie"); writeUserJSON(user, response); } } } catch (UnavailableException ex) { log(ex.getMessage(), ex); response.sendError(HttpServletResponse.SC_FORBIDDEN, ex.getMessage()); } catch (EmailNotUniqueException ex) { log(ex.getMessage(), ex); response.sendError(HttpServletResponse.SC_FORBIDDEN, ex.getMessage()); } }
From source file:com.cloud.servlet.StaticResourceServletTest.java
@Test public void testWithEtag() throws ServletException, IOException { final HashMap<String, String> headers = new HashMap<String, String>(); headers.put("If-None-Match", StaticResourceServlet.getEtag(new File(rootDirectory, "default.css"))); final HttpServletResponse response = doGetTest("default.css", headers); Mockito.verify(response).setStatus(HttpServletResponse.SC_NOT_MODIFIED); }
From source file:org.auraframework.http.AuraResourceServlet.java
/** * check the top level component/app./*from ww w .j a va 2s . c o m*/ * * This routine checks to see that we have a valid top level component. If our top level component is out of sync, * we have to ignore it here, but we _must_ force the client to not cache the response. * * If there is a QFE, we substitute the QFE descriptor for the one given us, and continue. Again, we cannot allow * caching. * * Finally, if there is no descriptor given, we simply ignore the request and give them an empty response. Which is * done here by returning null. * * Also note that this handles the 'if-modified-since' header, as we want to tell the browser that nothing changed * in that case. * * @param request the request (for exception handling) * @param response the response (for exception handling) * @param context the context to get the definition. * @return the set of descriptors we are sending back, or null in the case that we handled the response. * @throws IOException if there was an IO exception handling a client out of sync exception * @throws ServletException if there was a problem handling the out of sync */ private Set<DefDescriptor<?>> handleTopLevel(HttpServletRequest request, HttpServletResponse response, AuraContext context) throws IOException, ServletException { DefDescriptor<? extends BaseComponentDef> appDesc = context.getApplicationDescriptor(); DefinitionService definitionService = Aura.getDefinitionService(); MasterDefRegistry mdr = context.getDefRegistry(); context.setPreloading(true); if (appDesc == null) { // // This means we have nothing to say to the client, so the response is // left completely empty. // return null; } long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); String uid = context.getUid(appDesc); try { try { definitionService.updateLoaded(appDesc); if (uid != null && ifModifiedSince != -1) { // // In this case, we have an unmodified descriptor, so just tell // the client that. // response.sendError(HttpServletResponse.SC_NOT_MODIFIED); return null; } } catch (ClientOutOfSyncException coose) { // // We can't actually handle an out of sync here, since we are doing a // preload. We have to ignore it, and continue as if nothing happened. // But in the process, we make sure to set 'no-cache' so that the result // is thrown away. This may actually not give the right result in bizarre // corner cases... beware cache inconsistencied on revert after a QFE. // // We actually probably should do something different, like send a minimalist // set of stuff to make the client re-try. // setNoCache(response); String oosUid = mdr.getUid(null, appDesc); return mdr.getDependencies(oosUid); } } catch (QuickFixException qfe) { DefDescriptor<ComponentDef> qfeDescriptor; // // A quickfix exception means that we couldn't compile something. // In this case, we still want to preload things, but we want to preload // quick fix values, note that we force NoCache here. // setNoCache(response); qfeDescriptor = definitionService.getDefDescriptor("markup://auradev:quickFixException", ComponentDef.class); context.setLoadingApplicationDescriptor(qfeDescriptor); String qfeUid; try { qfeUid = mdr.getUid(null, qfeDescriptor); } catch (QuickFixException death) { // // Ok, we really can't handle this here, so just punt. This means that // the quickfix display is broken, and whatever we try will give us grief. // response.sendError(HttpServletResponse.SC_NOT_FOUND); return null; } return mdr.getDependencies(qfeUid); } setLongCache(response); if (uid == null) { uid = context.getUid(appDesc); } return mdr.getDependencies(uid); }
From source file:org.xwiki.resource.servlet.AbstractServletResourceReferenceHandler.java
/** * @param resourceReference the reference of the requested resource * @return {@code true} if the requested resource is static and is cached by the browser, {@code false} if the * browser should discard the cached version and use the new version from this response *//* w ww .j av a 2 s . co m*/ private boolean shouldBrowserUseCachedContent(R resourceReference) { // If the request contains an "If-Modified-Since" header and the requested resource has not been modified then // return a 304 Not Modified to tell the browser to use its cached version. Request request = this.container.getRequest(); if (request instanceof ServletRequest && ((ServletRequest) request).getHttpServletRequest().getHeader("If-Modified-Since") != null && isResourceCacheable(resourceReference)) { // The user probably used F5 to reload the page and the browser checks if there are changes. Response response = this.container.getResponse(); if (response instanceof ServletResponse) { // Return the 304 Not Modified. ((ServletResponse) response).getHttpServletResponse() .setStatus(HttpServletResponse.SC_NOT_MODIFIED); return true; } } return false; }
From source file:eionet.eunis.servlets.DownloadServlet.java
/** * Process the actual request.//from w w w. j a v a2s. 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. * @throws ServletException */ private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException, ServletException { String requestURI = request.getRequestURI(); String contextPath = request.getContextPath(); String pathInfo = request.getPathInfo(); String servletPath = request.getServletPath(); // Create the abstract file reference to the requested file. File file = null; String fileRelativePath = StringUtils.substringAfter(request.getRequestURI(), request.getContextPath()); fileRelativePath = StringUtils.replace(fileRelativePath, "%20", " "); if (StringUtils.isNotEmpty(fileRelativePath) && StringUtils.isNotEmpty(appHome)) { file = new File(appHome, fileRelativePath); } // If file was not found, send 404. if (file == null || !file.exists() || file.isDirectory()) { 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; // Validate request headers for caching --------------------------------------------------- // If-None-Match header should contain "*" or ETag. If so, then return 304. String ifNoneMatch = request.getHeader("If-None-Match"); if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) { response.setHeader("ETag", eTag); // Required in 304. response.sendError(HttpServletResponse.SC_NOT_MODIFIED); return; } // If-Modified-Since header should be greater than LastModified. If so, then return 304. // This header is ignored if any If-None-Match header is specified. long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) { response.setHeader("ETag", eTag); // Required in 304. response.sendError(HttpServletResponse.SC_NOT_MODIFIED); return; } // Validate request headers for resume ---------------------------------------------------- // If-Match header should contain "*" or ETag. If not, then return 412. String ifMatch = request.getHeader("If-Match"); if (ifMatch != null && !matches(ifMatch, eTag)) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // If-Unmodified-Since header should be greater than LastModified. If not, then return 412. long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since"); if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // Validate and process range ------------------------------------------------------------- // Prepare some variables. The full Range represents the complete file. Range full = new Range(0, length - 1, length); List<Range> ranges = new ArrayList<Range>(); // Validate and process Range and If-Range headers. String range = request.getHeader("Range"); if (range != null) { // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416. if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) { response.setHeader("Content-Range", "bytes */" + length); // Required in 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // If-Range header should either match ETag or be greater then LastModified. If not, // then return full file. String ifRange = request.getHeader("If-Range"); if (ifRange != null && !ifRange.equals(eTag)) { try { long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid. if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) { ranges.add(full); } } catch (IllegalArgumentException ignore) { ranges.add(full); } } // If any valid If-Range header, then process each part of byte range. if (ranges.isEmpty()) { for (String part : range.substring(6).split(",")) { // Assuming a file with length of 100, the following examples returns bytes at: // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100). long start = sublong(part, 0, part.indexOf("-")); long end = sublong(part, part.indexOf("-") + 1, part.length()); if (start == -1) { start = length - end; end = length - 1; } else if (end == -1 || end > length - 1) { end = length - 1; } // Check if Range is syntactically valid. If not, then return 416. if (start > end) { response.setHeader("Content-Range", "bytes */" + length); // Required in 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // Add range. ranges.add(new Range(start, end, length)); } } } // Prepare and initialize response -------------------------------------------------------- // Get content type by file name and set default GZIP support and content disposition. String contentType = getServletContext().getMimeType(fileName); boolean acceptsGzip = false; String disposition = "inline"; // If content type is unknown, then set the default value. // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp // To add new content types, add new mime-mapping entry in web.xml. if (contentType == null) { contentType = "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. // Else, expect for images, determine content disposition. If content type is supported by // the browser, then set to inline, else attachment which will pop a 'save as' dialogue. if (contentType.startsWith("text")) { String acceptEncoding = request.getHeader("Accept-Encoding"); acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip"); contentType += ";charset=UTF-8"; } else if (!contentType.startsWith("image")) { String accept = request.getHeader("Accept"); disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment"; } // Initialize response. response.reset(); response.setBufferSize(DEFAULT_BUFFER_SIZE); response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\""); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("ETag", eTag); response.setDateHeader("Last-Modified", lastModified); response.setDateHeader("Expires", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME); // Send requested file (part(s)) to client ------------------------------------------------ // Prepare streams. RandomAccessFile input = null; OutputStream output = null; try { // Open streams. input = new RandomAccessFile(file, "r"); output = response.getOutputStream(); if (ranges.isEmpty() || ranges.get(0) == full) { // Return full file. Range r = full; response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); if (content) { if (acceptsGzip) { // The browser accepts GZIP, so GZIP the content. response.setHeader("Content-Encoding", "gzip"); output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE); } else { // Content length is not directly predictable in case of GZIP. // So only add it if there is no means of GZIP, else browser will hang. response.setHeader("Content-Length", String.valueOf(r.length)); } // Copy full range. copy(input, output, r.start, r.length); } } else if (ranges.size() == 1) { // Return single part of file. Range r = ranges.get(0); response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); response.setHeader("Content-Length", String.valueOf(r.length)); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Copy single part range. copy(input, output, r.start, r.length); } } else { // Return multiple parts of file. response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Cast back to ServletOutputStream to get the easy println methods. ServletOutputStream sos = (ServletOutputStream) output; // Copy multi part range. for (Range r : ranges) { // Add multipart boundary and header fields for every range. sos.println(); sos.println("--" + MULTIPART_BOUNDARY); sos.println("Content-Type: " + contentType); sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total); // Copy single part range of multi part range. copy(input, output, r.start, r.length); } // End with multipart boundary. sos.println(); sos.println("--" + MULTIPART_BOUNDARY + "--"); } } } finally { // Gently close streams. close(output); close(input); } }
From source file:org.geowebcache.util.ResponseUtils.java
/** * Happy ending, sets the headers and writes the response back to the client. *//*from ww w . j a va 2 s. c o m*/ private static void writeData(ConveyorTile tile, RuntimeStats runtimeStats) throws IOException { HttpServletResponse servletResp = tile.servletResp; final HttpServletRequest servletReq = tile.servletReq; final CacheResult cacheResult = tile.getCacheResult(); int httpCode = HttpServletResponse.SC_OK; Resource blob = tile.getBlob(); String mimeType = tile.getMimeType().getMimeType(blob); 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, runtimeStats); }
From source file:org.niord.proxy.web.ETagServletFilter.java
/** * Inspired by javax.ws.rs.core.Request.evaluatePreconditions(). * Evaluate request preconditions based on the passed in value. * * @param etag an ETag for the current state of the resource * @return if the preconditions are met. */// www.ja v a 2 s . c o m private boolean evaluatePreconditions(EntityTag etag, HttpServletRequest request, HttpServletResponse response) { if (etag == null) { return false; } response.setHeader(HEADER_ETAG, etag.toString()); boolean match = Collections.list(request.getHeaders(HEADER_IF_NONE_MATCH)).stream().map(this::trimEtagValue) // Strip any "-gzip" suffix added by Apache modules .anyMatch(val -> val.equals(etag.toString())); if (match) { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return true; } // No matching etag headers return false; }
From source file:com.codename1.corsproxy.CORSProxy.java
protected boolean doResponseRedirectOrNotModifiedLogic(HttpServletRequest servletRequest, HttpServletResponse servletResponse, HttpResponse proxyResponse, int statusCode) throws ServletException, IOException { // 304 needs special handling. See: // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304 // We get a 304 whenever passed an 'If-Modified-Since' // header and the data on disk has not changed; server // responds w/ a 304 saying I'm not going to send the // body because the file has not changed. if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) { servletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH, 0); servletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return true; }//www .j ava2 s . c o m return false; }
From source file:eionet.gdem.web.FileDownloadServlet.java
/** * Process the actual request.// w ww .j a v a2 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. * @throws ServletException If an error occurs. */ private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content) throws IOException, ServletException { String urlPath = URLDecoder .decode(StringUtils.substringAfter(request.getRequestURI(), request.getContextPath()), "UTF-8"); String filePath = Properties.appRootFolder + urlPath; String securityMessage = checkPermissions(request, urlPath); if (securityMessage != null) { handleNotAuthorised(securityMessage, request, response); return; } // Get the file object from the file store File file = new File(filePath); // If file was not found, send 404. if (file == null || !file.exists() || !file.isFile()) { handleFileNotFound("Could not find file by the following URI: " + request.getRequestURI(), request, response); return; } // Prepare some variables. The ETag is an unique identifier of the file. String fileName = file.getName(); long length = file.length(); long lastModified = file.lastModified(); String eTag = fileName + "_" + length + "_" + lastModified; // Validate request headers for caching --------------------------------------------------- // If-None-Match header should contain "*" or ETag. If so, then return 304. String ifNoneMatch = request.getHeader("If-None-Match"); if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) { response.setHeader("ETag", eTag); // Required in 304. response.sendError(HttpServletResponse.SC_NOT_MODIFIED); return; } // If-Modified-Since header should be greater than LastModified. If so, then return 304. // This header is ignored if any If-None-Match header is specified. long ifModifiedSince = request.getDateHeader("If-Modified-Since"); if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) { response.setHeader("ETag", eTag); // Required in 304. response.sendError(HttpServletResponse.SC_NOT_MODIFIED); return; } // Validate request headers for resume ---------------------------------------------------- // If-Match header should contain "*" or ETag. If not, then return 412. String ifMatch = request.getHeader("If-Match"); if (ifMatch != null && !matches(ifMatch, eTag)) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // If-Unmodified-Since header should be greater than LastModified. If not, then return 412. long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since"); if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) { response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); return; } // Validate and process range ------------------------------------------------------------- // Prepare some variables. The full Range represents the complete file. Range full = new Range(0, length - 1, length); List<Range> ranges = new ArrayList<Range>(); // Validate and process Range and If-Range headers. String range = request.getHeader("Range"); if (range != null) { // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416. if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) { response.setHeader("Content-Range", "bytes */" + length); // Required in 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // If-Range header should either match ETag or be greater then LastModified. If not, // then return full file. String ifRange = request.getHeader("If-Range"); if (ifRange != null && !ifRange.equals(eTag)) { try { long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid. if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) { ranges.add(full); } } catch (IllegalArgumentException ignore) { ranges.add(full); } } // If any valid If-Range header, then process each part of byte range. if (ranges.isEmpty()) { for (String part : range.substring(6).split(",")) { // Assuming a file with length of 100, the following examples returns bytes at: // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100). long start = sublong(part, 0, part.indexOf("-")); long end = sublong(part, part.indexOf("-") + 1, part.length()); if (start == -1) { start = length - end; end = length - 1; } else if (end == -1 || end > length - 1) { end = length - 1; } // Check if Range is syntactically valid. If not, then return 416. if (start > end) { response.setHeader("Content-Range", "bytes */" + length); // Required in 416. response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return; } // Add range. ranges.add(new Range(start, end, length)); } } } // Prepare and initialize response -------------------------------------------------------- // Get content type by file name and set default GZIP support and content disposition. String contentType = getServletContext().getMimeType(fileName); boolean acceptsGzip = false; String disposition = "inline"; // If content type is unknown, then set the default value. // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp // To add new content types, add new mime-mapping entry in web.xml. if (contentType == null) { contentType = "text/plain"; } // If content type is text, then determine whether GZIP content encoding is supported by // the browser and expand content type with the one and right character encoding. // Else, expect for images, determine content disposition. If content type is supported by // the browser, then set to inline, else attachment which will pop a 'save as' dialogue. if (contentType.startsWith("text")) { String acceptEncoding = request.getHeader("Accept-Encoding"); acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip"); contentType += ";charset=UTF-8"; } else if (!contentType.startsWith("image")) { String accept = request.getHeader("Accept"); disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment"; } // Initialize response. response.reset(); response.setBufferSize(DEFAULT_BUFFER_SIZE); response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\""); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("ETag", eTag); response.setDateHeader("Last-Modified", lastModified); response.setDateHeader("Expires", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME); // Send requested file (part(s)) to client ------------------------------------------------ // Prepare streams. RandomAccessFile input = null; OutputStream output = null; try { // Open streams. input = new RandomAccessFile(file, "r"); output = response.getOutputStream(); if (ranges.isEmpty() || ranges.get(0) == full) { // Return full file. Range r = full; response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); if (content) { if (acceptsGzip) { // The browser accepts GZIP, so GZIP the content. response.setHeader("Content-Encoding", "gzip"); output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE); } else { // Content length is not directly predictable in case of GZIP. // So only add it if there is no means of GZIP, else browser will hang. response.setHeader("Content-Length", String.valueOf(r.length)); } // Copy full range. copy(input, output, r.start, r.length); } } else if (ranges.size() == 1) { // Return single part of file. Range r = ranges.get(0); response.setContentType(contentType); response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total); response.setHeader("Content-Length", String.valueOf(r.length)); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Copy single part range. copy(input, output, r.start, r.length); } } else { // Return multiple parts of file. response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206. if (content) { // Cast back to ServletOutputStream to get the easy println methods. ServletOutputStream sos = (ServletOutputStream) output; // Copy multi part range. for (Range r : ranges) { // Add multipart boundary and header fields for every range. sos.println(); sos.println("--" + MULTIPART_BOUNDARY); sos.println("Content-Type: " + contentType); sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total); // Copy single part range of multi part range. copy(input, output, r.start, r.length); } // End with multipart boundary. sos.println(); sos.println("--" + MULTIPART_BOUNDARY + "--"); } } } finally { // Gently close streams. close(output); close(input); } }
From source file:org.jtalks.jcommune.web.controller.AvatarController.java
/** * Write user avatar in response for rendering it on html pages. * * @param request servlet request//from ww w .ja va2 s .c om * @param response servlet response * @param id user database identifier * @throws NotFoundException if user with given encodedUsername not found * @throws IOException throws if an output exception occurred */ @RequestMapping(value = "/users/{id}/avatar", method = RequestMethod.GET) public void renderAvatar(HttpServletRequest request, HttpServletResponse response, @PathVariable Long id) throws NotFoundException, IOException { JCUser user = userService.get(id); Date ifModifiedDate = super.getIfModifiedSinceDate(request.getHeader(IF_MODIFIED_SINCE_HEADER)); // using 0 unix time if avatar has never changed (the date is null). It's easier to work with something // non-null than to check for null all the time. DateTime avatarLastModificationTime = defaultIfNull(user.getAvatarLastModificationTime(), new DateTime(0)); // if-modified-since header doesn't include milliseconds, so if it floors the value (millis = 0), then // actual modification date will always be after the if-modified-since and we'll always be returning avatar avatarLastModificationTime = avatarLastModificationTime.withMillisOfSecond(0); if (avatarLastModificationTime.isAfter(ifModifiedDate.getTime())) { byte[] avatar = user.getAvatar(); response.setContentType("image/jpeg"); response.setContentLength(avatar.length); response.getOutputStream().write(avatar); } else { response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } setupAvatarHeaders(response, new Date(avatarLastModificationTime.getMillis())); }