CURL Header Fehler 411 - Content-type

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • CURL Header Fehler 411 - Content-type

    Hallo an die Runde,

    Was soll mein Skript können?
    per curl Aufruf eine Webapi ansprechen
    an diese per POST ein XML Request oder zu Testzwecken auch
    einfach Formulardaten übergeben.
    (.asmx)

    Was funktioniert nicht?
    Es kommt ein 411 Fehler zurück ==> Content-Length Required

    Google alles durchsucht keine Lösung gefunden .
    Hab schon öfters mit curl gearbeitet aber der Fehler ist mir neu
    vorallem weil ich den content-length im Header mitsende.

    Ich hoffe ihr seht evtl. ein Fehler, wenn nicht kann es an dem Zielserver liegen
    von der Config her? Oder braucht dieser evtl. mehr infos von mir im Header?

    Hier mein Skript:
    PHP-Code:
    $api_data[request] = 'username=XXXXXXXXXXXX&apiKey=XXXXXXXXXX';

    $api_data[headers][] = "POST  HTTP/1.1\r\n";
    $api_data[headers][] = "Host: ".$_SERVER['HTTP_HOST']."\r\n";
    $api_data[headers][] = "Content-Length: ".strlen($api_data[request])."\r\n";
    $api_data[headers][] = "Content-type: application/x-www-form-urlencoded\r\n";
    $api_data[headers][] = "Connection: close\r\n";

    $api_data[host]         = 'http://IP:PORT/script.asmx';

    $start array_sum(explode(' 'microtime()));

    for(
    $connection_try=0;$connection_try<=0;$connection_try++)
        {
        unset(
    $ch);
        unset(
    $ressource);
        
        
    $ch curl_init();
        
    //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        
    curl_setopt($chCURLOPT_RETURNTRANSFER1);
        
    curl_setopt($chCURLOPT_HTTPHEADER$api_data[headers]);
        
    curl_setopt($chCURLOPT_URL$api_data[host]);
        
    //curl_setopt($ch, CURLOPT_POST, 1);
        
    curl_setopt($chCURLOPT_HEADERTRUE);
        
    curl_setopt($chCURLOPT_POSTFIELDS$api_data[request]);
        
    //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
        
    curl_setopt($chCURLOPT_TIMEOUT5);
        
        
    $status curl_getinfo($chCURLINFO_HTTP_CODE); 
        
        
    $ressource curl_exec($ch);
        
    $stop array_sum(explode(' 'microtime()));
        
    $totalTime $stop $start;
        
        if ( 
    curl_errno($ch) )
            {
            
    $ressource 'ERROR -> ' curl_errno($ch) . ': ' curl_error($ch);
            } 
        else
            {
            
    $returnCode = (int)curl_getinfo($chCURLINFO_HTTP_CODE);
            switch(
    $returnCode)
                {
                case 
    404:
                    
    $ressource 'ERROR -> 404 Not Found';
                    break;
                
                default:
                    break;
                }
            }
        
    curl_close($ch);
        } 
    Ausgabe:

    Request:
    POST HTTP/1.1
    Host: www.XXXX.com
    Content-Length: 39
    Content-type: application/x-www-form-urlencoded
    Connection: close
    username=XXXXXXXXXXXX&apiKey=XXXXXXXXXX

    Response:
    HTTP/1.1 411 Length Required
    Content-Type: text/html
    Date: Tue, 19 Oct 2010 09:39:17 GMT
    Connection: close
    Content-Length: 24

    <h1>Length Required</h1>

  • #2
    Hallo,

    bitte benutze die Beispieldomains (siehe Signatur).

    Offenbar ist die Länge falsch. In deinem Beispiel sind es 40 Zeichen, nicht 39. Davon abgesehen brauchst du den Content-Length-Header nicht selbst zu setzen, das macht cURL für dich.

    Wenn das alles nicht hilft, ist der Webservice kaputt und sendet diese Fehlermeldung, obwohl es nicht zutrifft.

    Edit: noch ein Tipp. Für Firefox gibt es ein Addon namens Poster. Den nehme ich gerne, um solche cURL-Sachen mal von Hand zu überprüfen.

    Gruß,

    Amica
    Zuletzt geändert von AmicaNoctis; 19.10.2010, 12:01.
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Danke für deine Antwort.

      Das Postplugin von Firefox bringt mir hier leider nichts, weil nur die IP Adresse
      des Webserver zugelassen, von dem ich die Anfrage an den Webservice stelle.

      Ich hab mal versuch den gesendeten Header oder Upload Menge auszugeben:
      $status = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD)."<br />";
      $status .= curl_getinfo($ch, CURLINFO_HEADER_OUT);

      Ausgabe:
      0
      "leer"

      Hab ich auch mal auskommentiert:
      //$api_data[headers][] = "Content-Length: ".strlen($api_data[request])."\r\n";

      Auf der Maschine wo der Webservice leuft funktioniert die Anfrage über ein Testformular über POST.

      Also nur nicht wenn ich von EXTERN die Daten per POST sende bringt diesen Fehler. Leider weiss ich nicht was ich jetzt machen soll.

      Die Softwarefirma des Webservice(lokal auf dem Server) sagt natürlich funktioniert alles.

      Grüße
      Tom

      Kommentar


      • #4
        Was sagt denn curl_getinfo($ch), nachdem du
        PHP-Code:
        curl_setopt($chCURLINFO_HEADER_OUTtrue); 
        gesetzt hast?
        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
        Super, danke!
        [/COLOR]

        Kommentar


        • #5
          PHP-Code:
          $ch curl_init();
                  
          //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                  
          curl_setopt($chCURLOPT_RETURNTRANSFER1);
                  
          curl_setopt($chCURLOPT_HTTPHEADER$api_data[headers]);
                  
          curl_setopt($chCURLOPT_URL$api_data[host]);
                  
          //curl_setopt($ch, CURLOPT_POST, 1);
                  
          curl_setopt($chCURLOPT_HEADERTRUE);
                  
          curl_setopt($chCURLOPT_POSTFIELDS$api_data[request]);
                  
          //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
                  
          curl_setopt($chCURLOPT_TIMEOUT5);
                  
                  
          $status curl_getinfo($chCURLINFO_SIZE_UPLOAD)."<br />";
                  
          $status .= curl_getinfo($chCURLINFO_HEADER_OUT)."<br />"
                  
          //$status .= implode('<br />',curl_getinfo($ch));
                  
                  
          echo "<pre>";
                  
          print_r(curl_getinfo($ch));
                  echo 
          "</pre>";
                  
                  
          $ressource curl_exec($ch); 
          Array
          (
          [url] => http://example.com:8085/scriptname.asmx/Login
          [http_code] => 0
          [header_size] => 0
          [request_size] => 0
          [filetime] => 0
          [ssl_verify_result] => 0
          [redirect_count] => 0
          [total_time] => 0
          [namelookup_time] => 0
          [connect_time] => 0
          [pretransfer_time] => 0
          [size_upload] => 0
          [size_download] => 0
          [speed_download] => 0
          [speed_upload] => 0
          [download_content_length] => 0
          [upload_content_length] => 0
          [starttransfer_time] => 0
          [redirect_time] => 0
          )

          Kommentar


          • #6
            curl_getinfo musst du nach curl_exec aufrufen.

            Edit: Danach wiederum solltest du curl_close aufrufen. Ist zwar in deinem Falle erstmal nicht zwingend erforderlich, aber wenn du dann mit Cookies arbeiten musst, was mit hoher Wahrscheinlichkeit der Fall ist, werden die sonst nicht gespeichert.

            Edit2: den Aufruf
            PHP-Code:
            curl_setopt($chCURLINFO_HEADER_OUTtrue); 
            vermisse ich immer noch.
            Zuletzt geändert von AmicaNoctis; 19.10.2010, 13:24.
            [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
            Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
            Super, danke!
            [/COLOR]

            Kommentar


            • #7
              Vielen dank gut zu wissen: Sorry hier nun richtig

              Hier die Ausgabe:
              Array
              (
              [url] => http://example.com:8085/StepsPorWebService.asmx/Login
              [content_type] => text/html
              [http_code] => 411
              [header_size] => 133
              [request_size] => 193
              [filetime] => -1
              [ssl_verify_result] => 0
              [redirect_count] => 0
              [total_time] => 0.050079
              [namelookup_time] => 7.5E-5
              [connect_time] => 0.025486
              [pretransfer_time] => 0.025537
              [size_upload] => 0
              [size_download] => 24
              [speed_download] => 479
              [speed_upload] => 0
              [download_content_length] => 24
              [upload_content_length] => 0
              [starttransfer_time] => 0.05005
              [redirect_time] => 0
              [request_header] => POST /scriptname.asmx/Login HTTP/1.1
              Accept: */*
              Host: example_sendfrom.com
              Content-type: application/x-www-form-urlencoded
              Content-Length: 39
              )
              Zuletzt geändert von tomtherock; 19.10.2010, 13:31.

              Kommentar


              • #8
                Ich seh grad, dass du CURLOPT_POST nicht auf true setzt. Warum nicht? Mach das mal
                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                Super, danke!
                [/COLOR]

                Kommentar


                • #9
                  Ja macht leider keinen Unterschied hab ich auch schon mal rein drin gehabt.

                  Mir ist aber folgendes nun aufgefalle:
                  PHP-Code:
                  $api_data[headers][] = "Content-type: application/x-www-form-urlencoded\r\n";
                          
                          
                  $ch curl_init();
                          
                  //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                          
                  curl_setopt($chCURLOPT_RETURNTRANSFER1);
                          
                  curl_setopt($chCURLOPT_HTTPHEADER$api_data[headers]);
                          
                  curl_setopt($chCURLOPT_URL$api_data[host]);
                          
                  curl_setopt($chCURLOPT_POSTtrue);
                          
                  curl_setopt($chCURLINFO_HEADER_OUTtrue);
                          
                  curl_setopt($chCURLOPT_HEADERTRUE);
                          
                  curl_setopt($chCURLOPT_POSTFIELDS$api_data[request]);
                          
                  //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
                          
                  curl_setopt($chCURLOPT_TIMEOUT5);
                          
                          
                  $ressource curl_exec($ch);
                          
                          
                  $info_header "<textarea rows='10' cols='50'>".(curl_getinfo($chCURLINFO_HEADER_OUT))."</textarea>"
                  Request:
                  POST /sciptname.asmx/Login HTTP/1.1
                  Host: example.com:8085
                  Accept: */*
                  Content-type: application/x-www-form-urlencoded

                  Content-Length: 39

                  username=XXX&apiKey=XXX

                  Responds from Server
                  HTTP/1.1 411 Length Required
                  Content-Type: text/html
                  Date: Tue, 19 Oct 2010 11:42:28 GMT
                  Connection: close
                  Content-Length: 24

                  <h1>Length Required</h1>

                  ========================================================
                  OHNE eigenen Header mitsenden (man beachte die Position und umbruch)
                  Kann ich mit curl nicht einen ganz eigenen HEADER mitsenden:

                  so z.b.:
                  Content-Type: application/x-www-form-urlencoded
                  Content-Length: 39

                  ==> mehr braucht der Webservice laut der Softwarefirma nicht.

                  //curl_setopt($ch, CURLOPT_HTTPHEADER, $api_data[headers]);

                  Request:
                  POST /StepsPorWebService.asmx/Login HTTP/1.1
                  Host: example.com:8085
                  Accept: */*
                  Content-Length: 39
                  Content-Type: application/x-www-form-urlencoded

                  username=XXX&apiKey=XXX

                  Responds from Server
                  HTTP/1.1 500 Internal Server Error
                  Date: Tue, 19 Oct 2010 11:45:34 GMT
                  Server: Microsoft-IIS/6.0
                  X-Powered-By: ASP.NET
                  X-AspNet-Version: 2.0.50727
                  Cache-Control: private
                  Content-Type: text/html; charset=utf-8
                  Content-Length: 3092

                  Kommentar


                  • #10
                    Deinen letzten Beitrag hab ich nicht ganz nachvollziehen können. Die Ausgabe passt irgendwie nicht zum Quelltext.

                    Was steht denn erstmal in $api_data["headers"] und $api_data["request"] drin? Du hast übrigens die Anführungszeichen vergessen und damit auch die Forenregeln hinsichtlich Error-Reporting verletzt. Es wäre möglich, dass es daran schon liegt, aber du Fehlermeldungen von PHP ignorierst, was gerade zum Debuggen keine gute Idee ist.

                    Edit: Jetzt sehe ich erst, wo der Umbruch herkommt: Du darfst keine Zeilenumbrüche in den Header schreiben (erste Zeile), das macht cURL alleine. Dadurch wird auch die Content-Length nicht als header, sondern im Body übertragen.
                    Zuletzt geändert von AmicaNoctis; 19.10.2010, 13:58.
                    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                    Super, danke!
                    [/COLOR]

                    Kommentar


                    • #11
                      Zitat von tomtherock Beitrag anzeigen
                      Request:
                      POST /sciptname.asmx/Login HTTP/1.1
                      Host: example.com:8085
                      Accept: */*
                      Content-type: application/x-www-form-urlencoded

                      Content-Length: 39

                      username=XXX&apiKey=XXX
                      ...

                      OHNE eigenen Header mitsenden (man beachte die Position und umbruch)
                      Den Umbruch baust du selbst ein mit
                      PHP-Code:
                      $api_data[headers][] = "Content-type:  application/x-www-form-urlencoded\r\n"
                      Das ist falsch. Denn dieser Umbruch signalisiert der Gegenseite das Ende der HTTP-Header. Content-Length wird also nicht mehr als Header sondern Teil der POST-Daten interpretiert. Folglich fehlt der Content-Length-Header, was der Webservice nicht akzeptiert.

                      Kommentar


                      • #12
                        Ja hab das mit den Umbrüchen habe ich nun selbst gerade gemerkt,
                        danke für den Hinweis.

                        was sehr kurios ist das egal ob ich nun den richtigen eigenen Header mitsende,
                        oder aber keine eignen Header Daten mitsende, der Fehler mit 411 Content-Length verschwunden ist nun aber immer ein Internal Server Err zurück kommt.

                        Sprich das Script der Gegenseite kann meinen Post nicht richtig verarbeiten,
                        bzw. gefällt der Header wahrscheinlich nicht und verarbeitet die Anfrage nicht.

                        Ist es möglich mit curl einen eigenen Header mitzusenden?

                        Content-Type: application/x-www-form-urlencoded
                        Content-Length: 39
                        Mein kompletter Code:
                        PHP-Code:

                        $api_data
                        ["headers"][] = "Content-type: application/x-www-form-urlencoded";
                                
                        $api_data["request"] = 'username=XXX&apiKey=XXX';            
                                
                                
                        $ch curl_init();
                                
                        //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                                
                        curl_setopt($chCURLOPT_RETURNTRANSFER1);
                                
                        curl_setopt($chCURLOPT_HTTPHEADER$api_data[headers]);
                                
                        curl_setopt($chCURLOPT_URL$api_data[host]);
                                
                        curl_setopt($chCURLOPT_POSTtrue);
                                
                        curl_setopt($chCURLINFO_HEADER_OUTtrue);
                                
                        curl_setopt($chCURLOPT_HEADERTRUE);
                                
                        curl_setopt($chCURLOPT_POSTFIELDS$api_data[request]);
                                
                        //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
                                
                        curl_setopt($chCURLOPT_TIMEOUT5);
                                
                                
                        $ressource curl_exec($ch);
                                
                                
                        $info_header nl2br( (curl_getinfo($chCURLINFO_HEADER_OUT)) ); 
                                
                                
                        //print_r(curl_getinfo($ch));
                                
                                
                        $stop array_sum(explode(' 'microtime()));
                                
                        $totalTime $stop $start;
                                
                                if ( 
                        curl_errno($ch) )
                                    {
                                    
                        $ressource 'ERROR -> ' curl_errno($ch) . ': ' curl_error($ch);
                                    } 
                                else
                                    {
                                    
                        $returnCode = (int)curl_getinfo($chCURLINFO_HTTP_CODE);
                                    switch(
                        $returnCode)
                                        {
                                        case 
                        404:
                                            
                        $ressource 'ERROR -> 404 Not Found';
                                            break;
                                        
                                        default:
                                            break;
                                        }
                                    }
                                
                        curl_close($ch); 

                        Kommentar


                        • #13
                          Warum willst du das machen. Nimm einfach mal alle eigenen Header raus und benutz nur das:

                          PHP-Code:
                                  // hier deine $api_data initialisieren

                                  
                          header("Content-Type: text/plain");
                                  
                          curl_setopt($chCURLOPT_POSTtrue);
                                  
                          curl_setopt($chCURLOPT_HEADERtrue);
                                  
                          curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
                                  
                          curl_setopt($chCURLINFO_HEADER_OUTtrue);

                                  
                          // benutz endlich Hochkommas für Array-Keys!
                                  
                          curl_setopt($chCURLOPT_URL$api_data["host"]);
                                  
                          curl_setopt($chCURLOPT_POSTFIELDS$api_data["request"]);

                                  echo 
                          curl_exec($ch);
                                  
                          print_r(curl_getinfo($ch));
                                  
                          curl_close($ch); 
                          Ausgabe erwünscht.
                          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                          Super, danke!
                          [/COLOR]

                          Kommentar


                          • #14
                            Hab ich ja bereits oben gemacht und Euch geschrieben gleiches resultat.

                            ps: Hab den Entwickler bereits angeschrieben das er mit bitte doch ein ErrorReport senden soll. Weil damit kann man ja schlecht was anfangen. Außer wie oben beschrieben Vermutungen anstellen was er nicht verarbeiten kann.
                            - Header?
                            - Inhalt?
                            - Inhalt Format etc?

                            Hier nach deinem Curl Aufruf Ausgabe:

                            HTTP/1.1 500 Internal Server Error Date: Tue, 19 Oct 2010 12:23:06 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 3092
                            Serverfehler in der Anwendung /.
                            --------------------------------------------------------------------------------

                            Laufzeitfehler
                            Beschreibung: Anwendungsfehler auf dem Server. Aufgrund der aktuellen benutzerdefinierten Fehlereinstellungen für diese Anwendung können die Details des Anwendungsfehlers (aus Sicherheitsgründen) nicht remote angezeigt werden. Sie können jedoch von Browsern angezeigt werden, die auf dem lokalen Server ausgeführt werden.

                            Details: Sie können die Details dieser Fehlermeldung auf dem lokalen Computer anzeigen, indem Sie ein <customErrors>-Tag in der Konfigurationsdatei web.config erstellen, die sich im Stammverzeichnis der aktuellen Webanwendung befindet. Das mode-Attribut dieses <customErrors>-Tags sollte dann auf "Off" festgelegt werden.


                            <!-- Web.Config Configuration File -->

                            <configuration>
                            <system.web>
                            <customErrors mode="Off"/>
                            </system.web>
                            </configuration>


                            Hinweise: Die aktuelle Seite kann durch eine benutzerdefinierte Fehlerseite ersetzt werden, indem Sie das defaultRedirect-Attribut des <customErrors>-Konfigurationstags dieser Anwendung so setzen, das es auf einen benutzerdefinierten Fehlerseiten-URL zeigt.


                            <!-- Web.Config Configuration File -->

                            <configuration>
                            <system.web>
                            <customErrors mode="RemoteOnly" defaultRedirect="mycustompage.htm"/>
                            </system.web>
                            </configuration>


                            Array ( [url] => http://example.com:8085/StepsPorWebService.asmx/Login [content_type] => text/html; charset=utf-8 [http_code] => 500 [header_size] => 240 [request_size] => 195 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.103929 [namelookup_time] => 6.7E-5 [connect_time] => 0.025427 [pretransfer_time] => 0.025468 [size_upload] => 0 [size_download] => 3092 [speed_download] => 29751 [speed_upload] => 0 [download_content_length] => 3092 [upload_content_length] => 0 [starttransfer_time] => 0.079223 [redirect_time] => 0 [request_header] => POST /StepsPorWebService.asmx/Login HTTP/1.1 Host: example.com:8085 Accept: */* Content-Length: 39 Content-Type: application/x-www-form-urlencoded )

                            Kommentar


                            • #15
                              So Lösung gefunden.

                              Die schnittstelle hat nur über einen anderen Link richtig verarbeitet werden
                              können zudem nur über XML API
                              ==> POST METHODE war von den Pflaumen von EXTERN nicht bedacht worden.

                              Vielen dank an alle und habe trotzdem einiges mitgenommen grad das man
                              vorsicht und sehr genau arbeiten muss bei Headern.



                              Das hat letzendlich funktioniert:
                              PHP-Code:
                              $ch curl_init();
                                      
                              //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
                                      
                              $api_data["headers"][] = "Content-Type: application/soap+xml; charset=utf-8";
                                      
                                      
                              curl_setopt($chCURLOPT_HTTPHEADER$api_data["headers"]);
                                      
                              curl_setopt($chCURLOPT_URL$api_data["host"]);
                                      
                              curl_setopt($chCURLOPT_POSTtrue);
                                      
                              curl_setopt($chCURLINFO_HEADER_OUTtrue);
                                      
                              curl_setopt($chCURLOPT_HEADERTRUE);
                                      
                              curl_setopt($chCURLOPT_POSTFIELDS$api_data["request"]);
                                      
                              curl_setopt($chCURLOPT_RETURNTRANSFER1);
                                      
                              //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
                                      
                              curl_setopt($chCURLOPT_TIMEOUT5);
                                      
                                      
                              $ressource curl_exec($ch); 

                              Kommentar

                              Lädt...
                              X