Thomas Mell (Validome): Problem mit POST-Request auslesen

Hallo,
ab Opera 9 existiert die Möglichkeit das im Browser angezeigte Dokument validieren zu lassen. Dafür wird der Quelltext per POST an den Validator verschickt. Das hat den großen Vorteil das auch lokale Dokumente ohne Upload validiert werden können.
Leider verarbeiten der W3C-Validator und Validome diese Daten falsch, da sowohl der MIME-Type als auch der Charset keine Beachtung findet.
Dies möchte ich nun bei Validome ändern, habe dabei aber ein großes Problem das ich nicht „genackt“ bekomme.
Hier mal der POST-Request von Opera:

POST /validate HTTP/1.1
User-Agent: Opera/9.00 (X11; Linux i686; U; en)
Host: www.validome.org
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: de,en;q=0.9
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
TE: deflate, gzip, chunked, identity, trailers
Content-Length: 5167
Content-Type: multipart/form-data; boundary=----------Mw0diRC5NaQNPRX9iksyxN
Connection: keep-alive
------------Mw0diRC5NaQNPRX9iksyxN
Content-Disposition: form-data; name="uploadFile"; filename="validate.xml"
Content-Type: application/xhtml+xml; charset=utf-8

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...

Ich komme zwar ganz leicht an den übergebenen Quelltext des Dokumentes, jedoch nicht an den Header dieser Daten (Content-Disposition: form-data; name="uploadFile"; filename="validate.xml"
Content-Type: application/xhtml+xml; charset=utf-8).
Existent in PHP eine Funktion o.ä. um an diesen Header zu kommen?
Notfalls könnte ich auch auf Perl zurückgreifen, währe aber nicht meine Wunschlösung.

Viele Grüße
Thomas Mell

  1. hi,

    Existent in PHP eine Funktion o.ä. um an diesen Header zu kommen?

    Du suchst apache_request_headers() bzw. getallheaders() (letzteres ist nur ein Alias für die vorgenannte Funktion).

    Diese Funktion liefert dir ein assoziatives Array zurück, in dem die Header-Bezeichner die Schlüssel darstellen. (Bin aber im Moment überfragt, ob diese dort case-sensitive behandelt werden.)

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Hi,
      diese Funktion kenne ich, die gibt mir aber den HTTP-Header zurück, nicht den Header des POST-Feldes:

      POST /validate HTTP/1.1
      User-Agent: Opera/9.00 (X11; Linux i686; U; en)
      Host: www.validome.org
      Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
      Accept-Language: de,en;q=0.9
      Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
      Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
      TE: deflate, gzip, chunked, identity, trailers
      Content-Length: 5167
      Content-Type: multipart/form-data; boundary=----------Mw0diRC5NaQNPRX9iksyxN
      Connection: keep-alive

      Ich benötige aber:

      Content-Disposition: form-data; name="uploadFile"; filename="validate.xml"
      Content-Type: application/xhtml+xml; charset=utf-8

      Grüße
      Thomas Mell

      1. hi,

        diese Funktion kenne ich, die gibt mir aber den HTTP-Header zurück, nicht den Header des POST-Feldes:

        Ach so, du meinst die _im_ Request Body des POST-Request stehenden Angaben ...

        Ich benötige aber:

        Content-Disposition: form-data; name="uploadFile"; filename="validate.xml"
        Content-Type: application/xhtml+xml; charset=utf-8

        Dann wirst du sie wohl extrahieren müssen - mit Stringfunktionen, ggf. regulären Ausdrücken.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hep,

          Dann wirst du sie wohl extrahieren müssen - mit Stringfunktionen, ggf. regulären Ausdrücken.

          Daran habe ich auch schon gedacht, dafür müsste ich aber erst mal den Request Body als String geliefert bekommen. Ich habe aber auch hierfür nichts in PHP gefunden.

          Grüße
          Thomas

          1. hi,

            Daran habe ich auch schon gedacht, dafür müsste ich aber erst mal den Request Body als String geliefert bekommen. Ich habe aber auch hierfür nichts in PHP gefunden.

            $HTTP_RAW_POST_DATA hätte ich jetzt eigentlich antworten wollen, sehe aber gerade im Manual folgenden Hinweis:

            $HTTP_RAW_POST_DATA is not available with enctype="multipart/form-data".

            Dann wirst du dich wohl an

            However, the preferred method for accessing the raw POST data is php://input.

            halten müssen.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            1. Hi,
              php://input is not available with enctype="multipart/form-data".

              Das war wohl auch nix ;-))

              Grüße
              Thomas

              1. hi,

                php://input is not available with enctype="multipart/form-data".

                Das war wohl auch nix ;-))

                Hm, wie nimmst du die Daten denn dann derzeit überhaupt in Empfang?

                Über $_FILES?

                gruß,
                wahsaga

                --
                /voodoo.css:
                #GeorgeWBush { position:absolute; bottom:-6ft; }
                1. Hi,

                  Hm, wie nimmst du die Daten denn dann derzeit überhaupt in Empfang?

                  Über $_FILES?

                  Ja, bei der upload-Funktion von Validome ist eh kein Header vorhanden, demnach auch kein Problem bisher. Opera übergibt aber dankenswerterweise den MIMI-Type und den Charset des Dokumentes. Somit können wir es so validieren als wenn wir es selbst geladen hätten. Ich komme aber einfach nicht an die benötigten Daten...

                  Grüße
                  Thomas

  2. Hey,

    Notfalls könnte ich auch auf Perl zurückgreifen, währe aber nicht meine Wunschlösung.

    Einzeiler gefällig?

      
    #!perl  
    use HTTP::Request;  
      
    print [HTTP::Request->parse(<<REQUEST)->parts]->[0]->headers->header('Content-Type');  
    POST /check HTTP/1.1  
    User-Agent: Opera/9.02 (Windows NT 5.0; U; de)  
    Host: validator.w3.org  
    Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1  
    Accept-Language: de,en;q=0.9  
    Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1  
    Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0  
    Connection: Keep-Alive, TE  
    TE: deflate, gzip, chunked, identity, trailers  
    Content-Length: 489  
    Content-Type: multipart/form-data; boundary=----------zsmTCjOACDaBkeqqTrYBUx  
      
    ------------zsmTCjOACDaBkeqqTrYBUx  
    Content-Disposition: form-data; name="uploaded_file"; filename="validate.xml"  
    Content-Type: text/xml; charset=UTF-8  
      
    <?xml version='1.0' encoding='UTF-8'?>  
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">  
    <head>  
    <title />  
    </head>  
    <body>  
    </body>  
    </html>  
      
    ------------zsmTCjOACDaBkeqqTrYBUx--  
    REQUEST  
      
    
    
    --
    水-金-地-火-木-土-天-海-冥
    1. Hallo,

      print [HTTP::Request->parse(<<REQUEST)->parts]->[0]->headers->header('Content-Type');

      Das bringt mir einen "Can't find string terminator "REQUEST" anywhere before EOF at /xxxxxxx/test.pl line 8."

      Ich habe von Perl leider nicht mehr die große Ahnung (meine Perl-Zeit ist 4 Jahre her ;-).

      Grüße
      Thomas

      1. http://perldoc.perl.org/perlop.html#<<EOF-here-doc-heredoc-here-document-<<
        | If the terminating identifier is on the last line of the program, you must be
        | sure there is a newline after it; otherwise, Perl will give the warning Can't
        | find string terminator "END" anywhere before EOF....

        --
        水-金-地-火-木-土-天-海-冥
        1. Hi,
          ähh, danke - jetzt bin ich genau so schlau wie vorher ;-))
          Wie wo was soll ich ein newline einfügen ? Für was steht überhaupt "<<REQUEST" ? Ist das der Request als Sting ?

          Grüße
          Thomas

          1. Hey,
            kannst du kein Englisch?

            Füge ein Newline am Ende des Quellcodes an. Momentan ist dein letztes Zeichen T.

            << leitet ein Here-doc ein. Das ist eine Art, einen String zu begrenzen, und zwar die bequemste, wenn der String sich über mehrere Zeilen erstreckt. Der String geht von der ersten Zeile nach dem Anfangsidentifizierer bis zum Endidentifizierer. REQUEST ist der Identifizierer.

            Folgende Beispiele liefern identische Strings.

              
            my $s1 = "Hallo\nWelt\n";  
            my $s2 = 'Hallo  
            Welt  
            ';  
            my $s3 = <<ENDOFSTRING;  
            Hallo  
            Welt  
            ENDOFSTRING  
            
            
            --
            水-金-地-火-木-土-天-海-冥
            1. Hi,

              Füge ein Newline am Ende des Quellcodes an.

              Auf den Quellcode habe ich aber keinen Einfluß, der wird vom Opera geschickt.
              Wenn ich das nun richtig verstehe, soll ich hinter <<REQUEST die Requestdaten einfügen ?! Etwa so?
              <<REQUEST;
              $Requestdaten
              REQUEST

              Aber genau die Requestdaten habe ich dort gar nicht, sondern möchte sie haben. Kann es sein das wir aneinander vorbeireden ?
              Kann es sein das der Ausdruck ...->parse(<<REQUEST)... die folgenden Daten nur parst, aber diese vorgesetzt bekommen muß?
              POST /validate HTTP/1.1
              User-Agent: Opera/9.00 (X11; Linux i686; U; en)
              Host: www.validome.org
              Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
              Accept-Language: de,en;q=0.9
              Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
              Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
              TE: deflate, gzip, chunked, identity, trailers
              Content-Length: 5167
              Content-Type: multipart/form-data; boundary=----------Mw0diRC5NaQNPRX9iksyxN
              Connection: keep-alive
              ------------Mw0diRC5NaQNPRX9iksyxN
              Content-Disposition: form-data; name="uploadFile"; filename="validate.xml"
              Content-Type: application/xhtml+xml; charset=utf-8

              <?xml version='1.0' encoding='UTF-8'?>
              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              ...

              Ich benötige aber diese Daten, wie sie dann geparst werden ist mir egal. <STDIN> liefert mir nur den Body (ab ------------Mw0diRC5NaQNPRX9iksyxN), ich benötige aber "alles".

              Grüße
              Thomas

              1. Mein Programm aus https://forum.selfhtml.org/?t=139327&m=905176 ist hinfällig. Springe zum letzten Absatz für den nützlichen Teil dieses Postings.

                Das ist Quellcode. Ein Klartextauszug von einem Wireshark-Netzwerkmitschnitt ist keiner. Ich habe der Quellcode gesagt, also mit bestimmten Artikel. Ich weiß nicht, wie du so unaufmerksam/unkonzentriert sein und das und die ganze Geschichte missverstehen kannst. Zeit für Urlaub, <interjection xml:lang="en_CA">eh</interjection>? ;)

                Jedenfalls hast du darauf sehr wohl Einfluss. Beim kopieren vom Forum und einfügen in eine Datei hast du so abgespeichert:

                Wie ich erwähnte, ist dein letztes Zeichen T. Dahinter gehört noch ein Newline, so:

                Weil die Funktion Quelltext überprüfen Strg+Alt+V in Opera 9 anscheinend den Host validator.w3.org fest verdrahtet hat, habe ich ihn mittels hosts-Datei zeitweilig auf meinen Webserver umgebogen. Wie man dem POST-Request entnehmen kann, wird die Ressource /check aufgerufen, also habe ich das folgende Programm unter dem Namen check im Documentroot abgelegt.

                #!perl  
                use CGI qw();  
                my $cgi = new CGI;  
                print $cgi->header('text/plain;charset=utf-8');  
                print $cgi->uploadInfo($cgi->param('uploaded_file'))->{'Content-Type'};  
                
                
                --
                水-金-地-火-木-土-天-海-冥