1

I have an API with the following stack:

Sinatra <=HTTPS/TLS=> Nginx <=HTTPS/TLS=> ALB(ELBv2)

It's a basic URL shortener that sends a 301 redirect to the browser to go to the longer URL. This was working flawlessly for a year or two, but since Chrome 58, I now get ERR_SPDY_PROTOCOL_ERROR on redirects from the API in Chrome. Regular pages return just fine, and other browsers work fine. The reply is definitely sent by the ALB, as I see traffic flow, and there's no errors reported in CloudWatch or in the logs for either Nginx or Sinatra.

I've opened a ticket with AWS Support, but I haven't gotten much useful from it. Has anyone else seen something similar? I'm not even sure what to try to fix this, since my nginx isn't even configured to use SPDY or HTTP2.

EDIT: Here's an ALB sample access log for the broken attempt and a working (via curl):

h2 2017-06-21T15:30:01.438546Z app/aws-example-net/019315b3036f76ac 184.75.37.61:59367 10.252.14.202:443 0.000 0.004 0.000 301 301 30 1170 "GET https://aws.example.net:443/short/-OpLPG8h HTTP/2.0" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36" ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:us-east-1:XXXXXXXXXXXX:targetgroup/ecs-prod-e-urlshortener/7c6cddcc83c91aeb "Root=1-594a90f9-41b321bf039f142a083cb587"
h2 2017-06-21T15:30:06.928711Z app/aws-example-net/019315b3036f76ac 184.75.37.61:19376 10.252.14.202:443 0.000 0.004 0.000 301 301 46 1170 "GET https://aws.example.net:443/short/-OpLPG8h HTTP/2.0" "curl/7.50.1" ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:us-east-1:XXXXXXXXXXXX:targetgroup/ecs-prod-e-urlshortener/7c6cddcc83c91aeb "Root=1-594a90fe-2f1b92043fe3030461e84219"

EDIT 2:

Sanitized example output from curl -vvv:

https://pastebin.com/Ws553Mxj

Dan R
  • 255
  • 1
  • 3
  • 13
  • Nginx shouldn't see any SPDY or HTTP/2 even if enabled in this configuration, but ALB speaks HTTP/2 and transforms it to HTTP/1.1 toward Nginx. What's in the ALB log? – Michael - sqlbot Jun 20 '17 at 22:02
  • @Michael-sqlbot - I added the access logs – Dan R Jun 21 '17 at 15:40
  • Wild, crazy, and entirely unjustified speculation: you're returning something in the response headers that should be valid, but it tickles a bug in Chrome and sends it down the wrong code path, triggering the error. Can you show the response headers (from `curl`) with only as much sanitization as necessary? – Michael - sqlbot Jun 21 '17 at 16:49
  • Can you provide a test URL that exhibits the behavior? Does the site redirect to itself (same host, different/longer path) or to a different site? Does this break 100% of the time? All URLs, or always but only for certain URLs, etc.? – Michael - sqlbot Jun 21 '17 at 16:55
  • @Michael-sqlbot I added a pastebin of the curl output, working on getting a test URL up... the URL's (by design) disappear after being retrieved, so I need to tweak it to setup a permanent redirect. – Dan R Jun 21 '17 at 19:51
  • I may have just run into this issue too.. Works with Chrome <- Nginx <- Node.js. but fails with the spdy error on Chrome <- ALB <- Nginx <- Node.js... Going to try and do some more digging... – calebboyd Jul 09 '17 at 07:48
  • Good luck! I ended up rewriting the app as a lambda/API Gateway, since it was pretty trivial anyway. – Dan R Aug 07 '17 at 16:43

1 Answers1

1

We ran into this problem just now. Our app was setting the "Content-Length" header and using gzip. Apparently http/2 doesn't like that combo!

Removed "Content-Length" and it works.

Sean256
  • 161
  • 1
  • 5
  • very cool! I'll see if I left that API up and see if I can fix it. I ended up rewriting it as labmda + api gateway instead. – Dan R Jan 23 '18 at 16:44