cURL en het gebruik van gzip

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

- Ariën  -
Beheerder

- Ariën -

09/06/2019 19:34:05
Quote Anchor link
Van de week viel mij op dat een API die ik vaak gebruikt (de oudere NS-API) opeens niet meer met mijn server wou praten als ik een request deed. Het wachten duurde te lang, en het leek er gewoon op dat mijn IP op een blacklist zou staan.

Na lang zoeken kreeg ik van iemand de tip om eens een request met Gzip te proberen.
En warempel: Toen werkte het, met dit als resultaat aan code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
$url
= "https://webservices.ns.nl/ns-api-storingen?actual=true";
$username = "foo";
$password = "bar";
$headers = array(
    "Accept-Encoding: gzip, deflate"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
$response = curl_exec($ch);
// check for curl errors
if ( strlen($response) && (curl_errno($ch)==CURLE_OK) && (curl_getinfo($ch, CURLINFO_HTTP_CODE)==200) ) {
    // check for gzipped content
    if ( (ord($response[0])==0x1f) && (ord($response[1])==0x8b) ) {
        // skip header and ungzip the data
        $response = gzinflate(substr($response,10));
    }
}

curl_close($ch);

print_r($response);
?>


Nu vind ik het opvallend dat enkele anderen deze problemen niet hadden, en ik vraag me af hoe dat zit?
Is het niet zo dat je met een configuratie in PHP/de webserver ook altijd in PHP een request kan sturen met GZIP, en dat je het ook zelf weer kan encoden?
In mijn script pluis ik de request nog eens uit met onder meer gzinflate, maar ik heb het idee dat dit veel beter kan aan de hand van wat vaste configuratie.
 
PHP hulp

PHP hulp

28/03/2024 16:05:21
 
Thomas van den Heuvel

Thomas van den Heuvel

09/06/2019 23:13:31
Quote Anchor link
Wat ik eerst zou doen is een (uitgebreide) analyse maken van waarom je in eerste instantie op een blacklist terecht bent gekomen / de dienst niet langer toegankelijk was. Het helpt hierbij als je een soort van verbose log bijhoudt / had bijgehouden. Mogelijk was door een combinatie van instellingen jouw script op die webservice aan het hameren en ben je daarna op de zwarte lijst belandt (dit klinkt wat mij betreft nog steeds als het meest voor de hand liggende scenario).

Dan, als je de oorzaak / een concrete foutmelding hebt zou je eens verder kunnen gaan kijken. Mogelijk is de response helemaal niet ge-gzipped, maar wordt deze wel als zodanig geserveerd waardoor curl tript. Mogelijk is je curl-versie te oud waardoor deze incompatibel is geraakt met de webservice of bepaalde byte-sequences niet aankan... wie zal het zeggen? (Seriously though, controleer dit allebei zou ik zeggen, spuugt de webservice alles wel netjes uit op de manier dat het zegt dat het doet en is curl niet verouderd)

Vergelijk het met een RSS-feed die wordt geserveerd alsof deze geëncodeerd is met UTF-8, maar stiekem toch ISO-whatever is. Sja, dan krijg je stront. Mogelijk is hier hetzelfde aan de hand.

Wellicht biedt de bovenstaande oplossing/workaround soelaas, maar wat heb je dan precies opgelost, want je weet nog steeds niet (goed) wat er misging. Ook ziet het er een beetje uit als een hack. Ik zou ergens verwachten dat curl zelf dingen in- en uit kan pakken, zodat je zelf niet met hex-sequences hoeft te lopen pielen.
 
- Ariën  -
Beheerder

- Ariën -

09/06/2019 23:26:15
Quote Anchor link
Thomas van den Heuvel op 09/06/2019 23:13:31:
Wat ik eerst zou doen is een (uitgebreide) analyse maken van waarom je in eerste instantie op een blacklist terecht bent gekomen / de dienst niet langer toegankelijk was. Het helpt hierbij als je een soort van verbose log bijhoudt / had bijgehouden. Mogelijk was door een combinatie van instellingen jouw script op die webservice aan het hameren en ben je daarna op de zwarte lijst belandt (dit klinkt wat mij betreft nog steeds als het meest voor de hand liggende scenario).


Lees nog eens goed, want het gaat dus niet om een blacklist.
Quote:
Het wachten duurde te lang, en het leek er gewoon op dat mijn IP op een blacklist zou staan.

Na lang zoeken kreeg ik van iemand de tip om eens een request met Gzip te proberen.
En warempel: Toen werkte het... (...)


Quote:
Dan, als je de oorzaak / een concrete foutmelding hebt zou je eens verder kunnen gaan kijken. Mogelijk is de response helemaal niet ge-gzipped, maar wordt deze wel als zodanig geserveerd waardoor curl tript. Mogelijk is je curl-versie te oud waardoor deze incompatibel is geraakt met de webservice of bepaalde byte-sequences niet aankan... wie zal het zeggen? (Seriously though, controleer dit allebei zou ik zeggen, spuugt de webservice alles wel netjes uit op de manier dat het zegt dat het doet en is curl niet verouderd)

Goed idee, ik zal deze eens updaten, en kijken of dit wat oplevert.
Wel gaat het ook mis bij file_get_contents. Dus dat valt ook weer op!
Ik moet het dus niet alleen bij curl zoeken, lijkt mij.
Quote:
Wellicht biedt de bovenstaande oplossing/workaround soelaas, maar wat heb je dan precies opgelost, want je weet nog steeds niet (goed) wat er misging. Ook ziet het er een beetje uit als een hack.

Dat was mijn verwachting ook! Daarom zei ik ook dat ik iets corrects zoek zoals bijv. een goede configuratie-settings of iets dergelijks.
Gewijzigd op 09/06/2019 23:36:30 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

10/06/2019 00:45:24
Quote Anchor link
- Ariën - op 09/06/2019 23:26:15:
Wel gaat het ook mis bij file_get_contents. Dus dat valt ook weer op!

Op een willekeurige manier ergens data vandaan trekken via HTTPS met authenticatie en dan verwachten dat dat altijd direct goed gaat is misschien wat veel gevraagd.
Gewijzigd op 10/06/2019 00:46:26 door Thomas van den Heuvel
 
- Ariën  -
Beheerder

- Ariën -

10/06/2019 00:52:32
Quote Anchor link
Thomas van den Heuvel op 10/06/2019 00:45:24:
- Ariën - op 09/06/2019 23:26:15:
Wel gaat het ook mis bij file_get_contents. Dus dat valt ook weer op!

Op een willekeurige manier ergens data vandaan trekken via HTTPS met authenticatie en dan verwachten dat dat altijd direct goed gaat is misschien wat veel gevraagd.

Het ging puur om te kijken of de webservices al *iets** zou antwoorden ("Hej! Je mag er niet in! Ik zeg 401: "Autentication required").

Ook in dit geval leek de 'handshake' ook niet tot stand te komen.
Ik zal het nog eens testen met dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
$arrContextOptions
=array(
    "ssl"=>array(
        "verify_peer"=>false,
        "verify_peer_name"=>false,
    ),
);


$response = file_get_contents("https://webservice.ns.nl/etc....", false, stream_context_create($arrContextOptions));
?>

Certificaat is netter, maar goed. Voor een test is het onnodig.

Het verbaast me enkel gewoon dat gzip verplicht is, en dat ik iets lijkt te missen?
Gewijzigd op 10/06/2019 01:02:13 door - Ariën -
 
- Ariën  -
Beheerder

- Ariën -

11/06/2019 11:47:04
Quote Anchor link
Heeft iemand nog een idee naar een goede oplossing? Want ik moet het niet enkel bij cURL zoeken, heb ik het idee. Ook in de changelog vind ik niks over een standaard Gzip-functionaliteit.

En is het normaal dat webservices verbindingen zonder gzip weigeren?
Gewijzigd op 11/06/2019 11:47:53 door - Ariën -
 
- Ariën  -
Beheerder

- Ariën -

17/06/2019 13:20:30
Quote Anchor link
Ik heb inmiddels te horen gekregen dat ze inderdaad enkel gzip toestaan. Ze hebben er zelf geen invloed op, maar ik vind het wel opvallend.

Nog even een schopje dus, want ik ben benieuwd hoe andere servers en met name API/webservices hiermee omgaan? En of er fatosenlijke settings zijn die het uit- en inpakken van gzip vanzelf doen, zonder dat ranzige 'hackje' met gzinflate.
Gewijzigd op 17/06/2019 13:22:16 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

17/06/2019 15:19:15
Quote Anchor link
Je zou zeggen dat de "transportlaag/functionaliteit" dit zelf zou kunnen afhandelen en dit lijkt inderdaad het geval te zijn. Ik kan mij zo voorstellen dat op die manier cURL ook beter weet wat deze met de ontvangen data moet doen. Het simpelweg toevoegen van een header zal cURL zelf niet aansturen op dit soort "post processing". Dit zal dan enkel invloed hebben op de request, maar niet op de response.

Edit: de "hack" lijkt ook sterk op deze SO-snippet? Maar als je dus expliciet iets instelt met CURLOPT_ENCODING verloopt de decodering (als het goed is) automatisch.

Edit #2: mogelijk zou je ook de response headers mee kunnen nemen in je response, en op grond daarvan bepalen of je iets moet gunzippen, daarvoor hoef je niet per se bytes te inspecteren. Maar dat zou je even uit moeten testen :].
Gewijzigd op 17/06/2019 19:13:20 door Thomas van den Heuvel
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.