Example usage for javax.servlet.http HttpServletResponse SC_PARTIAL_CONTENT

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

Introduction

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

Prototype

int SC_PARTIAL_CONTENT

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

Click Source Link

Document

Status code (206) indicating that the server has fulfilled the partial GET request for the resource.

Usage

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);
    }
}