Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] OPTIONS request for a httpmaid not configured for CORS should respond with 200 and no Access-Control-Request-* response header (aka deny by default) #82

Open
lestephane opened this issue Jun 1, 2020 · 0 comments
Assignees
Labels
bug Something isn't working

Comments

@lestephane
Copy link

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 intact

server 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
@lestephane lestephane added the bug Something isn't working label Jun 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants