-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Describe the bug
Right now, an http maid where I did not configure CORS with CorsConfigurators will return an HTTP 500 for a path that is otherwise recognized (albeit for a different method)
To Reproduce
@NotNull
private static QuantumMaid serverInstance(int port) {
QuantumMaid quantumMaid = quantumMaid()
.withHttpMaid(anHttpMaid()
.get("/*", dumpRequest())
.post("/*", dumpRequest())
.put("/*", dumpRequest())
.delete("/*", dumpRequest()).build())
.withLocalHostEndpointOnPort(port);
return quantumMaid;
}client request:
$ curl -v localhost:8080 -XOPTIONS
* Rebuilt URL to: localhost:8080/
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> OPTIONS / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Date: Mon, 01 Jun 2020 08:18:51 GMT
< Transfer-encoding: chunked
<
* Connection #0 to host localhost left intactserver output:
11:19:49.485 [HTTP-Dispatcher] ERROR de.quantummaid.httpmaid.exceptions.DefaultExceptionMapper - Exception during request processing
PATH = Path(path=/)
QUERY_PARAMETERS = QueryParameters(queryParameters={})
RESPONSE_STATUS = 500
REQUEST_BODY_STRING =
EXCEPTION = de.quantummaid.httpmaid.handler.PageNotFoundException: No handler found for path '/' and method 'OPTIONS'
PATH = Path(path=/)
QUERY_PARAMETERS = QueryParameters(queryParameters={})
RESPONSE_STATUS = 200
REQUEST_BODY_STRING =
UNMARSHALLED_REQUEST_BODY = null
RAW_METHOD = OPTIONS
IS_HTTP_REQUEST = true
REQUEST_CONTENT_TYPE = ContentType(value=null)
RESPONSE_HEADERS = {}
REQUEST_BODY_STREAM = sun.net.httpserver.FixedLengthInputStream@2704bf89
RAW_PATH = /
RAW_REQUEST_QUERY_PARAMETERS = {}
METHOD = HttpRequestMethod(value=OPTIONS)
RAW_REQUEST_HEADERS = sun.net.httpserver.UnmodifiableHeaders@29740f87
REQUEST_HEADERS = Headers(headers={HeaderKey(value=user-agent)=HeaderValue(value=curl/7.47.0), HeaderKey(value=host)=HeaderValue(value=localhost:8080), HeaderKey(value=accept)=HeaderValue(value=*/*)})
UNMARSHALLED_REQUEST_BODY = null
RAW_METHOD = OPTIONS
IS_HTTP_REQUEST = true
REQUEST_CONTENT_TYPE = ContentType(value=null)
RESPONSE_HEADERS = {}
REQUEST_BODY_STREAM = sun.net.httpserver.FixedLengthInputStream@2704bf89
RAW_PATH = /
RAW_REQUEST_QUERY_PARAMETERS = {}
METHOD = HttpRequestMethod(value=OPTIONS)
RAW_REQUEST_HEADERS = sun.net.httpserver.UnmodifiableHeaders@29740f87
REQUEST_HEADERS = Headers(headers={HeaderKey(value=user-agent)=HeaderValue(value=curl/7.47.0), HeaderKey(value=host)=HeaderValue(value=localhost:8080), HeaderKey(value=accept)=HeaderValue(value=*/*)})
de.quantummaid.httpmaid.handler.PageNotFoundException: No handler found for path '/' and method 'OPTIONS'
PATH = Path(path=/)
QUERY_PARAMETERS = QueryParameters(queryParameters={})
RESPONSE_STATUS = 200
REQUEST_BODY_STRING =
UNMARSHALLED_REQUEST_BODY = null
RAW_METHOD = OPTIONS
IS_HTTP_REQUEST = true
REQUEST_CONTENT_TYPE = ContentType(value=null)
RESPONSE_HEADERS = {}
REQUEST_BODY_STREAM = sun.net.httpserver.FixedLengthInputStream@2704bf89
RAW_PATH = /
RAW_REQUEST_QUERY_PARAMETERS = {}
METHOD = HttpRequestMethod(value=OPTIONS)
RAW_REQUEST_HEADERS = sun.net.httpserver.UnmodifiableHeaders@29740f87
REQUEST_HEADERS = Headers(headers={HeaderKey(value=user-agent)=HeaderValue(value=curl/7.47.0), HeaderKey(value=host)=HeaderValue(value=localhost:8080), HeaderKey(value=accept)=HeaderValue(value=*/*)})
at de.quantummaid.httpmaid.handler.PageNotFoundException.pageNotFoundException(PageNotFoundException.java:41)
at de.quantummaid.httpmaid.handler.InvokeHandlerProcessor.lambda$apply$0(InvokeHandlerProcessor.java:45)
at java.base/java.util.Optional.orElseThrow(Optional.java:408)
at de.quantummaid.httpmaid.handler.InvokeHandlerProcessor.apply(InvokeHandlerProcessor.java:45)
at de.quantummaid.httpmaid.chains.Chain.lambda$accept$0(Chain.java:74)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1239)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at de.quantummaid.httpmaid.chains.Chain.accept(Chain.java:74)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:69)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
at de.quantummaid.httpmaid.chains.ChainRegistry.putIntoChain(ChainRegistry.java:63)
at de.quantummaid.httpmaid.HttpMaid.handleRequest(HttpMaid.java:85)
at de.quantummaid.httpmaid.endpoint.purejavaendpoint.PureJavaEndpointHandler.handle(PureJavaEndpointHandler.java:48)
at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
at jdk.httpserver/sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:82)
at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
at jdk.httpserver/sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:692)
at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
at jdk.httpserver/sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:664)
at jdk.httpserver/sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:159)
at jdk.httpserver/sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:442)
at jdk.httpserver/sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:408)
at java.base/java.lang.Thread.run(Thread.java:834)
Expected behavior
If the path is known, and CORS is not configured, it should deny by default.
According to https://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request, denial looks like this:
If the server wants to deny the CORS request, it can just return a generic response (like HTTP 200), without any CORS header. The server may want to deny the request if the HTTP method or headers requested in the preflight are not valid. Since there are no CORS-specific headers in the response, the browser assumes the request is invalid, and doesn’t make the actual request:
Note: Using regular expressions to express input classes
When Cors has not been configured
request:
OPTIONS / HTTP/1.1
Origin: (.*)
Access-Control-Request-Method: (.*)
Access-Control-Request-Headers: (.*)
response:
HTTP/1.1 200 OK
Content-Type: Content-Type: text/html; charset=utf-8
NO Access-Control-Allow-Origin
NO Access-Control-Allow-Methods
NO Access-Control-Allow-Headers
- project version used: httpmaid 0.9.61 (bom 1.0.48)
- Java version used: 11