List of usage examples for org.springframework.http HttpHeaders RANGE
String RANGE
To view the source code for org.springframework.http HttpHeaders RANGE.
Click Source Link
From source file:com.github.zhanhb.ckfinder.download.PathPartial.java
/** * Parse the range header./* w w w . j av a 2 s. c o m*/ * * @param request The servlet request we are processing * @param response The servlet response we are creating * @param attr File attributes * @param etag ETag of the entity * @return array of ranges */ @Nullable @SuppressWarnings("ReturnOfCollectionOrArrayField") private Range[] parseRange(HttpServletRequest request, HttpServletResponse response, BasicFileAttributes attr, String etag) throws IOException { // Checking If-Range String headerValue = request.getHeader(HttpHeaders.IF_RANGE); if (headerValue != null) { long headerValueTime = -1; try { headerValueTime = request.getDateHeader(HttpHeaders.IF_RANGE); } catch (IllegalArgumentException e) { // Ignore } // If the ETag the client gave does not match the entity // eTag, then the entire entity is returned. if (headerValueTime == -1 && !headerValue.trim().equals(etag) || attr.lastModifiedTime().toMillis() > headerValueTime + 1000) { // If the timestamp of the entity the client got is older than // the last modification date of the entity, the entire entity // is returned. return FULL; } } long fileLength = attr.size(); if (fileLength == 0) { return FULL; } // Retrieving the range header (if any is specified String rangeHeader = request.getHeader(HttpHeaders.RANGE); if (rangeHeader == null) { return FULL; } // bytes is the only range unit supported (and I don't see the point // of adding new ones). if (!rangeHeader.startsWith("bytes=")) { return FULL; } // List which will contain all the ranges which are successfully // parsed. List<Range> result = new ArrayList<>(4); // Parsing the range list // "bytes=".length() = 6 for (int index, last = 6;; last = index + 1) { index = rangeHeader.indexOf(',', last); boolean isLast = index == -1; final String rangeDefinition = (isLast ? rangeHeader.substring(last) : rangeHeader.substring(last, index)).trim(); final int dashPos = rangeDefinition.indexOf('-'); if (dashPos == -1) { break; } final Range currentRange = new Range(fileLength); try { if (dashPos == 0) { final long offset = Long.parseLong(rangeDefinition); if (offset == 0) { // -0, --0 break; } currentRange.start = Math.max(fileLength + offset, 0); } else { currentRange.start = Long.parseLong(rangeDefinition.substring(0, dashPos)); if (dashPos < rangeDefinition.length() - 1) { currentRange.end = Long .parseLong(rangeDefinition.substring(dashPos + 1, rangeDefinition.length())); } } } catch (NumberFormatException e) { break; } if (!currentRange.validate()) { break; } result.add(currentRange); if (isLast) { int size = result.size(); if (size == 0) { break; } return result.toArray(new Range[size]); } } response.addHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + fileLength); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); return null; }
From source file:bjerne.gallery.controller.GalleryController.java
/** * Method used to return the binary of a gallery file ( * {@link GalleryFile#getActualFile()} ). This method handles 304 redirects * (if file has not changed) and range headers if requested by browser. The * range parts is particularly important for videos. The correct response * status is set depending on the circumstances. * <p>/*from w w w . j a v a 2 s .c om*/ * NOTE: the range logic should NOT be considered a complete implementation * - it's a bare minimum for making requests for byte ranges work. * * @param request * Request * @param galleryFile * Gallery file * @return The binary of the gallery file, or a 304 redirect, or a part of * the file. * @throws IOException * If there is an issue accessing the binary file. */ private ResponseEntity<InputStreamResource> returnResource(WebRequest request, GalleryFile galleryFile) throws IOException { LOG.debug("Entering returnResource()"); if (request.checkNotModified(galleryFile.getActualFile().lastModified())) { return null; } File file = galleryFile.getActualFile(); String contentType = galleryFile.getContentType(); String rangeHeader = request.getHeader(HttpHeaders.RANGE); long[] ranges = getRangesFromHeader(rangeHeader); long startPosition = ranges[0]; long fileTotalSize = file.length(); long endPosition = ranges[1] != 0 ? ranges[1] : fileTotalSize - 1; long contentLength = endPosition - startPosition + 1; LOG.debug("contentLength: {}, file length: {}", contentLength, fileTotalSize); LOG.debug("Returning resource {} as inputstream. Start position: {}", file.getCanonicalPath(), startPosition); InputStream boundedInputStream = new BoundedInputStream(new FileInputStream(file), endPosition + 1); InputStream is = new BufferedInputStream(boundedInputStream, 65536); InputStreamResource inputStreamResource = new InputStreamResource(is); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(contentLength); responseHeaders.setContentType(MediaType.valueOf(contentType)); responseHeaders.add(HttpHeaders.ACCEPT_RANGES, "bytes"); if (StringUtils.isNotBlank(rangeHeader)) { is.skip(startPosition); String contentRangeResponseHeader = "bytes " + startPosition + "-" + endPosition + "/" + fileTotalSize; responseHeaders.add(HttpHeaders.CONTENT_RANGE, contentRangeResponseHeader); LOG.debug("{} was not null but {}. Adding header {} to response: {}", HttpHeaders.RANGE, rangeHeader, HttpHeaders.CONTENT_RANGE, contentRangeResponseHeader); } HttpStatus status = (startPosition == 0 && contentLength == fileTotalSize) ? HttpStatus.OK : HttpStatus.PARTIAL_CONTENT; LOG.debug("Returning {}. Status: {}, content-type: {}, {}: {}, contentLength: {}", file, status, contentType, HttpHeaders.CONTENT_RANGE, responseHeaders.get(HttpHeaders.CONTENT_RANGE), contentLength); return new ResponseEntity<InputStreamResource>(inputStreamResource, responseHeaders, status); }
From source file:org.springframework.web.servlet.resource.ResourceHttpRequestHandler.java
/** * Processes a resource request./*from ww w . java 2 s .c o m*/ * <p>Checks for the existence of the requested resource in the configured list of locations. * If the resource does not exist, a {@code 404} response will be returned to the client. * If the resource exists, the request will be checked for the presence of the * {@code Last-Modified} header, and its value will be compared against the last-modified * timestamp of the given resource, returning a {@code 304} status code if the * {@code Last-Modified} value is greater. If the resource is newer than the * {@code Last-Modified} value, or the header is not present, the content resource * of the resource will be written to the response with caching headers * set to expire one year in the future. */ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // For very general mappings (e.g. "/") we need to check 404 first Resource resource = getResource(request); if (resource == null) { logger.trace("No matching resource found - returning 404"); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (HttpMethod.OPTIONS.matches(request.getMethod())) { response.setHeader("Allow", getAllowHeader()); return; } // Supported methods and required session checkRequest(request); // Header phase if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) { logger.trace("Resource not modified - returning 304"); return; } // Apply cache settings, if any prepareResponse(response); // Check the media type for the resource MediaType mediaType = getMediaType(request, resource); if (mediaType != null) { if (logger.isTraceEnabled()) { logger.trace("Determined media type '" + mediaType + "' for " + resource); } } else { if (logger.isTraceEnabled()) { logger.trace("No media type found for " + resource + " - not sending a content-type header"); } } // Content phase if (METHOD_HEAD.equals(request.getMethod())) { setHeaders(response, resource, mediaType); logger.trace("HEAD request - skipping content"); return; } ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response); if (request.getHeader(HttpHeaders.RANGE) == null) { Assert.state(this.resourceHttpMessageConverter != null, "Not initialized"); setHeaders(response, resource, mediaType); this.resourceHttpMessageConverter.write(resource, mediaType, outputMessage); } else { Assert.state(this.resourceRegionHttpMessageConverter != null, "Not initialized"); response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes"); ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(request); try { List<HttpRange> httpRanges = inputMessage.getHeaders().getRange(); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); this.resourceRegionHttpMessageConverter.write(HttpRange.toResourceRegions(httpRanges, resource), mediaType, outputMessage); } catch (IllegalArgumentException ex) { response.setHeader("Content-Range", "bytes */" + resource.contentLength()); response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); } } }