Search in sources :

Example 31 with WebResource

use of org.apache.catalina.WebResource in project tomcat by apache.

the class WebdavStatus method doPropfind.

/**
     * PROPFIND Method.
     * @param req The Servlet request
     * @param resp The Servlet response
     * @throws ServletException If an error occurs
     * @throws IOException If an IO error occurs
     */
protected void doPropfind(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    if (!listings) {
        // Get allowed methods
        StringBuilder methodsAllowed = determineMethodsAllowed(req);
        resp.addHeader("Allow", methodsAllowed.toString());
        resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
        return;
    }
    String path = getRelativePath(req);
    if (path.length() > 1 && path.endsWith("/"))
        path = path.substring(0, path.length() - 1);
    // Properties which are to be displayed.
    Vector<String> properties = null;
    // Propfind depth
    int depth = maxDepth;
    // Propfind type
    int type = FIND_ALL_PROP;
    String depthStr = req.getHeader("Depth");
    if (depthStr == null) {
        depth = maxDepth;
    } else {
        if (depthStr.equals("0")) {
            depth = 0;
        } else if (depthStr.equals("1")) {
            depth = 1;
        } else if (depthStr.equals("infinity")) {
            depth = maxDepth;
        }
    }
    Node propNode = null;
    if (req.getContentLengthLong() > 0) {
        DocumentBuilder documentBuilder = getDocumentBuilder();
        try {
            Document document = documentBuilder.parse(new InputSource(req.getInputStream()));
            // Get the root element of the document
            Element rootElement = document.getDocumentElement();
            NodeList childList = rootElement.getChildNodes();
            for (int i = 0; i < childList.getLength(); i++) {
                Node currentNode = childList.item(i);
                switch(currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        break;
                    case Node.ELEMENT_NODE:
                        if (currentNode.getNodeName().endsWith("prop")) {
                            type = FIND_BY_PROPERTY;
                            propNode = currentNode;
                        }
                        if (currentNode.getNodeName().endsWith("propname")) {
                            type = FIND_PROPERTY_NAMES;
                        }
                        if (currentNode.getNodeName().endsWith("allprop")) {
                            type = FIND_ALL_PROP;
                        }
                        break;
                }
            }
        } catch (SAXException e) {
            // Something went wrong - bad request
            resp.sendError(WebdavStatus.SC_BAD_REQUEST);
            return;
        } catch (IOException e) {
            // Something went wrong - bad request
            resp.sendError(WebdavStatus.SC_BAD_REQUEST);
            return;
        }
    }
    if (type == FIND_BY_PROPERTY) {
        properties = new Vector<>();
        // propNode must be non-null if type == FIND_BY_PROPERTY
        @SuppressWarnings("null") NodeList childList = propNode.getChildNodes();
        for (int i = 0; i < childList.getLength(); i++) {
            Node currentNode = childList.item(i);
            switch(currentNode.getNodeType()) {
                case Node.TEXT_NODE:
                    break;
                case Node.ELEMENT_NODE:
                    String nodeName = currentNode.getNodeName();
                    String propertyName = null;
                    if (nodeName.indexOf(':') != -1) {
                        propertyName = nodeName.substring(nodeName.indexOf(':') + 1);
                    } else {
                        propertyName = nodeName;
                    }
                    // href is a live property which is handled differently
                    properties.addElement(propertyName);
                    break;
            }
        }
    }
    WebResource resource = resources.getResource(path);
    if (!resource.exists()) {
        int slash = path.lastIndexOf('/');
        if (slash != -1) {
            String parentPath = path.substring(0, slash);
            Vector<String> currentLockNullResources = lockNullResources.get(parentPath);
            if (currentLockNullResources != null) {
                Enumeration<String> lockNullResourcesList = currentLockNullResources.elements();
                while (lockNullResourcesList.hasMoreElements()) {
                    String lockNullPath = lockNullResourcesList.nextElement();
                    if (lockNullPath.equals(path)) {
                        resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
                        resp.setContentType("text/xml; charset=UTF-8");
                        // Create multistatus object
                        XMLWriter generatedXML = new XMLWriter(resp.getWriter());
                        generatedXML.writeXMLHeader();
                        generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", XMLWriter.OPENING);
                        parseLockNullProperties(req, generatedXML, lockNullPath, type, properties);
                        generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING);
                        generatedXML.sendData();
                        return;
                    }
                }
            }
        }
    }
    if (!resource.exists()) {
        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
        return;
    }
    resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
    resp.setContentType("text/xml; charset=UTF-8");
    // Create multistatus object
    XMLWriter generatedXML = new XMLWriter(resp.getWriter());
    generatedXML.writeXMLHeader();
    generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", XMLWriter.OPENING);
    if (depth == 0) {
        parseProperties(req, generatedXML, path, type, properties);
    } else {
        // The stack always contains the object of the current level
        Stack<String> stack = new Stack<>();
        stack.push(path);
        // Stack of the objects one level below
        Stack<String> stackBelow = new Stack<>();
        while ((!stack.isEmpty()) && (depth >= 0)) {
            String currentPath = stack.pop();
            parseProperties(req, generatedXML, currentPath, type, properties);
            resource = resources.getResource(currentPath);
            if (resource.isDirectory() && (depth > 0)) {
                String[] entries = resources.list(currentPath);
                for (String entry : entries) {
                    String newPath = currentPath;
                    if (!(newPath.endsWith("/")))
                        newPath += "/";
                    newPath += entry;
                    stackBelow.push(newPath);
                }
                // Displaying the lock-null resources present in that
                // collection
                String lockPath = currentPath;
                if (lockPath.endsWith("/"))
                    lockPath = lockPath.substring(0, lockPath.length() - 1);
                Vector<String> currentLockNullResources = lockNullResources.get(lockPath);
                if (currentLockNullResources != null) {
                    Enumeration<String> lockNullResourcesList = currentLockNullResources.elements();
                    while (lockNullResourcesList.hasMoreElements()) {
                        String lockNullPath = lockNullResourcesList.nextElement();
                        parseLockNullProperties(req, generatedXML, lockNullPath, type, properties);
                    }
                }
            }
            if (stack.isEmpty()) {
                depth--;
                stack = stackBelow;
                stackBelow = new Stack<>();
            }
            generatedXML.sendData();
        }
    }
    generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING);
    generatedXML.sendData();
}
Also used : InputSource(org.xml.sax.InputSource) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) WebResource(org.apache.catalina.WebResource) IOException(java.io.IOException) Document(org.w3c.dom.Document) XMLWriter(org.apache.catalina.util.XMLWriter) SAXException(org.xml.sax.SAXException) Stack(java.util.Stack) DocumentBuilder(javax.xml.parsers.DocumentBuilder)

Example 32 with WebResource

use of org.apache.catalina.WebResource in project tomcat by apache.

the class WebdavStatus method determineMethodsAllowed.

/**
     * Determines the methods normally allowed for the resource.
     * @param req The Servlet request
     * @return a string builder with the allowed HTTP methods
     */
private StringBuilder determineMethodsAllowed(HttpServletRequest req) {
    StringBuilder methodsAllowed = new StringBuilder();
    WebResource resource = resources.getResource(getRelativePath(req));
    if (!resource.exists()) {
        methodsAllowed.append("OPTIONS, MKCOL, PUT, LOCK");
        return methodsAllowed;
    }
    methodsAllowed.append("OPTIONS, GET, HEAD, POST, DELETE");
    // Trace - assume disabled unless we can prove otherwise
    if (req instanceof RequestFacade && ((RequestFacade) req).getAllowTrace()) {
        methodsAllowed.append(", TRACE");
    }
    methodsAllowed.append(", PROPPATCH, COPY, MOVE, LOCK, UNLOCK");
    if (listings) {
        methodsAllowed.append(", PROPFIND");
    }
    if (resource.isFile()) {
        methodsAllowed.append(", PUT");
    }
    return methodsAllowed;
}
Also used : WebResource(org.apache.catalina.WebResource) RequestFacade(org.apache.catalina.connector.RequestFacade)

Example 33 with WebResource

use of org.apache.catalina.WebResource in project tomcat by apache.

the class WebdavStatus method copyResource.

/**
     * Copy a resource.
     *
     * @param req Servlet request
     * @param resp Servlet response
     * @return boolean true if the copy is successful
     * @throws IOException If an IO error occurs
     */
private boolean copyResource(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // Parsing destination header
    String destinationPath = req.getHeader("Destination");
    if (destinationPath == null) {
        resp.sendError(WebdavStatus.SC_BAD_REQUEST);
        return false;
    }
    // Remove url encoding from destination
    destinationPath = UDecoder.URLDecode(destinationPath, "UTF8");
    int protocolIndex = destinationPath.indexOf("://");
    if (protocolIndex >= 0) {
        // if the Destination URL contains the protocol, we can safely
        // trim everything upto the first "/" character after "://"
        int firstSeparator = destinationPath.indexOf('/', protocolIndex + 4);
        if (firstSeparator < 0) {
            destinationPath = "/";
        } else {
            destinationPath = destinationPath.substring(firstSeparator);
        }
    } else {
        String hostName = req.getServerName();
        if ((hostName != null) && (destinationPath.startsWith(hostName))) {
            destinationPath = destinationPath.substring(hostName.length());
        }
        int portIndex = destinationPath.indexOf(':');
        if (portIndex >= 0) {
            destinationPath = destinationPath.substring(portIndex);
        }
        if (destinationPath.startsWith(":")) {
            int firstSeparator = destinationPath.indexOf('/');
            if (firstSeparator < 0) {
                destinationPath = "/";
            } else {
                destinationPath = destinationPath.substring(firstSeparator);
            }
        }
    }
    // Normalise destination path (remove '.' and '..')
    destinationPath = RequestUtil.normalize(destinationPath);
    String contextPath = req.getContextPath();
    if ((contextPath != null) && (destinationPath.startsWith(contextPath))) {
        destinationPath = destinationPath.substring(contextPath.length());
    }
    String pathInfo = req.getPathInfo();
    if (pathInfo != null) {
        String servletPath = req.getServletPath();
        if ((servletPath != null) && (destinationPath.startsWith(servletPath))) {
            destinationPath = destinationPath.substring(servletPath.length());
        }
    }
    if (debug > 0)
        log("Dest path :" + destinationPath);
    // Check destination path to protect special subdirectories
    if (isSpecialPath(destinationPath)) {
        resp.sendError(WebdavStatus.SC_FORBIDDEN);
        return false;
    }
    String path = getRelativePath(req);
    if (destinationPath.equals(path)) {
        resp.sendError(WebdavStatus.SC_FORBIDDEN);
        return false;
    }
    // Parsing overwrite header
    boolean overwrite = true;
    String overwriteHeader = req.getHeader("Overwrite");
    if (overwriteHeader != null) {
        if (overwriteHeader.equalsIgnoreCase("T")) {
            overwrite = true;
        } else {
            overwrite = false;
        }
    }
    // Overwriting the destination
    WebResource destination = resources.getResource(destinationPath);
    if (overwrite) {
        // Delete destination resource, if it exists
        if (destination.exists()) {
            if (!deleteResource(destinationPath, req, resp, true)) {
                return false;
            }
        } else {
            resp.setStatus(WebdavStatus.SC_CREATED);
        }
    } else {
        // If the destination exists, then it's a conflict
        if (destination.exists()) {
            resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED);
            return false;
        }
    }
    // Copying source to destination
    Hashtable<String, Integer> errorList = new Hashtable<>();
    boolean result = copyResource(errorList, path, destinationPath);
    if ((!result) || (!errorList.isEmpty())) {
        if (errorList.size() == 1) {
            resp.sendError(errorList.elements().nextElement().intValue());
        } else {
            sendReport(req, resp, errorList);
        }
        return false;
    }
    // Copy was successful
    if (destination.exists()) {
        resp.setStatus(WebdavStatus.SC_NO_CONTENT);
    } else {
        resp.setStatus(WebdavStatus.SC_CREATED);
    }
    // Removing any lock-null resource which would be present at
    // the destination path
    lockNullResources.remove(destinationPath);
    return true;
}
Also used : Hashtable(java.util.Hashtable) WebResource(org.apache.catalina.WebResource)

Example 34 with WebResource

use of org.apache.catalina.WebResource in project tomcat by apache.

the class DefaultServlet method renderHtml.

/**
     * Return an InputStream to an HTML representation of the contents of this
     * directory.
     *
     * @param contextPath Context path to which our internal paths are relative
     * @param resource    The associated resource
     * @param encoding    The encoding to use to process the readme (if any)
     *
     * @return the HTML data
     *
     * @throws IOException an IO error occurred
     */
protected InputStream renderHtml(String contextPath, WebResource resource, String encoding) throws IOException {
    // Prepare a writer to a buffered area
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8");
    PrintWriter writer = new PrintWriter(osWriter);
    StringBuilder sb = new StringBuilder();
    String[] entries = resources.list(resource.getWebappPath());
    // rewriteUrl(contextPath) is expensive. cache result for later reuse
    String rewrittenContextPath = rewriteUrl(contextPath);
    String directoryWebappPath = resource.getWebappPath();
    // Render the page header
    sb.append("<html>\r\n");
    sb.append("<head>\r\n");
    sb.append("<title>");
    sb.append(sm.getString("directory.title", directoryWebappPath));
    sb.append("</title>\r\n");
    sb.append("<STYLE><!--");
    sb.append(org.apache.catalina.util.TomcatCSS.TOMCAT_CSS);
    sb.append("--></STYLE> ");
    sb.append("</head>\r\n");
    sb.append("<body>");
    sb.append("<h1>");
    sb.append(sm.getString("directory.title", directoryWebappPath));
    // Render the link to our parent (if required)
    String parentDirectory = directoryWebappPath;
    if (parentDirectory.endsWith("/")) {
        parentDirectory = parentDirectory.substring(0, parentDirectory.length() - 1);
    }
    int slash = parentDirectory.lastIndexOf('/');
    if (slash >= 0) {
        String parent = directoryWebappPath.substring(0, slash);
        sb.append(" - <a href=\"");
        sb.append(rewrittenContextPath);
        if (parent.equals(""))
            parent = "/";
        sb.append(rewriteUrl(parent));
        if (!parent.endsWith("/"))
            sb.append("/");
        sb.append("\">");
        sb.append("<b>");
        sb.append(sm.getString("directory.parent", parent));
        sb.append("</b>");
        sb.append("</a>");
    }
    sb.append("</h1>");
    sb.append("<HR size=\"1\" noshade=\"noshade\">");
    sb.append("<table width=\"100%\" cellspacing=\"0\"" + " cellpadding=\"5\" align=\"center\">\r\n");
    // Render the column headings
    sb.append("<tr>\r\n");
    sb.append("<td align=\"left\"><font size=\"+1\"><strong>");
    sb.append(sm.getString("directory.filename"));
    sb.append("</strong></font></td>\r\n");
    sb.append("<td align=\"center\"><font size=\"+1\"><strong>");
    sb.append(sm.getString("directory.size"));
    sb.append("</strong></font></td>\r\n");
    sb.append("<td align=\"right\"><font size=\"+1\"><strong>");
    sb.append(sm.getString("directory.lastModified"));
    sb.append("</strong></font></td>\r\n");
    sb.append("</tr>");
    boolean shade = false;
    for (String entry : entries) {
        if (entry.equalsIgnoreCase("WEB-INF") || entry.equalsIgnoreCase("META-INF"))
            continue;
        WebResource childResource = resources.getResource(directoryWebappPath + entry);
        if (!childResource.exists()) {
            continue;
        }
        sb.append("<tr");
        if (shade)
            sb.append(" bgcolor=\"#eeeeee\"");
        sb.append(">\r\n");
        shade = !shade;
        sb.append("<td align=\"left\">&nbsp;&nbsp;\r\n");
        sb.append("<a href=\"");
        sb.append(rewrittenContextPath);
        sb.append(rewriteUrl(directoryWebappPath + entry));
        if (childResource.isDirectory())
            sb.append("/");
        sb.append("\"><tt>");
        sb.append(RequestUtil.filter(entry));
        if (childResource.isDirectory())
            sb.append("/");
        sb.append("</tt></a></td>\r\n");
        sb.append("<td align=\"right\"><tt>");
        if (childResource.isDirectory())
            sb.append("&nbsp;");
        else
            sb.append(renderSize(childResource.getContentLength()));
        sb.append("</tt></td>\r\n");
        sb.append("<td align=\"right\"><tt>");
        sb.append(childResource.getLastModifiedHttp());
        sb.append("</tt></td>\r\n");
        sb.append("</tr>\r\n");
    }
    // Render the page footer
    sb.append("</table>\r\n");
    sb.append("<HR size=\"1\" noshade=\"noshade\">");
    String readme = getReadme(resource, encoding);
    if (readme != null) {
        sb.append(readme);
        sb.append("<HR size=\"1\" noshade=\"noshade\">");
    }
    if (showServerInfo) {
        sb.append("<h3>").append(ServerInfo.getServerInfo()).append("</h3>");
    }
    sb.append("</body>\r\n");
    sb.append("</html>\r\n");
    // Return an input stream to the underlying bytes
    writer.write(sb.toString());
    writer.flush();
    return (new ByteArrayInputStream(stream.toByteArray()));
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) WebResource(org.apache.catalina.WebResource) OutputStreamWriter(java.io.OutputStreamWriter) ByteArrayOutputStream(java.io.ByteArrayOutputStream) PrintWriter(java.io.PrintWriter)

Example 35 with WebResource

use of org.apache.catalina.WebResource in project tomcat by apache.

the class DefaultServlet method serveResource.

/**
     * Serve the specified resource, optionally including the data content.
     *
     * @param request  The servlet request we are processing
     * @param response The servlet response we are creating
     * @param content  Should the content be included?
     * @param encoding The encoding to use if it is necessary to access the
     *                 source as characters rather than as bytes
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet-specified error occurs
     */
protected void serveResource(HttpServletRequest request, HttpServletResponse response, boolean content, String encoding) throws IOException, ServletException {
    boolean serveContent = content;
    // Identify the requested resource path
    String path = getRelativePath(request, true);
    if (debug > 0) {
        if (serveContent)
            log("DefaultServlet.serveResource:  Serving resource '" + path + "' headers and data");
        else
            log("DefaultServlet.serveResource:  Serving resource '" + path + "' headers only");
    }
    if (path.length() == 0) {
        // Context root redirect
        doDirectoryRedirect(request, response);
        return;
    }
    WebResource resource = resources.getResource(path);
    if (!resource.exists()) {
        // Check if we're included so we can return the appropriate
        // missing resource name in the error
        String requestUri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
        if (requestUri == null) {
            requestUri = request.getRequestURI();
        } else {
            // SRV.9.3 says we must throw a FNFE
            throw new FileNotFoundException(sm.getString("defaultServlet.missingResource", requestUri));
        }
        response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri);
        return;
    }
    if (!resource.canRead()) {
        // Check if we're included so we can return the appropriate
        // missing resource name in the error
        String requestUri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
        if (requestUri == null) {
            requestUri = request.getRequestURI();
        } else {
            // reasonable
            throw new FileNotFoundException(sm.getString("defaultServlet.missingResource", requestUri));
        }
        response.sendError(HttpServletResponse.SC_FORBIDDEN, requestUri);
        return;
    }
    // ends with "/" or "\", return NOT FOUND
    if (resource.isFile() && (path.endsWith("/") || path.endsWith("\\"))) {
        // Check if we're included so we can return the appropriate
        // missing resource name in the error
        String requestUri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
        if (requestUri == null) {
            requestUri = request.getRequestURI();
        }
        response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri);
        return;
    }
    boolean isError = response.getStatus() >= HttpServletResponse.SC_BAD_REQUEST;
    boolean included = false;
    // satisfied.
    if (resource.isFile()) {
        // Checking If headers
        included = (request.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH) != null);
        if (!included && !isError && !checkIfHeaders(request, response, resource)) {
            return;
        }
    }
    // Find content type.
    String contentType = resource.getMimeType();
    if (contentType == null) {
        contentType = getServletContext().getMimeType(resource.getName());
        resource.setMimeType(contentType);
    }
    // These need to reflect the original resource, not the potentially
    // precompressed version of the resource so get them now if they are going to
    // be needed later
    String eTag = null;
    String lastModifiedHttp = null;
    if (resource.isFile() && !isError) {
        eTag = resource.getETag();
        lastModifiedHttp = resource.getLastModifiedHttp();
    }
    // Serve a precompressed version of the file if present
    boolean usingPrecompressedVersion = false;
    if (compressionFormats.length > 0 && !included && resource.isFile() && !pathEndsWithCompressedExtension(path)) {
        List<PrecompressedResource> precompressedResources = getAvailablePrecompressedResources(path);
        if (!precompressedResources.isEmpty()) {
            Collection<String> varyHeaders = response.getHeaders("Vary");
            boolean addRequired = true;
            for (String varyHeader : varyHeaders) {
                if ("*".equals(varyHeader) || "accept-encoding".equalsIgnoreCase(varyHeader)) {
                    addRequired = false;
                    break;
                }
            }
            if (addRequired) {
                response.addHeader("Vary", "accept-encoding");
            }
            PrecompressedResource bestResource = getBestPrecompressedResource(request, precompressedResources);
            if (bestResource != null) {
                response.addHeader("Content-Encoding", bestResource.format.encoding);
                resource = bestResource.resource;
                usingPrecompressedVersion = true;
            }
        }
    }
    ArrayList<Range> ranges = null;
    long contentLength = -1L;
    if (resource.isDirectory()) {
        if (!path.endsWith("/")) {
            doDirectoryRedirect(request, response);
            return;
        }
        // suppress them
        if (!listings) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI());
            return;
        }
        contentType = "text/html;charset=UTF-8";
    } else {
        if (!isError) {
            if (useAcceptRanges) {
                // Accept ranges header
                response.setHeader("Accept-Ranges", "bytes");
            }
            // Parse range specifier
            ranges = parseRange(request, response, resource);
            // ETag header
            response.setHeader("ETag", eTag);
            // Last-Modified header
            response.setHeader("Last-Modified", lastModifiedHttp);
        }
        // Get content length
        contentLength = resource.getContentLength();
        // (silent) ISE when setting the output buffer size
        if (contentLength == 0L) {
            serveContent = false;
        }
    }
    ServletOutputStream ostream = null;
    PrintWriter writer = null;
    if (serveContent) {
        // Trying to retrieve the servlet output stream
        try {
            ostream = response.getOutputStream();
        } catch (IllegalStateException e) {
            // trying to serve a text file
            if (!usingPrecompressedVersion && ((contentType == null) || (contentType.startsWith("text")) || (contentType.endsWith("xml")) || (contentType.contains("/javascript")))) {
                writer = response.getWriter();
                // Cannot reliably serve partial content with a Writer
                ranges = FULL;
            } else {
                throw e;
            }
        }
    }
    // Check to see if a Filter, Valve of wrapper has written some content.
    // If it has, disable range requests and setting of a content length
    // since neither can be done reliably.
    ServletResponse r = response;
    long contentWritten = 0;
    while (r instanceof ServletResponseWrapper) {
        r = ((ServletResponseWrapper) r).getResponse();
    }
    if (r instanceof ResponseFacade) {
        contentWritten = ((ResponseFacade) r).getContentWritten();
    }
    if (contentWritten > 0) {
        ranges = FULL;
    }
    if (resource.isDirectory() || isError || ((ranges == null || ranges.isEmpty()) && request.getHeader("Range") == null) || ranges == FULL) {
        // Set the appropriate output headers
        if (contentType != null) {
            if (debug > 0)
                log("DefaultServlet.serveFile:  contentType='" + contentType + "'");
            response.setContentType(contentType);
        }
        if (resource.isFile() && contentLength >= 0 && (!serveContent || ostream != null)) {
            if (debug > 0)
                log("DefaultServlet.serveFile:  contentLength=" + contentLength);
            // written to the response.
            if (contentWritten == 0) {
                response.setContentLengthLong(contentLength);
            }
        }
        if (serveContent) {
            try {
                response.setBufferSize(output);
            } catch (IllegalStateException e) {
            // Silent catch
            }
            InputStream renderResult = null;
            if (ostream == null) {
                // content directly.
                if (resource.isDirectory()) {
                    renderResult = render(getPathPrefix(request), resource, encoding);
                } else {
                    renderResult = resource.getInputStream();
                }
                copy(resource, renderResult, writer, encoding);
            } else {
                // Output is via an InputStream
                if (resource.isDirectory()) {
                    renderResult = render(getPathPrefix(request), resource, encoding);
                } else {
                    // Output is content of resource
                    if (!checkSendfile(request, response, resource, contentLength, null)) {
                        // sendfile not possible so check if resource
                        // content is available directly
                        byte[] resourceBody = resource.getContent();
                        if (resourceBody == null) {
                            // Resource content not available, use
                            // inputstream
                            renderResult = resource.getInputStream();
                        } else {
                            // Use the resource content directly
                            ostream.write(resourceBody);
                        }
                    }
                }
                // the output (this method closes the stream)
                if (renderResult != null) {
                    copy(resource, renderResult, ostream);
                }
            }
        }
    } else {
        if ((ranges == null) || (ranges.isEmpty()))
            return;
        // Partial content response.
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        if (ranges.size() == 1) {
            Range range = ranges.get(0);
            response.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length);
            long length = range.end - range.start + 1;
            response.setContentLengthLong(length);
            if (contentType != null) {
                if (debug > 0)
                    log("DefaultServlet.serveFile:  contentType='" + contentType + "'");
                response.setContentType(contentType);
            }
            if (serveContent) {
                try {
                    response.setBufferSize(output);
                } catch (IllegalStateException e) {
                // Silent catch
                }
                if (ostream != null) {
                    if (!checkSendfile(request, response, resource, range.end - range.start + 1, range))
                        copy(resource, ostream, range);
                } else {
                    // we should not get here
                    throw new IllegalStateException();
                }
            }
        } else {
            response.setContentType("multipart/byteranges; boundary=" + mimeSeparation);
            if (serveContent) {
                try {
                    response.setBufferSize(output);
                } catch (IllegalStateException e) {
                // Silent catch
                }
                if (ostream != null) {
                    copy(resource, ostream, ranges.iterator(), contentType);
                } else {
                    // we should not get here
                    throw new IllegalStateException();
                }
            }
        }
    }
}
Also used : ServletResponse(javax.servlet.ServletResponse) HttpServletResponse(javax.servlet.http.HttpServletResponse) ServletOutputStream(javax.servlet.ServletOutputStream) BufferedInputStream(java.io.BufferedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) FileNotFoundException(java.io.FileNotFoundException) WebResource(org.apache.catalina.WebResource) ResponseFacade(org.apache.catalina.connector.ResponseFacade) ServletResponseWrapper(javax.servlet.ServletResponseWrapper) PrintWriter(java.io.PrintWriter)

Aggregations

WebResource (org.apache.catalina.WebResource)47 Test (org.junit.Test)14 InputStream (java.io.InputStream)10 File (java.io.File)9 ByteArrayInputStream (java.io.ByteArrayInputStream)8 IOException (java.io.IOException)7 URL (java.net.URL)7 BufferedInputStream (java.io.BufferedInputStream)5 FileInputStream (java.io.FileInputStream)5 InputSource (org.xml.sax.InputSource)5 PrintWriter (java.io.PrintWriter)3 RandomAccessFile (java.io.RandomAccessFile)3 Manifest (java.util.jar.Manifest)3 DocumentBuilder (javax.xml.parsers.DocumentBuilder)3 WebResourceSet (org.apache.catalina.WebResourceSet)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 OutputStreamWriter (java.io.OutputStreamWriter)2 StringWriter (java.io.StringWriter)2 Hashtable (java.util.Hashtable)2 LinkedHashSet (java.util.LinkedHashSet)2