HTTP handler 502 errors on OPTIONS request

I deployed an Alpine container with Webdis and Redis to Fly. When using Fly HTTP+TLS handler, OPTIONS requests would respond with HTTP error 502 and only headers server, via, fly-request-id, date. Specifically, this caused a problem where Firefox would not allow GET requests to the service because it could not get the Access-Control-Allow-Origin header from Webdis with its pre-flight OPTIONS request. No-CORS GET requests were working fine and returning correct headers, but no-cors requests will make Firefox omit the Authorization header. I found that disabling the Fly HTTP handler and just using TLS would work fine to pass requests directly to Webdis for the time being.

Oh, that seems wrong of us.

Can you show give us a curl reproduction?

Looks like our proxy detected invalid headers and therefore returned a 502, this might be a mistake on our end.

Here is what Firefox generates for a cURL command representing its OPTIONS request. I broke lines and omitted details with XYZZY. This is 200 OK when only using the tls handler, but error 502 when using http and tls handler.

curl -v '' -X OPTIONS \
-H 'User-Agent: XYZZY' \
-H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br' -H 'Referer: https://XYZZY/' \
-H 'Access-Control-Request-Method: GET' \
-H 'Access-Control-Request-Headers: authorization' \
-H 'Origin: https://XYZZY' -H 'DNT: 1' \
-H 'Connection: keep-alive' -H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: no-cors' -H 'Sec-Fetch-Site: cross-site' \
-H 'TE: trailers' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache'

Thank you! I’ll try to reproduce with a test app.

I believe Webdis is returning in invalid header.

* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=*
*  start date: Jan 26 03:44:03 2022 GMT
*  expire date: Apr 26 03:44:02 2022 GMT
*  subjectAltName: host "" matched cert's "*"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
> Host:
> User-Agent: curl/7.77.0
> Accept: */*
> Accept-Language: en-US,en;q=0.5
> Accept-Encoding: gzip, deflate, br
> Referer: https://XYZZY/
> Access-Control-Request-Method: GET
> Access-Control-Request-Headers: authorization
> Origin: https://XYZZY
> DNT: 1
> Connection: keep-alive
> Sec-Fetch-Dest: empty
> Sec-Fetch-Mode: no-cors
> Sec-Fetch-Site: cross-site
> TE: trailers
> Pragma: no-cache
> Cache-Control: no-cache
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Webdis
< Access-Control-Allow-Methods: GET,POST,PUT,OPTIONS
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization
< Connection: Keep-Alive
< Content-Type: text/html
< Content-Length: 0
< :
* Connection #0 to host left intact

Specifically, this part here in the response headers:

< Content-Length: 0
< :

It seems like it sends back a header with no name and no value. Our proxy doesn’t allow that.

Thanks for looking into this. I filed an issue for Webdis. OPTIONS response has invalid blank header with no value · Issue #217 · nicolasff/webdis · GitHub