2017-08-31 5 views
1

J'essaye d'envoyer une demande de poste en utilisant Indy mais je suis confronté à quelques problèmes. Dans une forme je TIdHTTP, un TIdSSLIOHandlerSocketOpenSSL et un TIdCookieManager cinque ces propriétés:Weird indy redirect post

TIdHTTP:

IdHTTP1.IOHandler := FSSLIO; 
IdHTTP1.AllowCookies := True; 
IdHTTP1.HandleRedirects := True; 
IdHTTP1.ProxyParams.BasicAuthentication := False; 
IdHTTP1.ProxyParams.ProxyPort := 0; 
IdHTTP1.Request.ContentLength := -1; 
IdHTTP1.Request.Accept := 'text/html, */*'; 
IdHTTP1.Request.BasicAuthentication := False; 
IdHTTP1.Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)'; 
IdHTTP1.HTTPOptions := [hoKeepOrigProtocol, hoForceEncodeParams]; 
IdHTTP1.OnRedirect := IdHTTP1Redirect; 
IdHTTP1.CookieManager := IdCookieManager1;   

TIdSSLIOHandlerSocketOpenSSL: valeurs par défaut

TIdCookieManager: valeurs par défaut

procédure de OnRedirect:

Handled := True; 

Dans un bouton de la demande suivante:

Params := TStringStream.Create('asdf=asdf',TEncoding.UTF8);  
edtmemo1.Text := IdHTTP1.Post('https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/', Params); 
Params.Free; 

Mais renvoie l'erreur avec le code de réponse 301, mais la partie wierd est que l'emplacement est le même URL que je suis en train envoyer, alors entrez dans une boucle infinie.

Réponse

HTTP/1.1 301 Moved Permanently 
Date: Thu, 31 Aug 2017 20:23:32 GMT 
Server: Apache 
X-Powered-By: PHP/5.3.5 
P3P: CP="A politica de privacidade deve estar disponivel no site ou pode ser solicitada via fale conosco." 
Set-Cookie: SECCCAKEPHP=e19ttp30m5380ih41qal0gipg2; expires=Sat, 09-Sep-2017 04:23:32 GMT; path=/ 
Location: https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/ 
Cache-Control: max-age=604800 
Expires: Thu, 07 Sep 2017 20:23:32 GMT 
Content-Length: 0 
Content-Type: text/html; charset=utf-8 

Test Curl:

curl -vv -X POST -F 'asdf=asdf' https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/ 

J'ai essayé la même demande en utilisant boucle et fonctionne avec le code de réponse 200. Toute idée de ce qui pourrait se produire?

+0

Le serveur redirige vers la même URL, mais il envoie aussi un cookie qui manquait probablement dans la demande initiale. C'est un comportement raisonnable si le serveur veut récupérer ce cookie. Si le serveur est bloqué dans une boucle de redirection sans fin, c'est un problème différent. Sniff le trafic pour voir ce que curl envoie vs ce que «TIdHTTP» envoie. Pour flairer le trafic HTTPS de curl, vous pouvez utiliser [Fiddler] (http://www.telerik.com/fiddler). Pour renifler le trafic HTTPS de 'TIdHTTP', vous pouvez affecter un composant' TIdLog ... ', tel que' TIdLogFile', à la propriété 'TIdHTTP.Intercept'. Est-ce que 'TIdHTTP' renvoie ce cookie? –

+2

Quels paramètres de ligne de commande transmettez-vous à curl? Quel 'Params' passez-vous à' TIdHTTP.Post() '? S'il vous plaît fournir un [mcve] montrant tout ce que vous faites réellement pour reproduire le problème. De plus, Delphi 2010 a 8 ans, utilisez-vous une version tout aussi ancienne d'Indy? Au moment de la rédaction de ce document, la version actuelle d'Indy est 10.6.2.5434. –

+0

J'ai édité la question, ajouté la requête curl, et avec ces paramètres, curl ne gère pas les redirections, mais répond avec un code 200. La seule façon que je pourrais simuler le même problème dans curl est si au lieu de https j'utilise http. Et oui, je sais que Delphi 2010 est vieux et oui j'utilise la version 10.5.5 d'Indy, nous avons déjà essayé de mettre à jour, au moins Indy, mais nous avons fait face à BEAUCOUP DE PROBLEMES et malheureusement nous n'avons pas assez de temps Faites avec. – Rigotti

Répondre

0

Si vous lisez le curl documentation, vous verrez que les données de messages option -F dans multipart/form-data Format:

-F, --form

(HTTP) Cette boucle permet de simuler une remplie sous la forme dans laquelle un utilisateur a appuyé sur le bouton de soumission. Ceci provoque le bouclage vers les données POST en utilisant les données multipart/form-Content-Type selon RFC 2388. Cela permet le téléchargement de fichiers binaires, etc.

Cependant, votre code TIdHTTP est l'affichage des données qui sont dans le format application/x-www-form-urlencoded à la place. Et plus important encore, vous ne définissez pas la propriété TIdHTTP.Request.ContentType sur 'application/x-www-form-urlencoded' pour faire correspondre les données. Si vous postez un TStream, vous devez définir le ContentType en conséquence.

TIdHTTP préfère application/x-www-form-urlencoded données à envoyer au moyen d'un objet TStrings dérivée de (comme TStringList) au lieu d'un TStream, il peut donc assurer que les données sont codées et formaté correctement, par exemple:

var 
    Params: TStringList; 
begin 
    ... 
    Params := TStringList.Create; 
    try 
    Params.Add('asdf=asdf'); // <-- DO NOT url-encode the values here! 
    // the TStrings version of Post() will set the Request.ContentType 
    // to 'application/x-www-form-urlencoded' by default... 
    edtmemo1.Text := IdHTTP1.Post('https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/', Params); 
    finally 
    Params.Free; 
    end; 
    ... 
end; 

TIdHTTPmultipart/form-data préfère les données doivent être publiées à l'aide d'un objet TIdMultipartFormDataStream à la place (sauf si vous lui transmettez un autre TStream qui contient des données MIME pré-formatées).

Donc, pour correspondre à ce que votre commande curl envoie, essayez ceci:

uses 
    ..., IdMultipartFormData; 

var 
    Params: TIdMultipartFormDataStream; 
begin 
    ... 
    Params := TIdMultipartFormDataStream.Create; 
    try 
    Params.AddFormField('asdf', 'asdf', 'utf-8'); 
    // the TIdMultipartFormDataStream version of Post() will set the 
    // Request.ContentType to 'multipart/form-data' with a suitable 
    // MIME 'boundary' attribute for you... 
    edtmemo1.Text := IdHTTP1.Post('https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/', Params); 
    finally 
    Params.Free; 
    end; 
    ... 
end; 
+0

Merci beaucoup @ remy-lebeau pour la réponse, essayé votre suggestion mais malheureusement n'a pas fonctionné. Maintenant, il envoie avec 'Content-Type: multipart/form-data; limite = -------- 090117161550011'. Mais même résultat – Rigotti

+0

En utilisant la version actuelle d'Indy avec le code exact que vous avez montré dans votre question, je ne peux pas reproduire le problème. Sans faire aucun des changements que j'ai suggérés dans ma réponse, le serveur répond avec 200 contenant un document HTML, au lieu de répondre avec une redirection 301. Donc, vous devez faire ce que j'ai initialement suggéré: "* Sniff le trafic pour voir ce que curl envoie vs TIdHTTP envoie *". Il y a clairement quelque chose dans (ou manquant de) la requête TIdHTTP sur votre machine que le serveur n'aime pas. Tout curl envoie, 'TIdHTTP' peut répliquer avec le bon codage –

+0

J'ai essayé d'utiliser Fiddler, je pense qu'il peut y avoir un problème avec SSL, parce que dans le fiddler essaye de 'CONNECTER' au serveur, et renvoie 408 mauvaise demande. – Rigotti