2017-08-31 107 views
1

我想发送一个帖子请求使用Indy但我面临一些问题。 在一种形式中我有TIdHTTP,一个TIdSSLIOHandlerSocketOpenSSL和TIdCookieManager蒙山这些属性:奇怪的indy重定向后

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:默认值

TIdCookieManager:默认值

OnRedirect程序:

Handled := True; 

在按钮下面的请求:

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; 

但返回响应代码为301的错误,但奇怪的是,该位置是我想相同的URL发送,所以它进入一个无限循环。

响应

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 

卷曲测试:

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/ 

我使用curl尝试过同样的请求和响应代码为200 作品有什么可以发生任何想法?

+0

服务器重定向到相同的URL,但它也发送一个Cookie,很可能在初始请求丢失。如果服务器想要返回cookie,这是合理的行为。如果服务器陷入无尽的重定向循环,那是一个不同的问题。嗅探流量以查看curl发送的内容与“TIdHTTP”发送的内容。要嗅探curl的HTTPS流量,可以使用[Fiddler](http://www.telerik.com/fiddler)。要嗅探TIdHTTP的HTTPS流量,可以将'TIdLog ...'组件分配给'TIdHTTP.Intercept'属性,例如'TIdLogFile'。 'TIdHTTP'发送了那个cookie吗? –

+2

你传递什么命令行参数来卷曲?你传递给'TIdHTTP.Post()'什么'Params'?请提供[mcve]显示您实际正在执行的所有事情以重现问题。此外,德尔福2010年8岁,你是否使用同样旧版本的印地?在撰写本文时,目前的Indy版本是10.6.2.5434。 –

+0

我编辑了问题,添加了curl请求,并且使用这些参数,curl不处理重定向,但用200代码进行响应。 我可以在curl中模拟相同的问题的唯一方法是,如果不是https,我使用http。 是的,我知道德尔福2010年是旧的,是的,我使用Indy 10.5.5版本,我们已经尝试更新,至少Indy,但我们遇到很多问题,很不幸我们没有足够的时间或人员来处理它。 – Rigotti

回答

0

如果你读了curl documentation,你会看到,在multipart/form-data格式-F选项职位数据:

-F,--form

(HTTP)这让卷曲模拟填充 - 用户按下提交按钮的表单。 这会导致根据RFC 2388使用内容类型多部分/表单数据卷曲到POST数据。这样可以上传二进制文件等。

但是,您的TIdHTTP代码发布的数据是application/x-www-form-urlencoded格式。更重要的是,您并未将TIdHTTP.Request.ContentType属性设置为'application/x-www-form-urlencoded'以匹配数据。如果您发布TStream,则必须相应地设置ContentType

TIdHTTP宁愿使用TStrings派生对象被张贴application/x-www-form-urlencoded数据(如TStringList)而不是TStream,因此它可以确保数据被编码和格式正确,例如:

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; 

TIdHTTP喜欢multipart/form-data数据将使用TIdMultipartFormDataStream对象进行发布(除非您将另一个TStream传递给其中包含预格式化的MIME数据)。

因此,以符合你的curl命令的发送,试试这个来代替:

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

非常感谢你@remy-lebeau的答案,尝试了你的建议,但不幸的是没有奏效。现在它用'Content-Type:multipart/form-data;边界= -------- 090117161550011'。但相同的结果 – Rigotti

+0

使用当前版本的Indy与您在问题中显示的确切代码,我无法重现该问题。没有做出我在我的回答中提出的任何更改,服务器回复200包含HTML文档,而不是回复301重定向。所以,你需要做我最初的建议:“*嗅探流量,看看curl发送什么与TIdHTTP发送什么*”。服务器不喜欢的机器上的TIdHTTP请求显然存在(或丢失)。任何卷曲发送,'TIdHTTP'可以复制与正确的编码 –

+0

我试图使用Fiddler,我认为这可能是SSL的一些问题,因为在提琴手尝试'连接'到服务器,并返回408错误的请求。 – Rigotti