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

io.muserver.rest.CORSConfig Maven / Gradle / Ivy

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

import io.muserver.*;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;

/**
 * CORS configuration for REST resources. Create this using {@link CORSConfigBuilder#corsConfig()}
 */
public class CORSConfig {

    public final boolean allowCredentials;
    public final Collection allowedOrigins;
    public final List allowedOriginRegex;
    public final Collection exposedHeaders;
    public final long maxAge;
    private final String exposedHeadersCSV;

    CORSConfig(boolean allowCredentials, Collection allowedOrigins, List allowedOriginRegex, Collection exposedHeaders, long maxAge) {
        Mutils.notNull("allowedOriginRegex", allowedOriginRegex);
        this.allowCredentials = allowCredentials;
        this.allowedOrigins = Collections.unmodifiableCollection(allowedOrigins);
        this.allowedOriginRegex = allowedOriginRegex;
        this.exposedHeaders = Collections.unmodifiableCollection(exposedHeaders);
        this.maxAge = maxAge;
        this.exposedHeadersCSV = exposedHeaders.stream().sorted().collect(joining(", "));
    }

    boolean writeHeaders(MuRequest request, MuResponse response, Set matchedMethodsForPath) {

        response.headers().add(HeaderNames.VARY, HeaderNames.ORIGIN);

        String origin  = request.headers().get(HeaderNames.ORIGIN);
        if (Mutils.nullOrEmpty(origin)) {
            return false;
        }

        Headers respHeaders = response.headers();
        if (allowCors(origin)) {
            respHeaders.set(HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
            respHeaders.set(HeaderNames.ACCESS_CONTROL_ALLOW_METHODS, getAllowedMethods(matchedMethodsForPath));
            if (request.method() == Method.OPTIONS) {
                respHeaders.set(HeaderNames.ACCESS_CONTROL_MAX_AGE, maxAge);
                respHeaders.set(HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, exposedHeadersCSV);
            } else {
                respHeaders.set(HeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS, exposedHeadersCSV);
            }
            if (allowCredentials) {
                respHeaders.set(HeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
            }
            return true;
        } else {
            respHeaders.set(HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "null");
            return false;
        }

    }

    static String getAllowedMethods(Set matchedMethodsForPath) {
        Set allowed = matchedMethodsForPath.stream().map(m -> m.resourceMethod.httpMethod).collect(toSet());
        if (allowed.contains(Method.GET)) {
            allowed.add(Method.HEAD);
        }
        allowed.add(Method.OPTIONS);
        return allowed.stream().map(Enum::name).sorted().collect(joining(", "));
    }

    boolean allowCors(String origin) {
        if (allowedOrigins == null || allowedOrigins.contains(origin)) {
            return true;
        }
        for (Pattern pattern : allowedOriginRegex) {
            if (pattern.matcher(origin).matches()) {
                return true;
            }
        }
        return false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy