All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.undertow.runtime.KnownPathResourceManager Maven / Gradle / Ivy

package io.quarkus.undertow.runtime;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import io.undertow.httpcore.OutputChannel;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.resource.Resource;
import io.undertow.server.handlers.resource.ResourceManager;
import io.undertow.util.ETag;
import io.undertow.util.MimeMappings;

public class KnownPathResourceManager implements ResourceManager {

    public static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows");

    private final NavigableSet files;
    private final NavigableSet directories;
    private final ResourceManager underlying;

    public KnownPathResourceManager(Set files, Set directories, ResourceManager underlying) {
        this.underlying = underlying;
        TreeSet tree = new TreeSet<>();
        for (String i : files) {
            if (i.startsWith("/")) {
                i = i.substring(1);
            }
            if (i.endsWith("/")) {
                i = i.substring(0, i.length() - 1);
            }
            tree.add(i);
        }
        this.files = tree;
        Set tmp = new HashSet<>();
        for (String i : directories) {
            if (i.startsWith("/")) {
                i = i.substring(1);
            }
            if (i.endsWith("/")) {
                i = i.substring(0, i.length() - 1);
            }
            tmp.add(i);
        }
        tmp.add("");
        this.directories = new TreeSet<>(tmp);
    }

    @Override
    public Resource getResource(String path) throws IOException {
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }
        if (directories.contains(path)) {
            return new DirectoryResource(path);
        }
        return underlying.getResource(path);
    }

    @Override
    public void close() throws IOException {
        underlying.close();
    }

    private class DirectoryResource implements Resource {

        private final String path;

        private DirectoryResource(String path) {
            this.path = evaluatePath(path);
        }

        private String evaluatePath(String path) {
            return path.replaceAll("\\\\", "/");
        }

        @Override
        public String getPath() {
            return path;
        }

        @Override
        public Date getLastModified() {
            return null;
        }

        @Override
        public String getLastModifiedString() {
            return null;
        }

        @Override
        public ETag getETag() {
            return null;
        }

        @Override
        public String getName() {
            int i = path.lastIndexOf('/');
            if (i == -1) {
                return path;
            }
            return path.substring(i + 1);
        }

        @Override
        public boolean isDirectory() {
            return true;
        }

        @Override
        public List list() {
            List ret = new ArrayList<>();
            String slashPath = path.isEmpty() ? path : path + "/";
            if (IS_WINDOWS) {
                slashPath = slashPath.replaceAll("/", "\\\\"); // correct Windows paths
            }
            SortedSet fileSet = files.tailSet(slashPath);
            SortedSet dirSet = directories.tailSet(slashPath);

            for (var s : List.of(fileSet, dirSet)) {
                for (String file : s) {
                    var i = file;
                    if (i.equals(slashPath)) {
                        continue;
                    }
                    if (i.startsWith(slashPath)) {
                        i = evaluatePath(i);
                        if (!i.substring(slashPath.length()).contains("/")) {
                            try {
                                Resource resource = underlying.getResource(i);
                                if (resource == null && directories.contains(file)) {
                                    resource = new DirectoryResource(file);
                                }
                                if (resource == null) {
                                    throw new RuntimeException("Unable to get listed resource " + i + " from directory " + path
                                            + " for path " + slashPath + " from underlying manager " + underlying);
                                }
                                ret.add(resource);
                            } catch (IOException e) {
                                throw new UncheckedIOException(e);
                            }
                        }
                    } else {
                        break;
                    }
                }
            }

            return ret;
        }

        @Override
        public String getContentType(MimeMappings mimeMappings) {
            return null;
        }

        @Override
        public void serveBlocking(OutputStream outputStream, HttpServerExchange exchange) throws IOException {
            throw new IOException("Cannot serve directory");
        }

        @Override
        public void serveAsync(OutputChannel stream, HttpServerExchange exchange) {
            exchange.setStatusCode(500);
            exchange.endExchange();
        }

        @Override
        public Long getContentLength() {
            return null;
        }

        @Override
        public String getCacheKey() {
            return null;
        }

        @Override
        public File getFile() {
            return null;
        }

        @Override
        public Path getFilePath() {
            return null;
        }

        @Override
        public File getResourceManagerRoot() {
            return null;
        }

        @Override
        public Path getResourceManagerRootPath() {
            return null;
        }

        @Override
        public URL getUrl() {
            return null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy