AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi TidHTTP.Post() - Parameter werden nicht getrennt
Thema durchsuchen
Ansicht
Themen-Optionen

TidHTTP.Post() - Parameter werden nicht getrennt

Offene Frage von "TDKBacke"
Ein Thema von TDKBacke · begonnen am 9. Jan 2006 · letzter Beitrag vom 11. Jan 2006
Antwort Antwort
TDKBacke

Registriert seit: 9. Jan 2006
3 Beiträge
 
#1

TidHTTP.Post() - Parameter werden nicht getrennt

  Alt 9. Jan 2006, 19:33
Hallo Forum,

wie ich bei einer Suche hier im Forum feststellen musste, existieren schon einige Beiträge zum Thema TidHTTP.Post() und nicht (richtig) ankommende Parameter, allerdings ist mein Fall etwas anders gelagert.

Zuerst einmal der Code (der Vollständigkeit wegen etwas länglich, der wichtige Teil ist durch '!!! ... !!!'-Kommentare kenntlich gemacht):
Delphi-Quellcode:
procedure Proxy.HTTPServerCommandGet(AThread: TIdPeerThread;
  RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo);
var
    i : integer;
    HTTPClient : TIdHTTP;
    tmpStringList : TStringList;

begin
    // HTTPClient initialisieren
    HTTPClient:=TIdHTTP.Create(nil);
    HTTPClient.HandleRedirects:=true;
    HTTPClient.ProtocolVersion:=pv1_0;

    // HTTP-Header manipulieren
    // ...

    // POST-Anfragen weitergeben
    if (RequestInfo.Command='POST') then
    begin
        ResponseInfo.ContentStream:=TMemoryStream.Create;
        tmpStringList:=TStringList.Create;

        // !!! Hier beginnt das Problem !!!

        for i:=0 to RequestInfo.Params.Count-1 do
        begin
            // Variante 1
            tmpStringList.Add(RequestInfo.Params.Strings[i]);

            // Variante 2
            // if (i<RequestInfo.Params.Count-1) then tmpStringList.Add(URLEncode(RequestInfo.Params.Strings[i] + '&'))
            // else tmpStringList.Add(URLEncode(RequestInfo.Params.Strings[i]));
        end;

        HTTPClient.Post('http://' + RequestInfo.Host + RequestInfo.Document, tmpStringList, ResponseInfo.ContentStream);

        // !!! Hier endet das Problem !!!

    end;

    ResponseInfo.ContentType:=HTTPClient.Response.ContentType;
    ResponseInfo.ContentLength:=length(ResponseInfo.ContentText);
    ResponseInfo.ResponseNo:=HTTPClient.ResponseCode;
    ResponseInfo.ServerSoftware:=HTTPClient.Response.Server;

    ResponseInfo.WriteHeader;
    ResponseInfo.WriteContent;
end;
Wie man vielleicht erkennen kann, soll das einen HTTP-Proxy darstellen. Mit dem HTTP-Server aus Indy wird ein Request angenommen, an TidHTTP weitergeleitet und dessen Ergebnis wiederum an den Aufrufer zurückgegeben. (Für GET-Anfragen - hier rausgestrichen - funktioniert das übrigens problemlos.)
Bei POST-Anfragen gibt es aber folgendes Problem:
tmpStringList enthält die Parameter für die POST-Anfrage und hat nach dem Befüllen aus RequestInfo.Params z.B. den folgenden Inhalt:
tmpStringList.Strings[0]='nick=Anonym'
tmpStringList.Strings[1]='mail=beispiel'
tmpStringList.Strings[2]='msg=Inhalt'
tmpStringList.Strings[3]='id=camponotus'


Das ist soweit auch korrekt. Wenn ich nun aber testweise ein PHP-Skript aufrufe, das lediglich die oben genannten Variablen ausgibt, erhalte ich folgendes Ergebnis:
$id=
$nick=Anonym mail=beispiel msg=Inhalt id=camponotus
$mail=
$msg=


Offensichtlich werden die einzelnen Parameter also nicht getrennt und der komplette String der ersten Variable zugewiesen. Deswegen habe ich eine zweite, im obigen Code auskommentierte Variante zum Einlesen der Parameter ausprobiert, die an alle Parameter ausser dem letzten ein '&' anhängt. Dann sehen tmpStringList und das Ergebnis des PHP-Skripts so aus:
tmpStringList.Strings[0]='nick=Anonym&'
tmpStringList.Strings[1]='mail=beispiel&'
tmpStringList.Strings[2]='msg=Inhalt&'
tmpStringList.Strings[3]='id=camponotus'

=>
$id=
$nick=Anonym
$mail=
$msg=

Jetzt werden die Parameter nach dem ersten '&' also einfach ignoriert.

Mein Ziel wäre folgende Ausgabe:
$nick=Anonym
$mail=beispiel
$msg=Inhalt
$id=camponotus


Kann mir jemand sagen, wie ich das erreiche?
Offensichtlich stimmt ja etwas mit dem Abgrenzen der Parameter nicht. Mit #13+#10 statt '&' will es aber auch nicht gelingen. Genausowenig hilft die direkte Übergabe von RequestInfo.Params.Strings an Post().
Das PHP-Skript ist übrigens nicht die Fehlerquelle, zumindest funktioniert es ohne den Umweg über den Proxy wie erwartet.

Als Entwicklungsumgebung nutze ich Delphi 6 und die mitgelieferte Indy-Version.

Vielen Dank im voraus für alle Lösungen bzw. Anregungen.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: TidHTTP.Post() - Parameter werden nicht getrennt

  Alt 9. Jan 2006, 21:20
Herzlich Willkommen in der Delphi-PRAXiS, TDKBacke.

Mir fallen an deinem Code zwei Dinge auf. Du setzt die Protokoll-Version explizit auf pv1_0, wo doch die Indy-Macher schreiben, dass Indy selbsttätig einen fallback durchführt, sobald POST verwendet wird und solange keine bessere Methode bekannt ist um mit fehlerhaften HTTP Servern zu kommunizieren.

Dann wäre da noch dein FOR loop. Ich denke, dass du den eliminieren kannst:

Delphi-Quellcode:
// !!! Hier beginnt das Problem !!!
HTTPClient.Post(
  'http://' + RequestInfo.Host + RequestInfo.Document,
  RequestInfo.Params,
  ResponseInfo.ContentStream
);
// !!! Hier endet das Problem !!!
Ich kann den Code momentan nicht testen, aber auch wenn er dein Problem nicht löst, dann reduziert er wenigstens die lines of code.

Grüße vom marabu
  Mit Zitat antworten Zitat
TDKBacke

Registriert seit: 9. Jan 2006
3 Beiträge
 
#3

Re: TidHTTP.Post() - Parameter werden nicht getrennt

  Alt 9. Jan 2006, 22:16
@marabu:
Danke für die Begrüßung und die Antwort.

Allerdings:
Zitat von TDKBacke:
Genausowenig hilft die direkte Übergabe von RequestInfo.Params.Strings an Post().
So hatte ich es zu Beginn, dann wird aber, wie im ersten Beitrag beschrieben, alles als ein Parameter interpretiert. Deswegen wollte ich in der Schleife an jeden Parameter noch eine Art Terminator anhängen, aber weder '&' noch #13+#10 helfen weiter.

Werde mal auf HTTP 1.1 umstellen und sehen, was sich dadurch verändert. Klingt ja recht vielversprechend, wenn da von Entwicklerseite auf Probleme hingewiesen wird.
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: TidHTTP.Post() - Parameter werden nicht getrennt

  Alt 10. Jan 2006, 18:26
Hallo,

deinen vergeblichen Versuch die RequestInfo.Params direkt zu übergeben habe ich in der Fülle deines Beitrages wohl überlesen - tut mir leid.

Ich habe mir nun auch einen Proxy (zum Testen) geschrieben, beim IE eingetragen und ein Formular (4 Input Felder) mit POST in Auftrag gegeben. Ich speichere die Request.Params in einem ValueListEditor damit ich mitverfolgen kann, was so an Daten fließt - deshalb die CriticalSection UILock. Intern leite ich den Request auf eine PHP-Seite, die mir mit phpinfo() alle POST Variablen anzeigt. Alles schaut so aus wie du es gerne hättest. Jetzt ist es an dir den Unterschied in der Vorgehensweise zu finden.

Delphi-Quellcode:
procedure TDemoForm.HTTPServerCommandGet(AThread: TIdPeerThread;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  client: TIdHTTP;
begin
  UILock.Acquire;
  try
    VLE.Strings.Assign(ARequestInfo.Params);
  finally
    UILock.Release;
  end;
  AResponseInfo.ContentStream := TMemoryStream.Create;

  client := TIdHTTP.Create(nil);
  with client do
  begin
    Request.Assign(ARequestInfo);
    HandleRedirects := true;
    AllowCookies := true;
    CookieManager := TIdCookieManager.Create(client);
  end;

  if ARequestInfo.Command = 'POSTthen
    client.Post(
      // 'http://' + ARequestInfo.Host + ARequestInfo.Document,
      'http://localhost/root/test.php',
      ARequestInfo.Params,
      AResponseInfo.ContentStream
    )
  else if ARequestInfo.Command = 'GETthen
    client.Get(
      'http://' + ARequestInfo.Host + ARequestInfo.Document,
      AResponseInfo.ContentStream
    )
  else
  begin
    ShowMessage(ARequestInfo.Command);
    Exit;
  end;

  AResponseInfo.ContentType := client.Response.ContentType;
  AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size;
  AResponseInfo.ResponseNo := client.ResponseCode;
  AResponseInfo.ServerSoftware := client.Response.Server;

  AResponseInfo.WriteHeader;
  AResponseInfo.WriteContent;

  AResponseInfo.ContentStream.Free;
  client.Free;
end;
Grüße vom marabu
  Mit Zitat antworten Zitat
TDKBacke

Registriert seit: 9. Jan 2006
3 Beiträge
 
#5

Re: TidHTTP.Post() - Parameter werden nicht getrennt

  Alt 11. Jan 2006, 22:16
Danke für das Testen, habe mein Programm an Deine Vorlage angepasst. (Letztendlich also die Initialisierung des HTTP-Clients, die direkte Übergabe der Params an Post() und *räusper* die Freigabe am Ende.)
Geholfen hat es leider nichts, stattdessen kommt jetzt überhaupt nichts mehr an, statt wie zuvor alles in einem Parameter.
Wir scheinen verschiedene Indy-Versionen zu benutzen, da der Client bei mir die Member "AllowCookies" und " CookieManager" nicht kennt. (Aber ich schleuse die "Cookie:"- und "SetCookie:"-HTTP-Felder sowieso nur durch.) Allerdings halte ich es für unwahrscheinlich, dass die von Borland offiziell mit Delphi 6 ausgelieferte Indy-Version einen so gravierenden Fehler enthält.

Zur Sicherheit noch das verwendete PHP-Skript:
Code:
<?php
echo "id=$_POST["id"]
";
echo "nick=$_POST["nick"]
";
echo "mail=$_POST["mail"]
";
echo "msg=$_POST["msg"]
";
?>
Naja, da dürfte eigentlich nichts schief laufen, insbesondere da beim Aufruf über ein Formular ohne zwischengeschalteten Proxy die korrekten Werte ausgegeben werden.
  Mit Zitat antworten Zitat
Benutzerbild von tn249
tn249

Registriert seit: 18. Jan 2004
Ort: München
164 Beiträge
 
Delphi 2005 Personal
 
#6

Re: TidHTTP.Post() - Parameter werden nicht getrennt

  Alt 11. Jan 2006, 22:26
ich hab nicht alles gelesen, nur kurz meine erfahrungen zu indy-post;

1. es empfiehlt sich mit nem networksniffer die daten die übetragen werden zu überprüfen einfach um nicht von möglichen fehlern in der serversoftware abhängig zu sein.

2. ich hab es mit indy 9 noch nie geschafft post mit TStringlist erfolgreich abzuschicken, er hat die argumente einfach nicht angehängt, stattdessen habe ich TIdMultiPartFromData verwendet, was bei mir ohne fehler ging.

Gruß
Thomas
this post is printed on 100% recycled electrons
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz