List of usage examples for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT
int SC_PARTIAL_CONTENT
To view the source code for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT.
Click Source Link
From source file:org.sakaiproject.content.impl.BaseContentService.java
/** * Process the access request for a resource. * // www . j a v a 2 s.com * @param req * @param req * @param res * @param ref * @param copyrightAcceptedRefs * @throws PermissionException * @throws IdUnusedException * @throws ServerOverloadException * @throws CopyrightException */ protected void handleAccessResource(HttpServletRequest req, HttpServletResponse res, Reference ref, Collection<String> copyrightAcceptedRefs) throws EntityPermissionException, EntityNotDefinedException, EntityAccessOverloadException, EntityCopyrightException { // we only access resources, not collections if (ref.getId().endsWith(Entity.SEPARATOR)) throw new EntityNotDefinedException(ref.getReference()); // need read permission if (!allowGetResource(ref.getId())) throw new EntityPermissionException(sessionManager.getCurrentSessionUserId(), AUTH_RESOURCE_READ, ref.getReference()); ContentResource resource = null; try { resource = getResource(ref.getId()); } catch (IdUnusedException e) { throw new EntityNotDefinedException(e.getId()); } catch (PermissionException e) { throw new EntityPermissionException(e.getUser(), e.getLock(), e.getResource()); } catch (TypeException e) { throw new EntityNotDefinedException(ref.getReference()); } // if this entity requires a copyright agreement, and has not yet been set, get one if (((BaseResourceEdit) resource).requiresCopyrightAgreement() && !copyrightAcceptedRefs.contains(resource.getReference())) { throw new EntityCopyrightException(ref.getReference()); } // Wrap up the resource if we need to. resource = m_contentFilterService.wrap(resource); // Set some headers to tell browsers to revalidate and check for updated files res.addHeader("Cache-Control", "must-revalidate, private"); res.addHeader("Expires", "-1"); try { long len = resource.getContentLength(); String contentType = resource.getContentType(); ResourceProperties rp = resource.getProperties(); long lastModTime = 0; try { Time modTime = rp.getTimeProperty(ResourceProperties.PROP_MODIFIED_DATE); lastModTime = modTime.getTime(); } catch (Exception e1) { M_log.info("Could not retrieve modified time for: " + resource.getId()); } // KNL-1316 tell the browser when our file was last modified for caching reasons if (lastModTime > 0) { SimpleDateFormat rfc1123Date = new SimpleDateFormat(RFC1123_DATE, LOCALE_US); rfc1123Date.setTimeZone(TimeZone.getTimeZone("GMT")); res.addHeader("Last-Modified", rfc1123Date.format(lastModTime)); } // for url content type, encode a redirect to the body URL if (contentType.equalsIgnoreCase(ResourceProperties.TYPE_URL)) { if (len < MAX_URL_LENGTH) { byte[] content = resource.getContent(); if ((content == null) || (content.length == 0)) { throw new IdUnusedException(ref.getReference()); } // An invalid URI format will get caught by the outermost catch block URI uri = new URI(new String(content, "UTF-8")); eventTrackingService.post( eventTrackingService.newEvent(EVENT_RESOURCE_READ, resource.getReference(null), false)); //SAK-23587 process any macros present in this URL String decodedUrl = URLDecoder.decode(uri.toString(), "UTF-8"); decodedUrl = expandMacros(decodedUrl); res.sendRedirect(decodedUrl); } else { // we have a text/url mime type, but the body is too long to issue as a redirect throw new EntityNotDefinedException(ref.getReference()); } } else { // use the last part, the file name part of the id, for the download file name String fileName = Validator.getFileName(ref.getId()); String disposition = null; if (Validator.letBrowserInline(contentType)) { // if this is an html file we have more checks String lcct = contentType.toLowerCase(); if ((lcct.startsWith("text/") || lcct.startsWith("image/") || lcct.contains("html") || lcct.contains("script")) && m_serverConfigurationService.getBoolean(SECURE_INLINE_HTML, true)) { // increased checks to handle more mime-types - https://jira.sakaiproject.org/browse/KNL-749 boolean fileInline = false; boolean folderInline = false; try { fileInline = rp.getBooleanProperty(ResourceProperties.PROP_ALLOW_INLINE); } catch (EntityPropertyNotDefinedException e) { // we expect this so nothing to do! } if (!fileInline) try { folderInline = resource.getContainingCollection().getProperties() .getBooleanProperty(ResourceProperties.PROP_ALLOW_INLINE); } catch (EntityPropertyNotDefinedException e) { // we expect this so nothing to do! } if (fileInline || folderInline) { disposition = Web.buildContentDisposition(fileName, false); } } else { disposition = Web.buildContentDisposition(fileName, false); } } // drop through to attachment if (disposition == null) { disposition = Web.buildContentDisposition(fileName, true); } // NOTE: Only set the encoding on the content we have to. // Files uploaded by the user may have been created with different encodings, such as ISO-8859-1; // rather than (sometimes wrongly) saying its UTF-8, let the browser auto-detect the encoding. // If the content was created through the WYSIWYG editor, the encoding does need to be set (UTF-8). String encoding = resource.getProperties().getProperty(ResourceProperties.PROP_CONTENT_ENCODING); if (encoding != null && encoding.length() > 0) { contentType = contentType + "; charset=" + encoding; } // KNL-1316 let's see if the user already has a cached copy. Code copied and modified from Tomcat DefaultServlet.java long headerValue = req.getDateHeader("If-Modified-Since"); if (headerValue != -1 && (lastModTime < headerValue + 1000)) { // The entity has not been modified since the date specified by the client. This is not an error case. res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); return; } ArrayList<Range> ranges = parseRange(req, res, len); res.addHeader("Accept-Ranges", "bytes"); if (req.getHeader("Range") == null || (ranges == null) || (ranges.isEmpty())) { // stream the content using a small buffer to keep memory managed InputStream content = null; OutputStream out = null; try { content = resource.streamContent(); if (content == null) { throw new IdUnusedException(ref.getReference()); } res.setContentType(contentType); res.addHeader("Content-Disposition", disposition); // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4187336 if (len <= Integer.MAX_VALUE) { res.setContentLength((int) len); } else { res.addHeader("Content-Length", Long.toString(len)); } // set the buffer of the response to match what we are reading from the request if (len < STREAM_BUFFER_SIZE) { res.setBufferSize((int) len); } else { res.setBufferSize(STREAM_BUFFER_SIZE); } out = res.getOutputStream(); copyRange(content, out, 0, len - 1); } catch (ServerOverloadException e) { throw e; } catch (Exception ignore) { } finally { // be a good little program and close the stream - freeing up valuable system resources if (content != null) { content.close(); } if (out != null) { try { out.close(); } catch (Exception ignore) { } } } // Track event - only for full reads eventTrackingService.post( eventTrackingService.newEvent(EVENT_RESOURCE_READ, resource.getReference(null), false)); } else { // Output partial content. Adapted from Apache Tomcat 5.5.27 DefaultServlet.java res.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); if (ranges.size() == 1) { // Single response Range range = (Range) ranges.get(0); res.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length); long length = range.end - range.start + 1; if (length < Integer.MAX_VALUE) { res.setContentLength((int) length); } else { // Set the content-length as String to be able to use a long res.setHeader("content-length", "" + length); } res.addHeader("Content-Disposition", disposition); if (contentType != null) { res.setContentType(contentType); } // stream the content using a small buffer to keep memory managed InputStream content = null; OutputStream out = null; try { content = resource.streamContent(); if (content == null) { throw new IdUnusedException(ref.getReference()); } // set the buffer of the response to match what we are reading from the request if (len < STREAM_BUFFER_SIZE) { res.setBufferSize((int) len); } else { res.setBufferSize(STREAM_BUFFER_SIZE); } out = res.getOutputStream(); copyRange(content, out, range.start, range.end); } catch (ServerOverloadException e) { throw e; } catch (SocketException e) { //a socket exception usualy means the client aborted the connection or similar if (M_log.isDebugEnabled()) { M_log.debug("SocketExcetion", e); } } catch (Exception ignore) { } finally { // be a good little program and close the stream - freeing up valuable system resources if (content != null) { content.close(); } if (out != null) { try { out.close(); } catch (IOException ignore) { // ignore } } } } else { // Multipart response res.setContentType("multipart/byteranges; boundary=" + MIME_SEPARATOR); // stream the content using a small buffer to keep memory managed OutputStream out = null; try { // set the buffer of the response to match what we are reading from the request if (len < STREAM_BUFFER_SIZE) { res.setBufferSize((int) len); } else { res.setBufferSize(STREAM_BUFFER_SIZE); } out = res.getOutputStream(); copyRanges(resource, out, ranges.iterator(), contentType); } catch (SocketException e) { //a socket exception usualy means the client aborted the connection or similar if (M_log.isDebugEnabled()) { M_log.debug("SocketExcetion", e); } } catch (Exception ignore) { M_log.error("Swallowing exception", ignore); } finally { // be a good little program and close the stream - freeing up valuable system resources if (out != null) { try { out.close(); } catch (IOException ignore) { // ignore } } } } // output multiple ranges } // output partial content } // output resource } catch (Exception t) { throw new EntityNotDefinedException(ref.getReference(), t); } }