firebase / firebase-tools

The Firebase Command Line Tools
MIT License
4.02k stars 937 forks source link

HTTP function emulator forcibly handles all OPTIONS requests, and seems to assume they are all CORS preflight requests #6640

Open CodingDoug opened 10 months ago

CodingDoug commented 10 months ago

[REQUIRED] Environment info

firebase-tools: 13.0.2

Platform: macOS

[REQUIRED] Test case

Any OPTIONS request to an HTTP function.

[REQUIRED] Steps to reproduce

  1. Author any trivial HTTP function that logs anything upon invocation
  2. Run the emulator with it
  3. Send it an OPTIONS request, for example:
curl \
  -H "Origin: https://example.com" \
  -H "Access-Control-Request-Method: GET" \
  -H "Access-Control-Request-Headers: X-Requested-With" \
  -X OPTIONS \
  --verbose \
  [function url]

[REQUIRED] Expected behavior

I expect to see a log message for the invocation of the OPTIONS request.

[REQUIRED] Actual behavior

The emulator internally handles the OPTIONS request and doesn't invoke the function code. On top of that, it seems to assume that the OPTIONS request is a CORS preflight request. It always sends back a response that looks like this:

< HTTP/1.1 204 No Content
< x-powered-by: Express
< access-control-allow-origin: https://example.com
< vary: Origin, Access-Control-Request-Headers
< access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
< access-control-allow-headers: X-Requested-With
< content-length: 0
< date: Sat, 23 Dec 2023 21:20:36 GMT
< connection: close

Note also (as a second, separate problem here) that the access-control-allow-origin header is always exactly what was provided in the request Origin header, regardless of any actual cors configuration that would send otherwise. Also the access-control-allow-methods is always the same and never what the function wants to send (because it can't actually handle the cors response).

This behavior is problematic because I can't test my own OPTIONS handling, or any 3rd party CORS handling libraries. I have to deploy the code to see a proper OPTIONS invocation with the response that I want.

I understand this behavior makes it easy to get started working with HTTP and callable functions, but it's not accurate emulation, and leads to potential disappointment or frustration upon deployment.

AJAY-P-37 commented 1 month ago

@taeold / @joehan - do we have any updates on fixing this issue? I'm also facing this issue. Just a basic cloud function won't even get called when the request method is OPTIONS

exports.app = onRequest((request, response) => { response.send("Hello from Firebase!"); });