Using Delphi XE5 + Indy 10.
I am sending POST with login and password to log in. Site responds with redirect (302) to target page. In browser, redirect is handled by GET and everything goes right, but Indy continues with POST.
I solve this by using this code inside my OnRedirect handler:
procedure TForm1.MyRedirect(Sender: TObject;
var dest: string;
var NumRedirect: Integer;
var Handled: Boolean;
var VMethod: string);
var
TempHttp: TIdHttp;
begin
TempHttp := (Sender as TIdHTTP);
if (TempHttp.ResponseCode = 302) then
VMethod := 'GET';
Handled := true;
end;
Request method is then changed to GET, but Indy still sends POST request params with GET. So I get 413 Request Entity Too Large response.
How can I make Indy NOT send params with GET after redirect? Solution inside OnRedirect would be ideal.
Thanks!
Client behavior for handling the HTTP 302
reply code is ambiguous, and often treated erroneously by various clients. This is well documented in various RFCs, including 2068 and 2616. The 303
reply code was created to resolve the ambiguity, but many clients still do not support 303
yet, and many servers still use 302
expecting clients to behave as if 303
was used.
TIdHTTP
has jumped back and forth many times over the years trying to figure out what behavior should be used when 302
is received - should it redirect using GET
, or should it redirect using POST
? In 2012, an hoTreat302Like303
flag was added to the TIdHTTP.HTTPOptions
property to let users decide what to do. So make sure you are using an up-to-date version of Indy.
If 303
is received, TIdHTTP
will clear its Request.Source
property (thus ignoring any previous POST
params) and send a GET
request, ignoring the method returned by the OnRedirect
event handler, if assigned.
If 302
is received:
if hoTreat302Like303
is enabled, TIdHTTP
will clear its Request.Source
property (thus ignoring any previous POST
params) and send a GET
request, ignoring the method returned by the OnRedirect
event handler, if assigned.
if hoTreat302Like303
is disabled (which it is by default), TIdHTTP
will send a request using the method returned by the OnRedirect
event handler if assigned, otherwise it will send a request using the same method as the previous request that was redirected. But in either case, it does not clear its Request.Source
property (thus any previous POST
params will be re-sent). So if you change the method in the OnRedirect
handler, you will have to update the Request.Source
property accordingly as well, eg:
procedure TForm1.MyRedirect(Sender: TObject;
var dest: string;
var NumRedirect: Integer;
var Handled: Boolean;
var VMethod: string);
var
TempHttp: TIdHttp;
begin
TempHttp := (Sender as TIdHTTP);
if (TempHttp.ResponseCode = 302) then
begin
VMethod := 'GET';
TempHttp.Request.Source := nil; // <-- add this
end;
Handled := true;
end;