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

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

The newest version!
package io.muserver.rest;

import io.muserver.Method;
import io.muserver.MuServerBuilder;
import io.muserver.Mutils;
import io.muserver.handlers.CORSHandlerBuilder;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import static java.util.Arrays.asList;

/**
 * 

A builder to set configuration for CORS requests.

*/ public class CORSConfigBuilder { private boolean allowCredentials = false; private Collection allowedOrigins = Collections.emptySet(); private List allowedOriginRegex = new ArrayList<>(); private Collection exposedHeaders = Collections.emptySet(); private Collection allowedHeaders = Collections.emptySet(); private long maxAge = -1; /** * All origins will be allowed * @return This builder */ public CORSConfigBuilder withAllOriginsAllowed() { return withAllowedOrigins((Collection)null); } /** * If set to true, then access-control-allow-credentials is returned with true on CORS responses. * @param allowCredentials Whether or not to include the credentials header * @return This builder */ public CORSConfigBuilder withAllowCredentials(boolean allowCredentials) { this.allowCredentials = allowCredentials; return this; } /** * The origin values that CORS requests are allowed for, or null to allow all origins. * @param allowedOrigins Allowed origins, such as https://example.org or http://localhost:8080 * @return This builder */ public CORSConfigBuilder withAllowedOrigins(Collection allowedOrigins) { if (allowedOrigins != null) { for (String allowedOrigin : allowedOrigins) { if (!allowedOrigin.startsWith("http://") && !allowedOrigin.startsWith("https://")) { throw new IllegalArgumentException(allowedOrigin + " is invalid: origins much have an http:// or https:// prefix"); } if (allowedOrigin.lastIndexOf('/') > 8) { throw new IllegalArgumentException(allowedOrigin + " is invalid: origins should not have any paths. Example origin: https://example.org"); } } } this.allowedOrigins = allowedOrigins; return this; } /** * The origin values that CORS requests are allowed for. * @param allowedOrigins Allowed origins, such as https://example.org or http://localhost:8080 * @return This builder */ public CORSConfigBuilder withAllowedOrigins(String... allowedOrigins) { return withAllowedOrigins(asList(allowedOrigins)); } /** *

The origin values that CORS requests are allowed for.

*

If called multiple times, then just one of the patterns need to match to allow the origin.

*

Note: this is a no-op if null is used.

* @param allowedOriginRegex A regex to match, e.g. Pattern.compile("https://.*\\.example\\.org") to allow * all subdomains of example.org over HTTPS. * @return This builder */ public CORSConfigBuilder withAllowedOriginRegex(Pattern allowedOriginRegex) { if (allowedOriginRegex != null) { this.allowedOriginRegex.add(allowedOriginRegex); } return this; } /** *

The origin values that CORS requests are allowed for.

*

If called multiple times, then just one of the patterns need to match to allow the origin.

*

Note: this is a no-op if null is used.

* @param allowedOriginRegex A regex to match, e.g. "https://.*\\.example\\.org" to allow * all subdomains of example.org over HTTPS. * @return This builder * @throws PatternSyntaxException If the expression's syntax is invalid */ public CORSConfigBuilder withAllowedOriginRegex(String allowedOriginRegex) { if (allowedOriginRegex == null) { return this; } return withAllowedOriginRegex(Pattern.compile(allowedOriginRegex)); } /** * Adds all localhost URLs (whether http or https) as allowed origins. * @return This builder */ public CORSConfigBuilder withLocalhostAllowed() { return withAllowedOriginRegex(Pattern.compile("https?://localhost(:[0-9]+)?")); } /** *

Specifies which headers (aside from "simple" headers) are allowed to be accessed by JavaScript in responses.

*

The "simple" headers are: Cache-Control, Content-Language, * Content-Type, Expires, Last-Modified, Pragma * (so you do not need to specify these values).

* @param headerNames The names of headers to allow, for example Content-Type * @return This builder */ public CORSConfigBuilder withExposedHeaders(String... headerNames) { Mutils.notNull("headerNames", headerNames); return withExposedHeaders(asList(headerNames)); } /** *

Specifies which headers (aside from "simple" headers) are allowed to be accessed by JavaScript in responses.

*

The "simple" headers are: Cache-Control, Content-Language, * Content-Type, Expires, Last-Modified, Pragma * (so you do not need to specify these values).

* @param headerNames The names of headers to allow, for example Content-Type * @return This builder */ public CORSConfigBuilder withExposedHeaders(Collection headerNames) { Mutils.notNull("headerNames", headerNames); this.exposedHeaders = headerNames; return this; } /** *

On preflight OPTIONS requests, specifies which headers are allowed to be sent on the request, aside from the "simple" headers.

*

The "simple" headers are Accept, Accept-Language, Content-Language, * Content-Type (but only with a MIME type of application/x-www-form-urlencoded, multipart/form-data, or text/plain). * You do not need to specify the simple headers.

* @param headerNames The names of headers to allow, for example Content-Length * @return This builder */ public CORSConfigBuilder withAllowedHeaders(String... headerNames) { Mutils.notNull("headerNames", headerNames); return withAllowedHeaders(asList(headerNames)); } /** *

On preflight OPTIONS requests, specifies which headers are allowed to be sent on the request, aside from the "simple" headers.

*

The "simple" headers are Accept, Accept-Language, Content-Language, * Content-Type (but only with a MIME type of application/x-www-form-urlencoded, multipart/form-data, or text/plain). * You do not need to specify the simple headers.

* @param headerNames The names of headers to allow, for example Content-Length * @return This builder */ public CORSConfigBuilder withAllowedHeaders(Collection headerNames) { Mutils.notNull("headerNames", headerNames); this.allowedHeaders = headerNames; return this; } /** * On preflight OPTIONS requests, specifies the time the response is valid for * @param seconds The age in seconds, for example 600 for five minutes. * @return This builder. */ public CORSConfigBuilder withMaxAge(long seconds) { this.maxAge = seconds; return this; } /** * Creates a builder to set CORS configuration. Normally at least {@link #withAllowedOrigins(String...)} will be called. * @return A new builder to create CORS config with */ public static CORSConfigBuilder corsConfig() { return new CORSConfigBuilder() .withMaxAge(600); } /** * Creates CORS configuration that disables all CORS requests. * @return A new builder to create CORS config with */ public static CORSConfigBuilder disabled() { return new CORSConfigBuilder(); } /** * Creates a CORS handler from this config. *

This can be used when CORS configuration is needed outside of JAX-RS. Add the created handler to * a {@link MuServerBuilder} before any other handlers that require CORS config.

*

Note that if you only need CORS config for JAX-RS then instead of this method you should pass * this config to {@link RestHandlerBuilder#withCORS(CORSConfigBuilder)}

* @param allowedMethods The allowed methods for CORS calls * @return A handler that can be added. */ public CORSHandlerBuilder toHandler(Method... allowedMethods) { return CORSHandlerBuilder.corsHandler().withCORSConfig(this).withAllowedMethods(allowedMethods); } /** * Builds CORS configuration from a builder * @return An immutable configuration object. */ public CORSConfig build() { return new CORSConfig(allowCredentials, allowedOrigins, allowedOriginRegex, allowedHeaders, exposedHeaders, maxAge); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy