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

io.muserver.handlers.ResourceHandler Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
package io.muserver.handlers;

import io.muserver.*;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

import static io.muserver.handlers.ResourceType.DEFAULT_EXTENSION_MAPPINGS;

/**
 * A handler to serve static content. To create a handler, using {@link ResourceHandlerBuilder#fileOrClasspath(String, String)},
 * {@link ResourceHandlerBuilder#classpathHandler(String)}, {@link ResourceHandlerBuilder#fileHandler(File)} or one of its variants.
 */
public class ResourceHandler implements MuHandler {
    private final Map extensionToResourceType;
    private final String pathToServeFrom;
    private final String defaultFile;
    private final ResourceProviderFactory resourceProviderFactory;

    ResourceHandler(ResourceProviderFactory resourceProviderFactory, String pathToServeFrom, String defaultFile, Map extensionToResourceType) {
        this.resourceProviderFactory = resourceProviderFactory;
        this.pathToServeFrom = pathToServeFrom;
        this.extensionToResourceType = extensionToResourceType;
        this.defaultFile = defaultFile;
    }

    @Override
    public boolean handle(MuRequest request, MuResponse response) throws Exception {
        String requestPath = request.relativePath();
        if (!requestPath.startsWith(pathToServeFrom)) {
            return false;
        }
        if (requestPath.endsWith("/") && defaultFile != null) {
            requestPath += defaultFile;
        }

        String pathWithoutWebPrefix = pathToServeFrom.equals("/")
            ? requestPath
            : requestPath.substring(pathToServeFrom.length());

        String decodedRelativePath = Mutils.urlDecode(pathWithoutWebPrefix);
        ResourceProvider provider = resourceProviderFactory.get(decodedRelativePath);
        if (!provider.exists()) {
            return false;
        }
        if (provider.isDirectory()) {
            String goingTo = request.uri().getPath() + "/";
            response.redirect(goingTo);
        } else {
            String filename = requestPath.substring(requestPath.lastIndexOf('/'));
            addHeaders(response, filename);
            provider.sendTo(response, request.method() != Method.HEAD);
        }
        return true;
    }

    private void addHeaders(MuResponse response, String fileName) {
        int ind = fileName.lastIndexOf('.');
        ResourceType type;
        if (ind == -1) {
            type = ResourceType.DEFAULT;
        } else {
            String extension = fileName.substring(ind + 1).toLowerCase();
            type = extensionToResourceType.getOrDefault(extension, ResourceType.DEFAULT);
        }
        response.contentType(type.mimeType);
        response.headers().set(HeaderNames.VARY, "accept-encoding");
        response.headers().add(type.headers);
    }

    /**
     * 

Used to create a {@link ResourceHandler} for serving static files.

*

In order to serve from the filesystem during development, and from classpath and deploy time, see * {@link #fileOrClasspath(String, String)}

* @deprecated Use {@link ResourceHandlerBuilder} */ @Deprecated public static class Builder implements MuHandlerBuilder { private Map extensionToResourceType = DEFAULT_EXTENSION_MAPPINGS; private String pathToServeFrom = "/"; private String defaultFile = "index.html"; private ResourceProviderFactory resourceProviderFactory; /** * Specify custom filename extension to mime-type mappings. By default {@link ResourceType#DEFAULT_EXTENSION_MAPPINGS} * are used. * @param extensionToResourceType The mappings to use. * @return The builder * @deprecated Use {@link ResourceHandlerBuilder} */ @Deprecated public Builder withExtensionToResourceType(Map extensionToResourceType) { this.extensionToResourceType = extensionToResourceType; return this; } /** * Specifies the path to serve the static from. * @param pathToServeFrom A path that static data should be served from. Defaults to / * @return The builder * @deprecated Use {@link ResourceHandlerBuilder} */ @Deprecated public Builder withPathToServeFrom(String pathToServeFrom) { this.pathToServeFrom = pathToServeFrom; return this; } /** * Specifies the file to use when a request such as /web/ is made. Defaults to index.html * @param defaultFile The default file to use when a directory is requested * @return The builder * @deprecated Use {@link ResourceHandlerBuilder} */ @Deprecated public Builder withDefaultFile(String defaultFile) { this.defaultFile = defaultFile; return this; } Builder withResourceProviderFactory(ResourceProviderFactory resourceProviderFactory) { this.resourceProviderFactory = resourceProviderFactory; return this; } /** * Creates the handler * @return The built handler */ public ResourceHandler build() { if (resourceProviderFactory == null) { throw new IllegalStateException("No resourceProviderFactory has been set"); } return new ResourceHandler(resourceProviderFactory, pathToServeFrom, defaultFile, extensionToResourceType); } } /** * Creates a handler that serves files from the given directory. * @param directoryPath The directory. * @return A new builder. * @deprecated Use {@link ResourceHandlerBuilder#fileHandler(String)} */ @Deprecated public static ResourceHandler.Builder fileHandler(String directoryPath) { return fileHandler(Paths.get(directoryPath)); } /** * Creates a handler that serves files from the given directory. * @param baseDirectory The directory. * @return A new builder. * @deprecated Use {@link ResourceHandlerBuilder#fileHandler(File)} */ @Deprecated public static ResourceHandler.Builder fileHandler(File baseDirectory) { return fileHandler(baseDirectory.toPath()); } /** * Creates a handler that serves files from the given directory. * @param path The directory. * @return A new builder. * @deprecated Use {@link ResourceHandlerBuilder#fileHandler(Path)} */ @Deprecated public static ResourceHandler.Builder fileHandler(Path path) { return new Builder().withResourceProviderFactory(ResourceProviderFactory.fileBased(path)); } /** * Creates a handler that serves files from the classpath.. * @param classpathRoot A classpath directory, such as /web * @return A new builder. * @deprecated Use {@link ResourceHandlerBuilder#classpathHandler(String)} */ @Deprecated public static ResourceHandler.Builder classpathHandler(String classpathRoot) { return new Builder().withResourceProviderFactory(ResourceProviderFactory.classpathBased(classpathRoot)); } /** * Creates a resource handler that serves from the file system if the directory exists; otherwise from the class path. *

* A common use case is for when you want to serve from the file path at development time (so you can update * files without restarting) but at deploy time resources are packaged in an uber jar. * @param fileRootIfExists A path to a directory holding static content, which may not exist, e.g. src/main/resources/web * @param classpathRoot A classpath path to a directory holding static content, e.g. /web * @return Returns a file-based resource handler builder or a classpath-based one. * @deprecated Use {@link ResourceHandlerBuilder#fileOrClasspath(String, String)} */ @Deprecated public static ResourceHandler.Builder fileOrClasspath(String fileRootIfExists, String classpathRoot) { Path path = Paths.get(fileRootIfExists); if (Files.isDirectory(path)) { return fileHandler(path); } else { return classpathHandler(classpathRoot); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy