delphicookiesindyindy10delphi-10.2-tokyo

Indy TIdHTTP apparently missing a server cookie on post request?


I have Indy 10.6.2.5366 and delphi Tokyo 10.2 update 3.

In a response to an HTTPS POST, the CookieManager states there are no cookies, but when i do the same request in postman, there's a Cookie called "ROUTEID" in the response.

Postman request

but when i do the exactly same request on delphi, there is no "ROUTEID" cookie.

enter image description here

i need to persist the cookies because they have authentication information that i need to send in the subsequent requests, as Remy Lebeau states in this post.

I Must be doing something wrong, because in this other post, remy says that TCookieManager were completely re-written from scratch, but what i'm missing?

I've notice that postman shows 10 headers in the response, but delphi shows only 8 in the TIdHTTP.Response.RawHeaders

I know that the response code of my request is 401, but even with an unauthorized error, there's a cookie in the response.

finally, here's my code:

procedure TestMethod(AUrl, ABody: string);
var
  HTTP: TIdHTTP;
  SSL: TIdSSLIOHandlerSocketOpenSSL;
  LStreamRequestBody: TStringStream;
  LReturnBody: string;
  LCookieList: TIdCookieList;
  n: Integer;
begin

  HTTP := TIdHTTP.Create(nil);
  SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  LStreamRequestBody := TStringStream.Create(ABody, TEncoding.UTF8);
  try
    IdOpenSSLSetLibPath(Utils.Global.SSLLibPath);

    SSL.SSLOptions.Method := sslvSSLv23;
    SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
    SSL.SSLOptions.Method := sslvSSLv23;

    HTTP.IOHandler := SSL;
    HTTP.Response.ContentType := 'application/json;charset=utf-8';
    HTTP.Request.CustomHeaders.FoldLines := True;
    HTTP.Request.Accept := '*/*';
    HTTP.Request.ContentType := 'application/json';
    HTTP.Request.Connection := 'keep-alive';
    HTTP.Request.AcceptEncoding := 'gzip, deflate, br';
    HTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';

    HTTP.CookieManager := TIdCookieManager.Create(nil);
    HTTP.AllowCookies := True;
    HTTP.HandleRedirects := True;

    try
      LReturnBody := HTTP.Post(AUrl, LStreamRequestBody);
    Except
      on e: EIdHTTPProtocolException do
      begin
        LCookieList := HTTP.CookieManager.CookieCollection.LockCookieList(caRead);
        try
          for n := 0 to LCookieList.Count - 1 do
          begin

          end;
        finally
          HTTP.CookieManager.CookieCollection.UnlockCookieList(caRead);
        end;
      end;
    end;
  finally
    LStreamRequestBody.Free;
    HTTP.Free;
    SSL.Free;
  end;
end;

Solution

  • In a response to an HTTPS POST, the CookieManager states there are no cookies, but when i do the same request in postman, there's a Cookie called "ROUTEID" in the response ... but when i do the exactly same request on delphi, there is no "ROUTEID" cookie.

    Then the problem is not with Indy itself. The server is not sending a cookie to begin with.

    I've notice that postman shows 10 headers in the response, but delphi shows only 8 in the TIdHTTP.Response.RawHeaders

    That means the server is sending a different response to different user agents. See this question that I answered just yesterday, which suffered from a similar problem. But in a nutshell:

    Many servers are sensitive to the requesting agent, where they send different data to different agents. It is not uncommon for such servers to reject/not recognize Indy's default User-Agent value.

    ...

    When you are comparing curl [or, in this case, postman] requests to other HTTP libraries, you should always strive to make the requests be as close to identical as possible to eliminate any possible differences that can confuse servers. And when there are behavior differences between similar requests, it is typically the User-Agent [request header] at fault.

    I see you are setting the TIdHTTP.Request.UserAgent property to a value that mimics Firefox. Do you have the same problem if you set it to mimic Postman instead? I believe Postman's default User-Agent is something like PostmanRuntime/<version>. Do you have the same problem if you configure Postman to use the same Firefox User-Agent value that TIdHTTP is using?


    On a side note, not related to your cookie issue, but with your presented code in general: