简体   繁体   中英

Weird indy redirect post

I'm trying to send a post request using Indy but I am facing some problems. In a form I have TIdHTTP, a TIdSSLIOHandlerSocketOpenSSL and a TIdCookieManager whith these properties:

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: default values

TIdCookieManager: default values

OnRedirect procedure:

Handled := True;

In a button the following request:

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;

But returns error with response code 301, but the wierd part is that the location is the same url that I am trying to send, so it enter in an infinite loop.

Response

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 test:

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/

I tried the same request using curl and works with response code 200. Any idea of what could be happening?

If you read the curl documentation , you will see that the -F option posts data in multipart/form-data format:

-F, --form

(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388 . This enables uploading of binary files etc.

However, your TIdHTTP code is posting data that is in application/x-www-form-urlencoded format instead. And more importantly, you are not setting the TIdHTTP.Request.ContentType property to 'application/x-www-form-urlencoded' to match the data. If you post a TStream , you have to set the ContentType accordingly.

TIdHTTP prefers application/x-www-form-urlencoded data to be posted using a TStrings -derived object (like TStringList ) instead of a TStream , so it can ensure the data is encoded and formatted correctly, eg:

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 prefers multipart/form-data data to be posted using a TIdMultipartFormDataStream object instead (unless you pass it another TStream that contains pre-formatted MIME data in it).

So, to match what your curl command is sending, try this instead:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM