10
votes

If I curl a POST request with file upload to my google compute load balancer (LB) I get a 502 error. If I do the same curl to the worker node behind the LB, it works. If I use a library like PHP Guzzle, it works either way. If I do a basic GET request on the LB, I get the correct response but the worker log does not acknowledge receiving the request as if the LB cached it. What is going on? FYI, google LB newb. Thanks

Edit:

I'm using GCE HTTP LB. The Curl command looks like this:

curl http://1.2.3.4 -F "key=value" -F "data=@path/to/file"

This curl command works when using the GCE VM IP but does NOT when using the GCE HTTP LB IP.

2
three questions: 1. is this a GCE HTTP LB or Network LB? 2. how do you use curl POST to upload? 3. how does it look like the request header of a successful request through PHP Guzzle library.Kamran
@Kamran I updated my post, as to your Guzzle question, I will try to find out shortly.Matthew Scragg
did you resolve this issue?Kamran
Experiencing the same thing with trying to POST some JSONMatt W
Having the same issue POSTing to LB IP with curl in PHP...MDrollette

2 Answers

5
votes

This one line of code fixed it for me:

curl_setopt($ch, CURLOPT_HTTPHEADER, ['Expect:']);

You obviously need to add the empty Expect: header to whatever other headers you're sending up, but that header is what fixes cURL for use with Google HTTP load balancers.

More Info

The Google document Setting Up HTTP(S) Load Balancing has a note near the bottom in the Notes and Restrictions section saying that HTTP/1.1 100 Continue responses are not supported.

It seems that by default cURL will always set Expect: 100-continue headers when you send a POST request. Thus apparently cURL is unable to send POST through a GCE HTTP load balancer by default.

On the end-user side, you just see 502 responses coming back from Google, which is all the more confusing since making the exact same POST to a server that is not behind the load balancer works perfectly fine.

However, presence of Expect: 100-continue causes the Google Load Balancer to freak out and break the request.

On the server side the POST data cannot be parsed (it does not even arrive to the server, though the Content-Length is reported correctly). In my case this caused the server to return a 500 Internal Server Error, which the GCE LB munges and sends back to the user as a 502 Bad Gateway error.

After adding an empty Expect: header, my POST data is making it to my load balanced VMs correctly, they're parsing and returning valid responses, and my client is getting a 200 instead of a 502.

Thanks to this question which helped shed some light on the issue.

1
votes

Traffic from the load balancer to your instance is not enabled by default. Unfortunately this is not well documented, and really, when you create a load balancer this should happen automatically.

Try adding this firewall rule the network that your load balancer and VMs are on:

130.211.0.0/22   tcp:1-5000   Apply to all targets