Package com.vtence.molecule.middlewares

Source Code of com.vtence.molecule.middlewares.FileServer

package com.vtence.molecule.middlewares;

import com.vtence.molecule.Application;
import com.vtence.molecule.lib.FileBody;
import com.vtence.molecule.http.HttpMethod;
import com.vtence.molecule.http.HttpStatus;
import com.vtence.molecule.Request;
import com.vtence.molecule.Response;
import com.vtence.molecule.http.HttpDate;
import com.vtence.molecule.helpers.Joiner;
import com.vtence.molecule.http.MimeTypes;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.vtence.molecule.http.HeaderNames.ALLOW;
import static com.vtence.molecule.http.HeaderNames.IF_MODIFIED_SINCE;
import static com.vtence.molecule.http.HeaderNames.LAST_MODIFIED;
import static com.vtence.molecule.http.HttpMethod.GET;
import static com.vtence.molecule.http.HttpMethod.HEAD;
import static com.vtence.molecule.http.HttpStatus.METHOD_NOT_ALLOWED;
import static com.vtence.molecule.http.HttpStatus.NOT_MODIFIED;

public class FileServer implements Application {

    private final File root;
    private final MimeTypes mediaTypes = MimeTypes.defaults();
    private final Map<String, String> headers = new HashMap<String, String>();

    private static final List<HttpMethod> ALLOWED_METHODS = Arrays.asList(GET, HEAD);
    private static final String ALLOW_HEADER = Joiner.on(", ").join(ALLOWED_METHODS);

    public FileServer(File root) {
        this.root = root;
    }

    public void registerMediaType(String extension, String mediaType) {
        mediaTypes.register(extension, mediaType);
    }

    public FileServer header(String header, String value) {
        headers.put(header, value);
        return this;
    }

    public void handle(Request request, Response response) throws Exception {
        if (!methodAllowed(request)) {
            response.set(ALLOW, ALLOW_HEADER);
            response.status(METHOD_NOT_ALLOWED);
            return;
        }

        File file = new File(root, request.path());
        if (!canServe(file)) {
            response.status(HttpStatus.NOT_FOUND);
            response.contentType(MimeTypes.TEXT);
            response.body("File not found: " + request.path());
            return;
        }

        if (notModifiedSince(lastTimeSeen(request), file)) {
            response.status(NOT_MODIFIED);
            return;
        }

        addFileHeaders(response, file);
        addCustomHeaders(response);

        response.status(HttpStatus.OK);
        if (head(request)) return;

        response.body(new FileBody(file));
    }

    private boolean canServe(File file) {
        return file.exists() && file.canRead() && !file.isDirectory();
    }

    private boolean methodAllowed(Request request) {
        return ALLOWED_METHODS.contains(request.method());
    }

    private boolean notModifiedSince(String date, File file) {
        return HttpDate.format(file.lastModified()).equals(date);
    }

    private String lastTimeSeen(Request request) {
        return request.header(IF_MODIFIED_SINCE);
    }

    private void addFileHeaders(Response response, File file) {
        response.contentType(mediaTypes.guessFrom(file.getName()));
        response.setDate(LAST_MODIFIED, file.lastModified());
        response.contentLength(file.length());
    }

    private void addCustomHeaders(Response response) {
        for (String header : headers.keySet()) {
            response.set(header, headers.get(header));
        }
    }

    private boolean head(Request request) {
        return request.method() == HEAD;
    }
}
TOP

Related Classes of com.vtence.molecule.middlewares.FileServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.