Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.server.handlers.resource;
 
 import java.io.File;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 

Author(s):
Stuart Douglas
 
 public class ResourceHandler implements HttpHandler {
 
     private final List<StringwelcomeFiles = new CopyOnWriteArrayList<>(new String[]{"index.html""index.htm""default.html""default.htm"});
    
If directory listing is enabled.
 
     private volatile boolean directoryListingEnabled = false;

    
If the canonical version of paths should be passed into the resource manager.
 
     private volatile boolean canonicalizePaths = true;

    
The mime mappings that are used to determine the content type.
 
     private volatile MimeMappings mimeMappings = .;
     private volatile Predicate cachable = Predicates.truePredicate();
     private volatile Predicate allowed = Predicates.truePredicate();
     private volatile ResourceManager resourceManager;
    
If this is set this will be the maximum time the client will cache the resource.

Note: Do not set this for private resources, as it will cause a Cache-Control: public to be sent.

TODO: make this more flexible

This will only be used if the cachable predicate returns true

 
     private volatile Integer cacheTime;
    
we do not calculate a new expiry date every request. Instead calculate it once and cache it until it is in the past.

TODO: do we need this policy to be pluggable

 
     private volatile long lastExpiryDate;
     private volatile String lastExpiryHeader;
 
 
     public ResourceHandler(ResourceManager resourceManager) {
         this. = resourceManager;
    }


    
You should use ResourceHandler(ResourceManager) instead.
    @Deprecated
    public ResourceHandler() {
    }
    @Override
    public void handleRequest(final HttpServerExchange exchangethrows Exception {
        if (exchange.getRequestMethod().equals(.) ||
                exchange.getRequestMethod().equals(.)) {
            serveResource(exchangetrue);
        } else if (exchange.getRequestMethod().equals(.)) {
            serveResource(exchangefalse);
        } else {
            exchange.setResponseCode(405);
            exchange.endExchange();
        }
    }
    private void serveResource(final HttpServerExchange exchangefinal boolean sendContent) {
        if (DirectoryUtils.sendRequestedBlobs(exchange)) {
            return;
        }
        if (!.resolve(exchange)) {
            exchange.setResponseCode(403);
            exchange.endExchange();
            return;
        }
        ResponseCache cache = exchange.getAttachment(.);
        final boolean cachable = this..resolve(exchange);
        //we set caching headers before we try and serve from the cache
        if (cachable &&  != null) {
            exchange.getResponseHeaders().put(."public, max-age=" + );
            if (System.currentTimeMillis() > ) {
                long date = System.currentTimeMillis();
                 = DateUtils.toDateString(new Date(date));
                 = date;
            }
            exchange.getResponseHeaders().put(.);
        }
        if (cache != null && cachable) {
            if (cache.tryServeResponse()) {
                return;
            }
        }
        //we now dispatch to a worker thread
        //as resource manager methods are potentially blocking
        exchange.dispatch(new Runnable() {
            @Override
            public void run() {
                Resource resource = null;
                try {
                    if(. == '/' || !exchange.getRelativePath().contains(.)) {
                        //we don't process resources that contain the sperator character if this is not /
                        //this prevents attacks where people use windows path seperators in file URLS's
                        resource = .getResource(canonicalize(exchange.getRelativePath()));
                    }
                } catch (IOException e) {
                    ..ioException(e);
                    exchange.setResponseCode(500);
                    exchange.endExchange();
                    return;
                }
                if (resource == null) {
                    exchange.setResponseCode(404);
                    exchange.endExchange();
                    return;
                }
                if (resource.isDirectory()) {
                    Resource indexResource = null;
                    try {
                        indexResource = getIndexFiles(resource.getPath(), );
                    } catch (IOException e) {
                        ..ioException(e);
                        exchange.setResponseCode(500);
                        exchange.endExchange();
                        return;
                    }
                    if (indexResource == null) {
                        if () {
                            DirectoryUtils.renderDirectoryListing(exchangeresource);
                            return;
                        } else {
                            exchange.setResponseCode(.);
                            exchange.endExchange();
                            return;
                        }
                    } else if (!exchange.getRequestPath().endsWith("/")) {
                        exchange.setResponseCode(302);
                        exchange.getResponseHeaders().put(., RedirectBuilder.redirect(exchangeexchange.getRelativePath() + "/"true));
                        exchange.endExchange();
                        return;
                    }
                    resource = indexResource;
                }
                final ETag etag = resource.getETag();
                final Date lastModified = resource.getLastModified();
                if (!ETagUtils.handleIfMatch(exchangeetagfalse) ||
                        !DateUtils.handleIfUnmodifiedSince(exchangelastModified)) {
                    exchange.setResponseCode(412);
                    exchange.endExchange();
                    return;
                }
                if (!ETagUtils.handleIfNoneMatch(exchangeetagtrue) ||
                        !DateUtils.handleIfModifiedSince(exchangelastModified)) {
                    exchange.setResponseCode(304);
                    exchange.endExchange();
                    return;
                }
                //todo: handle range requests
                //we are going to proceed. Set the appropriate headers
                final String contentType = resource.getContentType();
                if(!exchange.getResponseHeaders().contains(.)) {
                    if (contentType != null) {
                        exchange.getResponseHeaders().put(.contentType);
                    } else {
                        exchange.getResponseHeaders().put(."application/octet-stream");
                    }
                }
                if (lastModified != null) {
                    exchange.getResponseHeaders().put(.resource.getLastModifiedString());
                }
                if (etag != null) {
                    exchange.getResponseHeaders().put(.etag.toString());
                }
                Long contentLength = resource.getContentLength();
                if (contentLength != null) {
                    exchange.getResponseHeaders().put(.contentLength.toString());
                }
                final ContentEncodedResourceManager contentEncodedResourceManager = ResourceHandler.this.;
                if (contentEncodedResourceManager != null) {
                    try {
                        ContentEncodedResource encoded = contentEncodedResourceManager.getResource(resourceexchange);
                        if (encoded != null) {
                            exchange.getResponseHeaders().put(.encoded.getContentEncoding());
                            exchange.getResponseHeaders().put(.encoded.getResource().getContentLength());
                            encoded.getResource().serve(exchange.getResponseSender(), exchange.);
                            return;
                        }
                    } catch (IOException e) {
                        //TODO: should this be fatal
                        ..ioException(e);
                        exchange.setResponseCode(500);
                        exchange.endExchange();
                        return;
                    }
                }
                if (!sendContent) {
                    exchange.endExchange();
                } else {
                    resource.serve(exchange.getResponseSender(), exchange.);
                }
            }
        });
    }
    private Resource getIndexFiles(ResourceManager resourceManagerfinal String baseList<Stringpossiblethrows IOException {
        String realBase;
        if (base.endsWith("/")) {
            realBase = base;
        } else {
            realBase = base + "/";
        }
        for (String possibility : possible) {
            Resource index = resourceManager.getResource(canonicalize(realBase + possibility));
            if (index != null) {
                return index;
            }
        }
        return null;
    }
    private String canonicalize(String s) {
        if() {
            return CanonicalPathUtils.canonicalize(s);
        }
        return s;
    }
    public boolean isDirectoryListingEnabled() {
        return ;
    }
    public ResourceHandler setDirectoryListingEnabled(final boolean directoryListingEnabled) {
        this. = directoryListingEnabled;
        return this;
    }
    public ResourceHandler addWelcomeFiles(String... files) {
        this..addAll(Arrays.asList(files));
        return this;
    }
    public ResourceHandler setWelcomeFiles(String... files) {
        this..clear();
        this..addAll(Arrays.asList(files));
        return this;
    }
    public MimeMappings getMimeMappings() {
        return ;
    }
    public ResourceHandler setMimeMappings(final MimeMappings mimeMappings) {
        this. = mimeMappings;
        return this;
    }
    public Predicate getCachable() {
        return ;
    }
    public ResourceHandler setCachable(final Predicate cachable) {
        this. = cachable;
        return this;
    }
    public Predicate getAllowed() {
        return ;
    }
    public ResourceHandler setAllowed(final Predicate allowed) {
        this. = allowed;
        return this;
    }
        return ;
    }
    public ResourceHandler setResourceManager(final ResourceManager resourceManager) {
        this. = resourceManager;
        return this;
    }
    public Integer getCacheTime() {
        return ;
    }
    public ResourceHandler setCacheTime(final Integer cacheTime) {
        this. = cacheTime;
        return this;
    }
        return ;
    }
    public ResourceHandler setContentEncodedResourceManager(ContentEncodedResourceManager contentEncodedResourceManager) {
        this. = contentEncodedResourceManager;
        return this;
    }
    public boolean isCanonicalizePaths() {
        return ;
    }

    
If this handler should use canonicalized paths. WARNING: If this is not true and io.undertow.server.handlers.CanonicalPathHandler is not installed in the handler chain then is may be possible to perform a directory traversal attack. If you set this to false make sure you have some kind of check in place to control the path.

Parameters:
canonicalizePaths If paths should be canonicalized
    public void setCanonicalizePaths(boolean canonicalizePaths) {
        this. = canonicalizePaths;
    }
    public static class Builder implements HandlerBuilder {
        @Override
        public String name() {
            return "resource";
        }
        @Override
        public Map<StringClass<?>> parameters() {
            Map<StringClass<?>> params = new HashMap<>();
            params.put("location"String.class);
            params.put("allow-listing"boolean.class);
            return params;
        }
        @Override
        public Set<StringrequiredParameters() {
            return Collections.singleton("location");
        }
        @Override
        public String defaultParameter() {
            return "location";
        }
        @Override
        public HandlerWrapper build(Map<StringObjectconfig) {
            return new Wrapper((String)config.get("location"), (Booleanconfig.get("allow-listing"));
        }
    }
    private static class Wrapper implements HandlerWrapper {
        private final String location;
        private final boolean allowDirectoryListing;
        private Wrapper(String locationboolean allowDirectoryListing) {
            this. = location;
            this. = allowDirectoryListing;
        }
        @Override
        public HttpHandler wrap(HttpHandler handler) {
            ResourceManager rm = new FileResourceManager(new File(), 1024);
            ResourceHandler resourceHandler = new ResourceHandler(rm);
            resourceHandler.setDirectoryListingEnabled();
            return resourceHandler;
        }
    }
New to GrepCode? Check out our FAQ X