haproxy will get 404 error for about 2-3 seconds if one of backend server down - http-status-code-404

this is the haproxy config.
defaults
option forwardfor
log global
option httplog
log 127.0.0.1 local3
option dontlognull
retries 3
option redispatch
timeout connect 5000ms
timeout client 5000ms
timeout server 5000ms
listen stats
bind *:9000
mode http
..............................................
backend testhosts
mode http
balance roundrobin
option httpchk HEAD /sabrix/scripts/menu-common.js
server host1 11.11.11.11:9080 check inter 2000 rise 1 fall 2
server host2 11.11.11.12:9080 check inter 2000 rise 1 fall 2
if service of 11.11.11.11 is down, haproxy will get 503 and 404 error about 2-3 seconds( it depends inter value, if inter value is very
small, the number of 404 error will be decreased).
2020-08-25T11:58:14 11.11.11.11:9080 200 POST /tsturl1 HTTP/1.1 2274
2020-08-25T11:58:14 11.11.11.22:9080 200 POST /tsturl1 HTTP/1.1 448
2020-08-25T11:58:14 11.11.11.11:9080 503 POST /tsturl1 HTTP/1.1 0
2020-08-25T11:58:14 11.11.11.11:9080 404 POST /tsturl1 HTTP/1.1 0
2020-08-25T11:58:14 11.11.11.11:9080 200 POST /tsturl1 HTTP/1.1 1503
2020-08-25T11:58:16 11.11.11.22:9080 200 POST /tsturl1 HTTP/1.1 617
2020-08-25T11:58:16 11.11.11.11:9080 404 POST /tsturl1 HTTP/1.1 0
2020-08-25T11:58:16 11.11.11.22:9080 200 POST /tsturl1 HTTP/1.1 618
2020-08-25T11:58:16 11.11.11.11:9080 404 POST /tsturl1 HTTP/1.1 0
2020-08-25T11:58:16 host1 is DOWN, reason: Layer7 wrong status, code: 404, info: "Not Found", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
2020-08-25T11:58:16 11.11.11.22:9080 200 POST /tsturl1 HTTP/1.1 645
2020-08-25T11:58:16 11.11.11.22:9080 200 POST /tsturl1 HTTP/1.1 618\
My question is :
why the parameter retry didn't work ? is it possible for the user always get 200 code rather than 400 error even when one of the backend server down ?
I'm using Haproxy 1.5.18.
THanks a lot

In the version you are using retries is for Layer 4 (i.e. connection timeout). HAProxy 2.0 introduced Layer 7 retries. These 2 blog posts may be helpful:
HAProxy 2.0
Layer 7 Retries and Chaos Engineering

Related

hawkBit swupdate Suricatta: HTTP/1.1 401 Unauthorized

I want to set up hawkBit (running on server) and swupdate (running on multiple clients - Linux OS) to perform OS/Software update in Suricatta mode.
1/ Follow up my post on hawkBit community, I've succeeded to run hawkBit in my server as below:
Exported to external link: http://:
Enabled MariaDB
Enabled Gateway Token Authentication (in hawkBit system configuration)
Created a software module
Uploaded an artifact
Created a distribution set
Assigned the software module to the distribution set
Create Targets (in Deployment Mangement UI) with Targets ID is "dev01"
Created a Rollout
Created a Target Filter
2/ I've succeeded to build/execute swupdate as SWupdate guideline
Enabled Suricatta daemon mode
Run swupdate: /usr/bin/swupdate -v -k /etc/public.pem -u '-t DEFAULT -u http://<domain>:<port> -i dev01'
I'm pretty sure this command isn't correct, output log as below:
* Trying <ip address>...
* TCP_NODELAY set
* Connected to <domain> (<ip address>) port <port> (#0)
> GET /DEFAULT/controller/v1/10 HTTP/1.1
Host: <domain>:<port>
User-Agent: libcurl-agent/1.0
Content-Type: application/json
Accept: application/json
charsets: utf-8
< HTTP/1.1 401 Unauthorized
< Date: Sun, 16 May 2021 02:43:40 GMT
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Length: 0
<
* Connection #0 to host <domain> left intact
[TRACE] : SWUPDATE running : [channel_log_effective_url] : Channel's effective URL resolved to http://<domain>:<port>/DEFAULT/controller/v1/dev01
[ERROR] : SWUPDATE failed [0] ERROR corelib/channel_curl.c : channel_get : 1109 : Channel operation returned HTTP error code 401.
[DEBUG] : SWUPDATE running : [suricatta_wait] : Sleeping for 45 seconds.
As per a suggestion from #laverman on Gitter:
You can use Gateway token in the Auth header of the request, e.g. “Authorization : GatewayToken a56cacb7290a8d8a96a2f149ab2f23d1”
but I don't know how the client sends this request (it should be sent by swupdate, right?)
3/ Follow up these instructions from Tutorial # EclipseCon Europe 2019, it guides me to send the request to provision multiple clients from hawkBit Device Simulator. And the problem is how to apply this to real devices.
Another confusion is: when creating new Software Module, Distribution on hawkBit UI, I can't find the ID of these, but creating by send request as Tutorial, I can see the IDs in the response.
So my questions are:
1/ Are my hawkBit setup steps correct?
2/ How can I configure/run swupdate (on clients) to perform the update: poll for new software, download, update, report status, ...
If my description isn't clear enough, please tell me.
Thanks
happy to see that you're trying out Hawkbit for your solution!
I have a few remarks:
The suricatta parameter for GatewayToken is -g, and -k for TargetToken respectively.
The -g <GATEWAY_TOKEN> needs to be set inside of the quotation marks
see SwUpdate Documentation
Example: /usr/bin/swupdate -v -u '-t DEFAULT -u http://<domain>:<port> -i dev01 -g 76430e1830c56f2ea656c9bbc88834a3'
For the GatewayToken Authentication, you need to provide the generated token in System Config view, it is a generated hashcode that looks similar to this example here
You can also authenticate each device/client separately using their own TargetToken.
You can find more information in the Hawkbit documentation

Flink 1.6.0 job jar upload size limit

What's job jar file size limit and is there a chance I could override it ?
With Flink 1.6.0 out and with a fully RESTified job submission I tried uploading jar like:
$ curl http://localhost:8081/jars/upload -X POST -F "jarfile=#word-count-beam/target/word-count-beam-bundled-0.1.jar" --verbose
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8081 (#0)
> POST /jars/upload HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 108716165
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------ab44aa4cd2db3c75
>
* Done waiting for 100-continue
< HTTP/1.1 413 Request Entity Too Large
< content-length: 0
* HTTP error before end of send, stop sending
<
* Closing connection 0
but I get:
413 Request Entity Too Large
Actual jar file size is:
$ du -h word-count-beam/target/word-count-beam-bundled-0.1.jar
113M word-count-beam/target/word-count-beam-bundled-0.1.jar
I'm running Flink in docker using 1.6.0-scala_2.11 image.
UPDATE: it's same when trying uploading from Web UI:
NOTE: jar upload feature worked with Flink 1.5 (Docker).
#robosoul , I think there is a rest limit in config, by default the max size is 104857600 in bytes, looks like you are exceeding the limit

Google's resumable video upload status API endpoint for Google Drive is failing with HTTP 400: "Failed to parse Content-Range header.":

In order to resume an interrupted upload to Google Drive, we have implemented status requests to Google's API following this guide.
https://developers.google.com/drive/v3/web/resumable-upload#resume-upload
Request:
PUT
https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=UPLOAD_ID HTTP/1.1
Content-Length: 0
Content-Range: bytes */*
It works perfectly in most of the cases. However, the following error occurs occasionally and even retries of the same call result in the same erroneous response.
Response:
HTTP 400: "Failed to parse Content-Range header."
We are using the google.appengine.api.urlfetch Python library to make this request in our Python App Engine backend.
Any ideas?
EDIT:
I could replicate this issue using cURL
curl -X PUT 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=UPLOAD_ID' -H 'Content-Length: 0' -vvvv -H 'Content-Range: bytes */*'
Response:
* Trying 172.217.25.138...
* Connected to www.googleapis.com (172.217.25.138) port 443 (#0)
* found 173 certificates in /etc/ssl/certs/ca-certificates.crt
* found 697 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* common name: *.googleapis.com (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: C=US,ST=California,L=Mountain View,O=Google Inc,CN=*.googleapis.com
* start date: Thu, 16 Mar 2017 08:54:00 GMT
* expire date: Thu, 08 Jun 2017 08:54:00 GMT
* issuer: C=US,O=Google Inc,CN=Google Internet Authority G2
* compression: NULL
* ALPN, server accepted to use http/1.1
> PUT /upload/drive/v3/files?uploadType=resumable&upload_id=UPLOAD_ID HTTP/1.1
> Host: www.googleapis.com
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 0
> Content-Range: bytes */*
>
< HTTP/1.1 400 Bad Request
< X-GUploader-UploadID: UPLOAD_ID
< Content-Type:
< X-GUploader-UploadID: UPLOAD_ID
< Content-Length: 37
< Date: Thu, 23 Mar 2017 22:45:58 GMT
< Server: UploadServer
< Content-Type: text/html; charset=UTF-8
< Alt-Svc: quic=":443"; ma=2592000; v="37,36,35"
<
* Connection #0 to host www.googleapis.com left intact
Failed to parse Content-Range header.

Why is POST Response Data Not Received in Internet Explorer?

I have an AngularJS web app that accesses a .NET WebAPI server end. Authentication is implemented through the AngularJS-OAuth2 library. I have the app and the WebAPI hosted in localhost under two different port numbers. I have also enabled Microsoft.Owin.Cors package on the server end to handle cross-domain requests.
In Chrome, GET and POST requests return data to the front-end. By inspecting the traffic through Fiddler I could see that a pair of requests/responses are sent (preflight/OPTIONS + actual) and also the relevant CORS headers (including origin and Access-Control-* headers) in both the requests and the responses. All as expected.
However, in Internet Explorer, my GET requests return data through the $http service but the POST does not. I could inspect that there are no preflight requests or CORS headers (I think IE treats different ports as the same origin). In checking the POST request/response in IE through Fiddler I could observe that it returns HTTP status 200 but state of Aborted (with X-ABORTED-WHEN: SendingResponse flag set). I could also inspect the JSON response with the correct data returned.
I have also tried setting a high timeout to no avail. The $http call looks like this:
return $http.post(apiUrl + "/search", service.getParameters(), { timeout: 600000 })
.success(function (data) {...
Fiddler shows something like this for the IE POST request:
Also (only) in IE, an unintentional page refresh is also triggered with the same button click as this POST operation.
Why does Internet Explorer abort only the POST requests when the correct data is also returned to the client and when Chrome does not have any issues at all?
Additional Information
Request:
POST https://localhost:44321/api//search HTTP/1.1
Content-Type: application/json;charset=utf-8
Accept: application/json, text/plain, */*
Authorization: Bearer <token>
Referer: https://localhost:44322/search
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: localhost:44321
Content-Length: 202
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: .ASPXANONYMOUS=<cookie>
Reponse:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: <file>
X-Powered-By: ASP.NET
Date: Wed, 10 Feb 2016 13:43:45 GMT
Content-Length: 2284
Fiddler session properties:
SESSION STATE: Aborted.
Request Entity Size: 202 bytes.
Response Entity Size: 2284 bytes.
== FLAGS ==================
BitFlags: [IsHTTPS, ClientPipeReused, ServerPipeReused] 0x19
X-ABORTED-WHEN: SendingResponse
X-CLIENTIP: 127.0.0.1
X-CLIENTPORT: 41889
X-EGRESSPORT: 41890
X-HOSTIP: ::1
X-PROCESSINFO: avp:3584
X-RESPONSEBODYTRANSFERLENGTH: 2,284
X-SERVERSOCKET: REUSE ServerPipe#168
== TIMING INFO ============
ClientConnected: 19:13:42.408
ClientBeginRequest: 19:13:42.444
GotRequestHeaders: 19:13:42.444
ClientDoneRequest: 19:13:42.772
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 0ms
HTTPS Handshake: 0ms
ServerConnected: 19:13:42.413
FiddlerBeginRequest: 19:13:42.772
ServerGotRequest: 19:13:42.772
ServerBeginResponse: 19:13:45.360
GotResponseHeaders: 19:13:45.360
ServerDoneResponse: 19:13:45.360
ClientBeginResponse: 19:13:45.360
ClientDoneResponse: 19:13:45.360
Overall Elapsed: 0:00:02.915
The response was buffered before delivery to the client.
== WININET CACHE INFO ============
This URL is not present in the WinINET cache. [Code: 2]
* Note: Data above shows WinINET's current cache state, not the state at the time of the request.
* Note: Data above shows WinINET's Medium Integrity (non-Protected Mode) cache only.
I believe you get bitten by the P3P policy requirement of IE here:
Internet Explorer supports a cookie-restricting privacy feature called P3P. Web developers often get tripped up by it because no other browser implements the P3P standard.
It seems similar to those QAs:
CORS request with IE11
CORS doesn't work with cookies in IE10
Internet Explorer 10 is ignoring XMLHttpRequest 'xhr.withCredentials = true'
Here's a blog post with an example how to send P3P information. Here's a document from Microsoft about P3P configuration

Google App Engine not generating 304, instead generating 200 always

Google App engine always generates 200 for the url /test.js and
test.js is not a static resource, but a url pattern for dynamically generated content. The content will expire after N hours and a fresh content will be generated.
I've tried with Last-Modified, ETag and Cache-Control. None seems to work.
Request
Request URL:http://localhost:8081/test.js
Request Method:GET
Status Code: 200 OK
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8081
If-Modified-Since:Fri, 18 Oct 2013 14:10:39 GMT
If-None-Match:"1B2M2Y8AsgTpgAmY7PhCfg"
Referer:http://localhost:8080/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Response Headers
cache-control:public, max-age=360000
Content-Length:2
content-type:application/script; charset=utf-8
Date:Fri, 18 Oct 2013 14:10:40 GMT
etag:"1B2M2Y8AsgTpgAmY7PhCfg"
expires:Tue, 22 Oct 2013 18:10:40 GMT
last-modified:Fri, 18 Oct 2013 14:10:40 GMT
Server:Development/2.0
Your request has Cache-Control:max-age=0, so any intermediate caches (incl. the browser-cache) won't serve cached content. This is likely a result of a setting in your browser.
For requests with revalidate headers (If-X), you need to have the logic in place to act properly. To save bandwidth, this is pretty simple with
webob (which is used by webapp2 and other frameworks) and the conditional-response setting. Avoiding computation as well depends a little more on what you're doing, but webob helps here too.
Redbot is a really useful tool for checking HTTP cache behaviour.
Refer to this for HTTP status:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
200 is just the correct HTTP OK status, that doesn't have any interpretation on whether the resource is static or not. (Try any dynamic web page out there like e.g. facebook) and you will notice it's 200. Having a response of 200 is perfectly normal
for 304 it's "Not Modified" - As mentioned in w3 "The 304 response MUST NOT contain a message-body". This is not what you want.
In your case your concern should be to set the correct expiry time for these http header (do it within your program code), so that the browser always request for a fresh copy of content after the expiry time (e.g. after 1 hour):
cache-control:public, max-age=3600
expires:Tue, 20 Oct 2013 18:10:40 GMT

Resources