【问题标题】:How to configure Wildfly to serve static content (like images)?如何配置 Wildfly 以提供静态内容(如图像)?
【发布时间】:2014-05-06 05:09:57
【问题描述】:

我有一个在 Wildfly 8.0.0 Final 上运行的 JavaEE 应用程序。

应用程序使用了很多图像,我不想将它们存储在数据库中,因此将它们写入硬盘。

如何配置 Wildfly/Undertow 以便在某个 URL 上提供这些文件 (/var/images),例如 http://localhost:8080/myapplication/imagesFromDisk

【问题讨论】:

    标签: wildfly undertow static-content


    【解决方案1】:

    在standalone.xml 中向undertow 子系统添加另一个文件处理程序和另一个位置:

    <server name="default-server">
        <http-listener name="default" socket-binding="http"/>
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content"/>
            <location name="/img" handler="images"/>
        </host>
    </server>
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content" directory-listing="true"/>
        <file name="images" path="/var/images" directory-listing="true"/>
    </handlers>
    

    【讨论】:

    • 您知道如何使用 CLI 工具执行此操作吗?我不知道如何访问处理程序和过滤器节点。 /subsystem=undertow/filters:read-resource Node path format is wrong around 'filters' (index=20). 即使我想阅读过滤器,这也不起作用。至于如何使用 CLI 访问它们,我没有看到文档 docs.jboss.org/author/display/WFLY8/… 中提到过滤器和处理程序。
    • 你知道在 Jboss 7.1.1 中实现这一点的方法吗?到处看看,什么都没有。
    • @PawelPredki,使用 --gui 选项启动 CLI,有一个命令生成器。例如。添加过滤器:/subsystem=undertow/configuration=filter/response-header=ie-disable-compatibility-header/:add(header-value=IE\=edge,header-name=X-UA-Compatible),然后是/subsystem=undertow/server=default-server/host=default-host/filter-ref=ie-disable-compatibility-header/:add。但是,在重新启动服务器之前,新过滤器将无法工作。
    • @hwellmann,我怎样才能在纯 Undertow 中实现这一点?我真的需要为文件添加一个新的处理程序吗?另外,为什么我不能只用图像/jpeg 类型和正文中的图像来响应 GET 请求?谢谢,我打开了一个问题,但还没有人回答。 (见stackoverflow.com/questions/29023144/…
    • 是否可以添加列排序功能?
    【解决方案2】:

    如果您不想或不能在standalone.xml 中使用configure the Undertow subsystem,那么您需要使其在.war 中工作。为此,您可以使用 servlet 来提供文件。周围的实现很少,最著名的(或谷歌上最高的)是by BalusC。不过,那个是在 LGPL 下获得许可的。所以我拿了DefaultServletmade it more easily extensible,所以你可以把它喂给正确的Undertow Resource,例如from a file system.

    理论上,Undertow 中的某些 servlet 也应该能够从文件系统提供服务,但 DefaultServlet 代码似乎只计入部署中的资源。

    基类:

     /*
     * JBoss, Home of Professional Open Source.
     * Copyright 2014 Red Hat, Inc., and individual contributors
     * as indicated by the @author tags.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     *  Unless required by applicable law or agreed to in writing, software
     *  distributed under the License is distributed on an "AS IS" BASIS,
     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *  See the License for the specific language governing permissions and
     *  limitations under the License.
     */
    package io.undertow.servlet.handlers;
    
    import io.undertow.io.IoCallback;
    import io.undertow.io.Sender;
    import io.undertow.server.HttpServerExchange;
    import io.undertow.server.handlers.resource.DirectoryUtils;
    import io.undertow.server.handlers.resource.RangeAwareResource;
    import io.undertow.server.handlers.resource.Resource;
    import io.undertow.server.handlers.resource.ResourceManager;
    import io.undertow.servlet.api.DefaultServletConfig;
    import io.undertow.servlet.api.Deployment;
    import io.undertow.servlet.spec.ServletContextImpl;
    import io.undertow.util.ByteRange;
    import io.undertow.util.CanonicalPathUtils;
    import io.undertow.util.DateUtils;
    import io.undertow.util.ETag;
    import io.undertow.util.ETagUtils;
    import io.undertow.util.Headers;
    import io.undertow.util.Methods;
    import io.undertow.util.StatusCodes;
    
    import javax.servlet.DispatcherType;
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * Abstract default servlet implementation for serving static content.
     * This is both a handler and a servlet. If no filters
     * match the current path then the content will be served up asynchronously using the
     * {@link io.undertow.server.HttpHandler#handleRequest(io.undertow.server.HttpServerExchange)} method,
     * otherwise the request is handled as a normal servlet request.
     * <p>
     * By default we only allow a restricted set of extensions.
     * <p>
     *
     * @author Stuart Douglas
     * @author Ondrej Zizka, zizka at seznam.cz
     */
    public abstract class DefaultServlet extends HttpServlet {
    
        public static final String DIRECTORY_LISTING = "directory-listing";
        public static final String DEFAULT_ALLOWED = "default-allowed";
        public static final String ALLOWED_EXTENSIONS = "allowed-extensions";
        public static final String DISALLOWED_EXTENSIONS = "disallowed-extensions";
        public static final String RESOLVE_AGAINST_CONTEXT_ROOT = "resolve-against-context-root";
    
        private static final Set<String> DEFAULT_ALLOWED_EXTENSIONS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
            "js", "css", "png", "jpg", "gif", "html", "htm", "txt", "pdf", "jpeg", "xml",
            "svg", "ttf", "java")));
    
        private Deployment deployment;
        private ResourceManager resourceManager;
    
        private final Settings settings = new Settings();
    
        public Settings getSettings() {
        return settings;
        }
    
    
    
        @Override
        public void init(ServletConfig config) throws ServletException {
        super.init(config);
    
        ServletContextImpl sc = (ServletContextImpl) config.getServletContext();
        this.deployment = sc.getDeployment();
    
        // Settings from the servlet init parameters.
        if (config.getInitParameter(DEFAULT_ALLOWED) != null) {
            settings.defaultAllowed = Boolean.parseBoolean(config.getInitParameter(DEFAULT_ALLOWED));
        }
        if (config.getInitParameter(ALLOWED_EXTENSIONS) != null) {
            String extensions = config.getInitParameter(ALLOWED_EXTENSIONS);
            settings.allowed = new HashSet<>(Arrays.asList(extensions.split(",")));
        }
        if (config.getInitParameter(DISALLOWED_EXTENSIONS) != null) {
            String extensions = config.getInitParameter(DISALLOWED_EXTENSIONS);
            settings.disallowed = new HashSet<>(Arrays.asList(extensions.split(",")));
        }
        if (config.getInitParameter(RESOLVE_AGAINST_CONTEXT_ROOT) != null) {
            settings.resolveAgainstContextRoot = Boolean.parseBoolean(config.getInitParameter(RESOLVE_AGAINST_CONTEXT_ROOT));
        }
    
        String listings = config.getInitParameter(DIRECTORY_LISTING);
        if (Boolean.valueOf(listings)) {
            settings.directoryListingEnabled = true;
        }
    
        // Settings from the deployment configuration.
        DefaultServletConfig defaultServletConfig = getDeployment().getDeploymentInfo().getDefaultServletConfig();
        if (defaultServletConfig != null) {
            getSettings().setDefaultAllowed(defaultServletConfig.isDefaultAllowed());
            getSettings().setAllowed(new HashSet<>());
            if (defaultServletConfig.getAllowed() != null) {
                getSettings().getAllowed().addAll(defaultServletConfig.getAllowed());
            }
            getSettings().setDisallowed(new HashSet<>());
            if (defaultServletConfig.getDisallowed() != null) {
                getSettings().getDisallowed().addAll(defaultServletConfig.getDisallowed());
            }
        }
    
        }
    
    
        @Override
        protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        String path = getPath(req);
        if (!isAllowed(path, req.getDispatcherType())) {
            resp.sendError(StatusCodes.NOT_FOUND);
            return;
        }
        if(File.separatorChar != '/') {
            //if the separator char is not / we want to replace it with a / and canonicalise
            path = CanonicalPathUtils.canonicalize(path.replace(File.separatorChar, '/'));
        }
    
        final Resource resource;
        //we want to disallow windows characters in the path
        if(File.separatorChar == '/' || !path.contains(File.separator)) {
            resource = resourceManager.getResource(path);
        } else {
            resource = null;
        }
    
        if (resource == null) {
            if (req.getDispatcherType() == DispatcherType.INCLUDE) {
                //servlet 9.3
                throw new FileNotFoundException(path);
            } else {
                resp.sendError(StatusCodes.NOT_FOUND);
            }
            return;
        }
    
        // Directory
        if (resource.isDirectory()) {
            if (!settings.directoryListingEnabled)
                resp.sendError(StatusCodes.FORBIDDEN);
    
            //  /servlet-name/some/dir/?css or ?js
            if ("css".equals(req.getQueryString())) {
                resp.setContentType("text/css");
                resp.getWriter().write(DirectoryUtils.Blobs.FILE_CSS);
                return;
            } else if ("js".equals(req.getQueryString())) {
                resp.setContentType("application/javascript");
                resp.getWriter().write(DirectoryUtils.Blobs.FILE_JS);
                return;
            }
    
            StringBuilder output = DirectoryUtils.renderDirectoryListing(req.getRequestURI(), resource);
            resp.getWriter().write(output.toString());
        }
    
        // File
        else {
            if(path.endsWith("/")) {
                //UNDERTOW-432
                resp.sendError(StatusCodes.NOT_FOUND);
                return;
            }
            serveFileBlocking(req, resp, resource);
        }
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
         * Where a servlet has received a POST request we still require the capability to include static content.
         */
        switch (req.getDispatcherType()) {
            case INCLUDE:
            case FORWARD:
            case ERROR:
                doGet(req, resp);
                break;
            default:
                super.doPost(req, resp);
        }
        }
    
        @Override
        protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        switch (req.getDispatcherType()) {
            case INCLUDE:
            case FORWARD:
            case ERROR:
                doGet(req, resp);
                break;
            default:
                super.doPut(req, resp);
        }
        }
    
        @Override
        protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        switch (req.getDispatcherType()) {
            case INCLUDE:
            case FORWARD:
            case ERROR:
                doGet(req, resp);
                break;
            default:
                super.doDelete(req, resp);
        }
        }
    
        @Override
        protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        switch (req.getDispatcherType()) {
            case INCLUDE:
            case FORWARD:
            case ERROR:
                doGet(req, resp);
                break;
            default:
                super.doOptions(req, resp);
        }
        }
    
        @Override
        protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        switch (req.getDispatcherType()) {
            case INCLUDE:
            case FORWARD:
            case ERROR:
                doGet(req, resp);
                break;
            default:
                super.doTrace(req, resp);
        }
        }
    
        protected void serveFileBlocking(final HttpServletRequest req, final HttpServletResponse resp, final Resource resource) throws IOException {
        final ETag etag = resource.getETag();
        final Date lastModified = resource.getLastModified();
        if(req.getDispatcherType() != DispatcherType.INCLUDE) {
            if (!ETagUtils.handleIfMatch(req.getHeader(Headers.IF_MATCH_STRING), etag, false) ||
                    !DateUtils.handleIfUnmodifiedSince(req.getHeader(Headers.IF_UNMODIFIED_SINCE_STRING), lastModified)) {
                resp.setStatus(StatusCodes.PRECONDITION_FAILED);
                return;
            }
            if (!ETagUtils.handleIfNoneMatch(req.getHeader(Headers.IF_NONE_MATCH_STRING), etag, true) ||
                    !DateUtils.handleIfModifiedSince(req.getHeader(Headers.IF_MODIFIED_SINCE_STRING), lastModified)) {
                resp.setStatus(StatusCodes.NOT_MODIFIED);
                return;
            }
        }
    
        //we are going to proceed. Set the appropriate headers
        if(resp.getContentType() == null) {
            if(!resource.isDirectory()) {
                final String contentType = deployment.getServletContext().getMimeType(resource.getName());
                if (contentType != null) {
                    resp.setContentType(contentType);
                } else {
                    resp.setContentType("application/octet-stream");
                }
            }
        }
        if (lastModified != null) {
            resp.setHeader(Headers.LAST_MODIFIED_STRING, resource.getLastModifiedString());
        }
        if (etag != null) {
            resp.setHeader(Headers.ETAG_STRING, etag.toString());
        }
        ByteRange range = null;
        long start = -1, end = -1;
        try {
            //only set the content length if we are using a stream
            //if we are using a writer who knows what the length will end up being
            //todo: if someone installs a filter this can cause problems
            //not sure how best to deal with this
            //we also can't deal with range requests if a writer is in use
            Long contentLength = resource.getContentLength();
            if (contentLength != null) {
                resp.getOutputStream();
                if(contentLength > Integer.MAX_VALUE) {
                    resp.setContentLengthLong(contentLength);
                } else {
                    resp.setContentLength(contentLength.intValue());
                }
                if(resource instanceof RangeAwareResource && ((RangeAwareResource)resource).isRangeSupported()) {
                    //TODO: figure out what to do with the content encoded resource manager
                    range = ByteRange.parse(req.getHeader(Headers.RANGE_STRING));
                    if(range != null && range.getRanges() == 1) {
                        start = range.getStart(0);
                        end = range.getEnd(0);
                        if(start == -1 ) {
                            //suffix range
                            long toWrite = end;
                            if(toWrite >= 0) {
                                if(toWrite > Integer.MAX_VALUE) {
                                    resp.setContentLengthLong(toWrite);
                                } else {
                                    resp.setContentLength((int)toWrite);
                                }
                            } else {
                                //ignore the range request
                                range = null;
                            }
                            start = contentLength - end;
                            end = contentLength;
                        } else if(end == -1) {
                            //prefix range
                            long toWrite = contentLength - start;
                            if(toWrite >= 0) {
                                if(toWrite > Integer.MAX_VALUE) {
                                    resp.setContentLengthLong(toWrite);
                                } else {
                                    resp.setContentLength((int)toWrite);
                                }
                            } else {
                                //ignore the range request
                                range = null;
                            }
                            end = contentLength;
                        } else {
                            long toWrite = end - start + 1;
                            if(toWrite > Integer.MAX_VALUE) {
                                resp.setContentLengthLong(toWrite);
                            } else {
                                resp.setContentLength((int)toWrite);
                            }
                        }
                        if(range != null) {
                            resp.setStatus(StatusCodes.PARTIAL_CONTENT);
                            resp.setHeader(Headers.CONTENT_RANGE_STRING, range.getStart(0) + "-" + range.getEnd(0) + "/" + contentLength);
                        }
                    }
                }
            }
        } catch (IllegalStateException e) {
    
        }
        final boolean include = req.getDispatcherType() == DispatcherType.INCLUDE;
        if (!req.getMethod().equals(Methods.HEAD_STRING)) {
            HttpServerExchange exchange = SecurityActions.requireCurrentServletRequestContext().getOriginalRequest().getExchange();
            if(range == null) {
                resource.serve(exchange.getResponseSender(), exchange, completionCallback(include));
            } else {
                ((RangeAwareResource)resource).serveRange(exchange.getResponseSender(), exchange, start, end, completionCallback(include));
            }
        }
        }
    
        private IoCallback completionCallback(final boolean include) {
        return new IoCallback() {
    
            @Override
            public void onComplete(final HttpServerExchange exchange, final Sender sender) {
                if (!include) {
                    sender.close();
                }
            }
    
            @Override
            public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
                //not much we can do here, the connection is broken
                sender.close();
            }
        };
        }
    
        /**
         * Returns the canonicalized URL path.
         */
        private String getPath(final HttpServletRequest request) {
        String servletPath;
        String pathInfo;
    
        if (request.getDispatcherType() == DispatcherType.INCLUDE && request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null) {
            pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
            servletPath = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
        } else {
            pathInfo = request.getPathInfo();
            servletPath = request.getServletPath();
        }
        String result = pathInfo;
        if (result == null) {
            result = servletPath;
        } else if(settings.resolveAgainstContextRoot) {
            result = servletPath + CanonicalPathUtils.canonicalize(pathInfo);
        } else {
            result = CanonicalPathUtils.canonicalize(result);
        }
        if ((result == null) || (result.equals(""))) {
            result = "/";
        }
        return result;
    
        }
    
        /**
         * @return true if the resource at the given path is allowed to be sent to the client.
         */
        protected boolean isAllowed(String path, DispatcherType dispatcherType) {
        int pos = path.lastIndexOf('/');
        final String lastSegment;
        if (pos == -1) {
            lastSegment = path;
        } else {
            lastSegment = path.substring(pos + 1);
        }
        if (lastSegment.isEmpty()) {
            return true;
        }
        int ext = lastSegment.lastIndexOf('.');
        if (ext == -1) {
            //no extension
            return true;
        }
        final String extension = lastSegment.substring(ext + 1, lastSegment.length());
        if (settings.defaultAllowed) {
            return !settings.disallowed.contains(extension);
        } else {
            return settings.allowed.contains(extension);
        }
        }
    
        public boolean isDirectoryListingEnabled() {
        return settings.directoryListingEnabled;
        }
    
    
        public void setDirectoryListingEnabled(boolean directoryListingEnabled) {
        settings.directoryListingEnabled = directoryListingEnabled;
        }
    
        public ResourceManager getResourceManager() {
        return resourceManager;
        }
    
    
        public void setResourceManager(ResourceManager resourceManager) {
        this.resourceManager = resourceManager;
        }
    
    
        public Deployment getDeployment() {
        return deployment;
        }
    
    
    
    
        protected static class Settings
        {
        private boolean directoryListingEnabled = false;
        private boolean defaultAllowed = true;
        private Set<String> allowed = DEFAULT_ALLOWED_EXTENSIONS;
        private Set<String> disallowed = Collections.emptySet();
        private boolean resolveAgainstContextRoot;
    
    
        public boolean isDirectoryListingEnabled() {
            return directoryListingEnabled;
        }
    
        public void setDirectoryListingEnabled(boolean directoryListingEnabled) {
            this.directoryListingEnabled = directoryListingEnabled;
        }
    
        public boolean isDefaultAllowed() {
            return defaultAllowed;
        }
    
        public void setDefaultAllowed(boolean defaultAllowed) {
            this.defaultAllowed = defaultAllowed;
        }
    
        public Set<String> getAllowed() {
            return allowed;
        }
    
        public void setAllowed(Set<String> allowed) {
            this.allowed = allowed;
        }
    
        public Set<String> getDisallowed() {
            return disallowed;
        }
    
        public void setDisallowed(Set<String> disallowed) {
            this.disallowed = disallowed;
        }
    
        public boolean isResolveAgainstContextRoot() {
            return resolveAgainstContextRoot;
        }
    
        public void setResolveAgainstContextRoot(boolean resolveAgainstContextRoot) {
            this.resolveAgainstContextRoot = resolveAgainstContextRoot;
        }
        }
    }
    

    file serving servlet(您将在web.xml 中使用的那个):

    /*
     * JBoss, Home of Professional Open Source.
     * Copyright 2014 Red Hat, Inc., and individual contributors
     * as indicated by the @author tags.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     *  Unless required by applicable law or agreed to in writing, software
     *  distributed under the License is distributed on an "AS IS" BASIS,
     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *  See the License for the specific language governing permissions and
     *  limitations under the License.
     */
    package org.jboss.windup.web.fileservlet;
    
    import io.undertow.Undertow;
    import java.util.logging.Logger;
    import io.undertow.server.handlers.resource.FileResourceManager;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import java.io.File;
    import org.jboss.windup.web.addons.websupport.WebPathUtil;
    
    /**
     * Default servlet responsible for serving up files from a directory.
     * This is both a handler and a servlet. If no filters
     * match the current path, then the resources will be served up asynchronously using the
     * {@link io.undertow.server.HttpHandler#handleRequest(io.undertow.server.HttpServerExchange)} method,
     * otherwise the request is handled as a normal servlet request.
     *
     * <p>
     * By default we only allow a restricted set of extensions.
     * <p>
    
     * @author Ondrej Zizka, zizka at seznam.cz
     * @see Undertow's DefaultServlet
     */
    public class FileDefaultServlet extends DefaultServlet
    {
        public static final String BASE_PATH = "base-path";
    
        /**
         * Which directory should this servlet serve files from.
         */
        private String basePath;
    
    
        @Override
        public void init(ServletConfig config) throws ServletException {
        super.init(config);
    
        initBasePath();
        this.setResourceManager(new FileResourceManager(new File(basePath), 8*1024));
        }
    
    
        private void initBasePath() throws ServletException
        {
        // Get base path (path to get all resources from) as init parameter.
        this.basePath = getInitParameter(BASE_PATH);
        this.basePath = WebPathUtil.expandVariables(this.basePath);
    
        // Validate base path.
        if (this.basePath == null) {
            throw new ServletException("FileServlet init param 'basePath' is required.");
        } else {
            File path = new File(this.basePath);
            if (!path.exists()) {
                throw new ServletException("FileServlet init param 'basePath' value '"
                        + this.basePath + "' does actually not exist in file system.");
            } else if (!path.isDirectory()) {
                throw new ServletException("FileServlet init param 'basePath' value '"
                        + this.basePath + "' is actually not a directory in file system.");
            } else if (!path.canRead()) {
                throw new ServletException("FileServlet init param 'basePath' value '"
                        + this.basePath + "' is actually not readable in file system.");
            }
        }
        }
    
    }
    

    这是一个 servlet,其工作方式与之前的 DefaultServlet 类似 - 即从部署中提供服务。

    /*
     * JBoss, Home of Professional Open Source.
     * Copyright 2014 Red Hat, Inc., and individual contributors
     * as indicated by the @author tags.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     *  Unless required by applicable law or agreed to in writing, software
     *  distributed under the License is distributed on an "AS IS" BASIS,
     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     *  See the License for the specific language governing permissions and
     *  limitations under the License.
     */
    package io.undertow.servlet.handlers;
    
    import javax.servlet.DispatcherType;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    
    /**
     * Default servlet responsible for serving up resources. This is both a handler and a servlet. If no filters
     * match the current path then the resources will be served up asynchronously using the
     * {@link io.undertow.server.HttpHandler#handleRequest(io.undertow.server.HttpServerExchange)} method,
     * otherwise the request is handled as a normal servlet request.
     * <p>
     * By default we only allow a restricted set of extensions.
     * <p>
     * todo: this thing needs a lot more work. In particular:
     * - caching for blocking requests
     * - correct mime type
     * - range/last-modified and other headers to be handled properly
     * - head requests
     * - and probably heaps of other things
     *
     * @author Ondrej Zizka, zizka at seznam.cz
     */
    public class ResourceDefaultServlet extends DefaultServlet {
    
        @Override
        public void init(ServletConfig config) throws ServletException {
        super.init(config);
    
        this.setResourceManager(getDeployment().getDeploymentInfo().getResourceManager());
        }
    
    
        @Override
        protected boolean isAllowed(String path, DispatcherType dispatcherType) {
    
        if (!path.isEmpty()) {
            if(dispatcherType == DispatcherType.REQUEST) {
                //WFLY-3543 allow the dispatcher to access stuff in web-inf and meta inf
                if (path.startsWith("/META-INF") ||
                        path.startsWith("META-INF") ||
                        path.startsWith("/WEB-INF") ||
                        path.startsWith("WEB-INF")) {
                    return false;
                }
            }
        }
    
        return super.isAllowed(path, dispatcherType);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-22
      • 1970-01-01
      • 2018-01-29
      • 2018-09-28
      • 2011-02-01
      • 2017-06-13
      • 2012-07-23
      • 1970-01-01
      相关资源
      最近更新 更多