
PĂ«rfaqĂ«suesi i klientit tonĂ«, nĂ«ntĂ«ti i aplikacioneve tĂ« tĂ« cilit qĂ«ndron nĂ« re nga Microsoft (Azure), iu pĂ«rgjigj njĂ« problemi: qĂ« nga njĂ« kohĂ« e afĂ«rt, disa kĂ«rkesa tĂ« disa klientĂ«ve nga Evropa kanĂ« filluar tĂ« pĂ«rfundojnĂ« me gabimin 400 (). TĂ« gjitha aplikacionet janĂ« shkruar nĂ« .NET, tĂ« vendosura nĂ« KubernetesâŠ
Një nga aplikacionet është API, përmes së cilës në fund të fundit arrin gjithë trafiku. Ky trafik dëgjohet nga serveri HTTP , i konfigurur nga klienti .NET dhe i vendosur në pod. Na ndihmoi me debugimin fakti që kishte një përdorues të caktuar, për të cilin problemi shfaqej vazhdimisht. Megjithatë, gjithçka u komplikuar nga zinxhiri i trafikut:

Gabimi në Ingress dukej si më poshtë:
{
"number_fields":{
"status":400,
"request_time":0.001,
"bytes_sent":465,
"upstream_response_time":0,
"upstream_retries":0,
"bytes_received":2328
},
"stream":"stdout",
"string_fields":{
"ingress":"app",
"protocol":"HTTP/1.1",
"request_id":"f9ab8540407208a119463975afda90bc",
"path":"/api/sign-in",
"nginx_upstream_status":"400",
"service":"app",
"namespace":"production",
"location":"/front",
"scheme":"https",
"method":"POST",
"nginx_upstream_response_time":"0.000",
"nginx_upstream_bytes_received":"120",
"vhost":"api.app.example.com",
"host":"api.app.example.com",
"user":"",
"address":"83.41.81.250",
"nginx_upstream_addr":"10.240.0.110:80",
"referrer":"https://api.app.example.com/auth/login?long_encrypted_header",
"service_port":"http",
"user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
"time":"2019-03-06T18:29:16+00:00",
"content_kind":"cache-headers-not-present",
"request_query":""
},
"timestamp":"2019-03-06 18:29:16",
"labels":{
"app":"nginx",
"pod-template-generation":"6",
"controller-revision-hash":"1682636041"
},
"namespace":"kube-nginx-ingress",
"nsec":6726612,
"source":"kubernetes",
"host":"k8s-node-55555-0",
"pod_name":"nginx-v2hcb",
"container_name":"nginx",
"boolean_fields":{}
}Në këtë rast, Kestrel ktheu:
HTTP/1.1 400 Kërkesë e Keqe
Connection: close
Date: Mër, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0Madje, edhe me nivelin maksimal të detajimit, gabimi i Kestrel kishte jashtëzakonisht pak informacion të dobishëm:
{
"number_fields":{"ThreadId":76},
"stream":"stdout",
"string_fields":{
"EventId":"{"Id"=>17, "Name"=>"ConnectionBadRequest"}",
"SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
"ConnectionId":"0HLL2VJSST5KV",
"@mt":"Connection id "{ConnectionId}" data kërkese të keqe: "{message}"",
"@t":"2019-03-07T13:06:48.1449083Z",
"@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Kërkesë e keqe: tituj të pavlefshëm.n në Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)n në Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<ProcessRequestsAsync>d__185`1.MoveNext()",
"message":"Kërkesë e keqe: tituj të pavlefshëm."
},
"timestamp":"2019-03-07 13:06:48",
"labels":{
"pod-template-hash":"2368795483",
"service":"app"
},
"namespace":"production",
"nsec":145341848,
"source":"kubernetes",
"host":"k8s-node-55555-1",
"pod_name":"app-67bdcf98d7-mhktx",
"container_name":"app",
"boolean_fields":{}
}Duket se vetëm tcpdump do të ndihmojë në zgjidhjen e këtij problemi⊠por përsëris për zinxhirin e trafik:

Hetimi
E qartë, se është më mirë të dëgjosh trafik në atë nod konkret, ku Kubernetes ka vendosur pod: sasia e dump-it do të jetë e tillë, saqë do të mund të gjejë ndonjë gjë mjaft shpejt. Dhe në të vërtetë, kur u shqyrtua, u vërejt një kadër e tillë:
GET /back/user HTTP/1.1
Host: api.app.example.com
X-Request-ID: 27ceb14972da8c21a8f92904b3eff1e5
X-Real-IP: 83.41.81.250
X-Forwarded-For: 83.41.81.250
X-Forwarded-Host: api.app.example.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Original-URI: /front/back/user
X-Scheme: https
X-Original-Forwarded-For: 83.41.81.250
X-Nginx-Geo-Client-Country: Spain
X-Nginx-Geo-Client-City: M.laga
Accept-Encoding: gzip
CF-IPCountry: ES
CF-RAY: 4b345cfd1c4ac691-MAD
CF-Visitor: {"scheme":"https"}
pragma: no-cache
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
referer: https://app.example.com/auth/login
accept-language: en-US,en;q=0.9,en-GB;q=0.8,pl;q=0.7
cookie: many_encrypted_cookies; .AspNetCore.Identity.Application=something_encrypted;
CF-Connecting-IP: 83.41.81.250
True-Client-IP: 83.41.81.250
CDN-Loop: cloudflare
HTTP/1.1 400 Bad Request
Connection: close
Date: Wed, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0 Duke e vĂ«zhguar me kujdes dump-in, u vu re fjala M.laga. ĂshtĂ« e lehtĂ« tĂ« kuptohet se nĂ« SpanjĂ« nuk ka qytet M.laga (por ka ). Duke u kapur pas kĂ«saj ideje, shikuam konfigurimet e Ingress-it, ku pikasĂ«m snippet-in e futur njĂ« muaj mĂ« parĂ« (nĂ« kĂ«rkesĂ« tĂ« klientit) âpa dĂ«mshĂ«mâ snippet:
ingress.kubernetes.io/configuration-snippet: |
proxy_set_header X-Nginx-Geo-Client-Country $geoip_country_name;
proxy_set_header X-Nginx-Geo-Client-City $geoip_city;Për sa kohë që u çaktivizua kalimi i këtyre kokave, gjithçka kishte filluar të funksionojë! (Shpejt doli në pah se këto kokat nuk ishin më të nevojshme për vetë aplikacionin.)
Tani le tĂ« shohim problemin nĂ« njĂ« pamje mĂ« tĂ« pĂ«rgjithshme. ĂshtĂ« lehtĂ«sisht e riprodhueshme brenda aplikacionit, nĂ«se bĂ«jmĂ« njĂ« kĂ«rkesĂ« telnet nĂ« localhost:80:
GET /back/user HTTP/1.1
Host: api.app.example.com
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
Cookie: test=Desiree ⊠kthehet 401 Unauthorized, ashtu siç pritej. ĂfarĂ« do tĂ« ndodhĂ« nĂ«se bĂ«jmĂ«:
GET /back/user HTTP/1.1
Host: api.app.example.com
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
Cookie: test=Désirée?
Do tĂ« kthehet 400 Bad request â nĂ« logun e aplikacionit do tĂ« pĂ«rfitojmĂ« gabimin e njohur:
{
"@t":"2019-03-31T12:59:54.3746446Z",
"@mt":"Connection id "{ConnectionId}" bad request data: "{message}"",
"@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.n at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)n at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<ProcessRequestsAsync>d__185`1.MoveNext()",
"ConnectionId":"0HLLLR1J974L9",
"message":"Malformed request: invalid headers.",
"EventId":{
"Id":17,
"Name":"ConnectionBadRequest"
},
"SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
"ThreadId":71
}Përfundimet
Përkatësisht Kestrel të përpunoni në mënyrë korrekte HTTP-të me simbole të sakta në UTF-8, të pranishme në emrat e shumë qyteteve.
Faktori shtesĂ« nĂ« rastin tonĂ« Ă«shtĂ« se klienti aktualisht nuk planifikon tĂ« ndryshojĂ« implementimin e Kestrel. SidoqoftĂ«, çështjet nĂ« AspNetCore vetĂ« (, ) tregojnĂ« se kjo nuk do tĂ« ndihmojĂ«âŠ
Përmbledhje: shënimi nuk është më rreth problemeve specifike të Kestrel ose UTF-8 (në vitin 2019?!), por se vëmendja dhe studimi sistematik i çdo hapi gjatë kërkimit të problemit do të japin rezultate përfundimisht. Sukese!
P.S.
Lexoni gjithashtu në blogun tonë:
- «»;
- «»;
- «»;
- «»;
- «».
Burimi: habr.com
