[PHP] Socket response geeft verschillende char encodings

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • headliner
  • Registratie: November 2007
  • Laatst online: 15-07-2023
Ik heb de volgende (ter verduidelijking vereenvoudigde) code:

code:
1
2
3
4
5
6
<?php

$indexer_line_1 = file_get_contents('http://www.elsevier.nl/Service/RSS/Feed/Buitenland/');
echo "DETECTED-1: ".mb_detect_encoding($indexer_line_1)."<br>\n";
$indexer_line_2 = file_get_contents('http://www.elsevier.nl/Service/RSS/Feed/Buitenland/');
echo "DETECTED-2: ".mb_detect_encoding($indexer_line_2)."<br>\n";


Wat of UTF-8 of ASCII terug geeft (incl de foutieve tekens als er ASCII wordt terug gegeven).
Bijvoorbeeld een output kan zijn:
code:
1
2
DETECTED-1: ASCII
DETECTED-2: UTF-8


Maar het geeft mij volledig willekeurig soms ASCII en soms UTF-8 terug.

Het lijkt me dit aan de elsevier webserver ligt die wellicht op basis van een soort caching soms een foute output terug geeft, maar om het helemaal uit te sluiten wilde ik het hier toch nog even vragen. Ik heb het zelf op meerdere servers uitgeprobeerd en telkens hetzelfde resultaat.

Iemand die mij kan bevestigen dat dit verschijnsel ook bij hun voorkomt? (of dat ik zelf toch fout zit)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Hmmm, even een snelle test of 't aan elsevier.nl ligt gedaan:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$iterations = 5;
$urls = array(
    'http://www.elsevier.nl/Service/RSS/Feed/Buitenland/',
    'http://www.nu.nl/feeds/rss/algemeen.rss',
    'http://www.telegraaf.nl/rss',
    'http://feeds.nos.nl/nosmyheadlines',
    'http://feeds.reuters.com/reuters/topNews'
);

foreach ($urls as $url) {
    echo sprintf('%s<br>', $url);
    for ($i=1; $i<=$iterations; $i++) {
        $content = file_get_contents($url);
        echo sprintf('Detected [%d]: %s (Len:%d Crc:%d)<br>', $i, mb_detect_encoding($content), strlen($content), crc32($content));
        flush();
    }
}

http://www.elsevier.nl/Service/RSS/Feed/Buitenland/
Detected [1]: ASCII (Len:18215 Crc:2067747170)
Detected [2]: UTF-8 (Len:19626 Crc:915717960)
Detected [3]: ASCII (Len:18215 Crc:2067747170)
Detected [4]: UTF-8 (Len:19626 Crc:915717960)
Detected [5]: ASCII (Len:18215 Crc:2067747170)
http://www.nu.nl/feeds/rss/algemeen.rss
Detected [1]: UTF-8 (Len:15421 Crc:446796644)
Detected [2]: UTF-8 (Len:15421 Crc:446796644)
Detected [3]: UTF-8 (Len:15421 Crc:668007985)
Detected [4]: UTF-8 (Len:15421 Crc:3751440848)
Detected [5]: UTF-8 (Len:15421 Crc:3751440848)
http://www.telegraaf.nl/rss
Detected [1]: UTF-8 (Len:44136 Crc:1071009995)
Detected [2]: UTF-8 (Len:44136 Crc:1071009995)
Detected [3]: UTF-8 (Len:44136 Crc:1071009995)
Detected [4]: UTF-8 (Len:44136 Crc:1071009995)
Detected [5]: UTF-8 (Len:44136 Crc:1071009995)
http://feeds.nos.nl/nosmyheadlines
Detected [1]: UTF-8 (Len:30296 Crc:162714397)
Detected [2]: UTF-8 (Len:30296 Crc:162714397)
Detected [3]: UTF-8 (Len:30296 Crc:162714397)
Detected [4]: UTF-8 (Len:30296 Crc:162714397)
Detected [5]: UTF-8 (Len:30296 Crc:162714397)
http://feeds.reuters.com/reuters/topNews
Detected [1]: UTF-8 (Len:20894 Crc:1554315176)
Detected [2]: UTF-8 (Len:20894 Crc:1554315176)
Detected [3]: UTF-8 (Len:20894 Crc:1554315176)
Detected [4]: UTF-8 (Len:20894 Crc:1554315176)
Detected [5]: UTF-8 (Len:20894 Crc:1554315176)


Hieruit concludeer ik een paar dingen:
  • nu.nl en elsevier.nl serveren niet altijd 'tzelfde bij elk request;
    • dat blijkt bij nu.nl uit de verschillende crc's; echter de lengte is constant dus dat is (neem ik even aan, nog niet gekeken) waarschijnlijk gewoon een datum of timestamp oid. die per request verandert.
    • elsevier daarentegen heeft ook telkens verschillende lengtes...
  • de rest komt met resultaten die je eerder zou verwachten
Nu is 't een kwestie van de $content opslaan en diffen :Y)
Voeg daartoe tussen regel 13 en 14 de volgende regel toe:
PHP:
1
file_put_contents(sprintf('%s.%d.txt', preg_replace('/[^a-z0-9]/i', '', $url), $i), $content);


Diffje erover en we concluderen 't volgende:
Vermoeden nu.nl was correct; enkel de tijd verschilt per request:
>     <pubDate>Fri, 15 Feb 2013 22:03:54 +0100</pubDate>
<     <pubDate>Fri, 15 Feb 2013 22:04:05 +0100</pubDate>
<     <pubDate>Fri, 15 Feb 2013 22:04:19 +0100</pubDate>

Wat wel opvalt is dat er (hierboven) ruim 10~14 seconden tussen zit; dat zal of te maken hebben met loadbalancing en twee (of meer) servers die niet gelijk staan, of caching van RSS output of mogelijk een combinatie van die twee zaken. Either way: alle iteraties voor nu.nl waren < 1 seconde gedaan dus die wild verschillende tijden zijn op z'n minst vreemd vanuit dat perspectief.

Als ik voor elsevier.nl alle even of alle oneven outputs met elkaar diff is er geen verschil. Tussen de even én oneven bestanden is het verschil als volgt. Als je die diff goed bekijkt zie je een aantal toch wel opmerkelijke zaken:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<title>Lichaam doorgedraaide oud-agent geïdentificeerd</title>            
<title>Lichaam doorgedraaide oud-agent gedentificeerd</title> 

<title>John Kerry: mogelijk 90.000 doden in Syrië</title>
<title>John Kerry: mogelijk 90.000 doden in Syri</title>

<description>Het dodental als gevolg van de burgeroorlog in Syrië is mogelijk al opgelopen tot 90.000</description>
<description>Het dodental als gevolg van de burgeroorlog in Syri&amp;#235; is mogelijk al opgelopen tot 90.000</description>

<title>Doden en gewonden bij vliegtuigcrash in Oekraïne</title>
<title>Doden en gewonden bij vliegtuigcrash in Oekrane</title> 

<description>Een passagiersvliegtuig heeft woensdag een crashlanding gemaakt bij de stad Donetsk in het oosten van Oekraïne. Zeker</description>
<description>Een passagiersvliegtuig heeft woensdag een crashlanding gemaakt bij de stad Donetsk in het oosten van Oekra&amp;#239;ne. Zeker</description>

<title>Verwarring over &#8216;high five&#8217; ambassadeur Iran (video)</title>
<title>Verwarring over high five ambassadeur Iran (video)</title>


Nu nog uitzoeken of file_get_contents of file_put_contents verkeerd is of elsevier.nl telkens iets anders doet...

Als ik validator.w3.org gebruik als (rudimentaire) test lijkt die wél elke keer dezelfde response te krijgen...

...en nu wordt 't interessant, want met een simpel C# projectje kan ik het niet reproduceren:
C#:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.Text.RegularExpressions;

namespace Topic1537626
{
    class Program
    {
        static void Main(string[] args)
        {
            Regex alphanum = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase);
            var iterations = 5;
            var urls = new[] {
                "http://www.elsevier.nl/Service/RSS/Feed/Buitenland/", 
                "http://www.nu.nl/feeds/rss/algemeen.rss", 
                "http://www.telegraaf.nl/rss", 
                "http://feeds.nos.nl/nosmyheadlines", 
                "http://feeds.reuters.com/reuters/topNews"
            };


            foreach (var url in urls)
            {
                Console.WriteLine("{0}", url);
                for (var i = 1; i <= iterations; i++)
                    Download(url, string.Format(@"d:\test\{0}.{1}.txt", alphanum.Replace(url, string.Empty), i));
            }
        }

        static void Download(string url, string path)
        {
            var req = (HttpWebRequest)HttpWebRequest.Create(url);
            var cachepolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);

            HttpWebRequest.DefaultCachePolicy = cachepolicy;
            req.Method = "GET";
            req.CachePolicy = cachepolicy;
            
            using (HttpWebResponse wr = (HttpWebResponse)req.GetResponse())
            using (StreamReader sr = new StreamReader(wr.GetResponseStream())) 
                File.WriteAllText(path, sr.ReadToEnd());
        }
    }
}

nu.nl geeft nog steeds met vlagen verschillende tijden in de RSS (wat consistent is met de PHP variant) echter elsevier.nl lijkt nu wél telkens dezelfde response te geven.

Ik heb nog even, voor de test, de nesting van de 2 for-loopjes uit de bovenstaande PHP omgedraaid om te zien of 't zou schelen als ik elke oneven request naar elsevier.nl zou sturen en elke even request naar nu.nl om zo uit te sluiten dat file_get_contents misschien interne state had die zou blijven hangen / "togglen" per request oid maar dat is niet 't geval (op 't eerste gezicht althans); van de requests die naar elsevier.nl gingen (1, 3, 5, 7, ...) waren de requests (1, 5, ...) en (3, 7, ...) identiek en de requests onderling (1, 3, 5, 7, ...) om-en-om; consistent met de eerste test.

Vooralsnog lijkt 't me aan PHP te liggen, validator.w3.org en C# krijgen wél telkens dezelfde response. Waar 't precies in zit mag Joost weten; ik heb niet de moeite genomen exact dezelfde headers te versturen e.d. dus daar zou nog een verschil in kunnen zitten. Een run van 50 requests op rij in PHP geeft consistent een A>B>A>B>.... patroon. Eenzelfde run onder C# geeft 50 identieke responses (maar is ook in ~2 seconden klaar i.t.t. PHP die 11 seconden nodig heeft over dezélfde verbinding :X 8)7 ).

[ Voor 54% gewijzigd door RobIII op 15-02-2013 23:52 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • headliner
  • Registratie: November 2007
  • Laatst online: 15-07-2023
Dank je voor het controleren! Ben iig blij dat het niet alleen aan mij ligt ;)

Helaas is het verschil in content bij elsevier de 'vreemde' tekens met umlaut etc. die in de ASCII response gewoon achterwege gelaten worden waardoor mijn intentie van nieuwe content indexeren bemoeilijkt omdat de titels telkens kunnen verschillen.

Ik zal het eens bij ze aankaarten.

Acties:
  • 0 Henk 'm!

  • headliner
  • Registratie: November 2007
  • Laatst online: 15-07-2023
Aanvulling op je laatste toevoeging:

Mijn originele indexer maakt gebruik van fsockopen/fgets die een HTTP 1.1 request doet (gzipped/chunked) met telkens exact dezelfde headers en dat geeft hetzelfde wisselende resultaat. Het ligt dus niet aan de headers die worden meegezonden en als het daadwerkelijk aan PHP ligt ligt het niet alleen aan de get_file_contents functie.
Overigens gaat het pas fout sinds begin Februari, daarvoor waren er geen problemen en er zijn geen aanpassingen gedaan aan de server of PHP installatie. Daarbij ondervind ik geen problemen met 1 van de andere 1000+ feeds die ik indexeer dus ik vermoed toch een inconsistentie aan de kant van elsevier server.

Ook het opvragen van de feed middels curl geeft wisselend resultaat dus het blijkt niet alleen aan PHP te liggen.

update
Om het platform even uit te sluiten heb ik het via een Windows machine uitgeprobeerd en ook daar wisselende response maar nu lijkt het wat consequenter inconsequent te zijn, namelijk vaker achter elkaar ASCII response, en dan paar minuten later telkens een UTF8 repsonse etc.
Het kan bijna niet anders dan dat er een loadbalancer/caching systeem wisselende content serveert.

[ Voor 19% gewijzigd door headliner op 16-02-2013 08:06 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ik zie net dat je topic in WEB staat dus geef ik 't nog een tikje naar PRG ;)
Waar hoort mijn topic?
headliner schreef op zaterdag 16 februari 2013 @ 08:01:
Het ligt dus niet aan de headers die worden meegezonden en als het daadwerkelijk aan PHP ligt ligt het niet alleen aan de get_file_contents functie.
Ik doelde niet op headers tussen onderlinge requests vanuit 'nzelfde (test)project maar juist verschillen in headers tussen verschillende projecten. Zouden ze bijv. user agent sniffing gebruiken en op basis daarvan zaken "anders" doen zou dat wel wat verklaren.

[ Voor 65% gewijzigd door RobIII op 16-02-2013 14:33 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij