2
votes

I have a cookiesmanager attached to IdHTTP component in a form.

var
  XMLRqst     : string;
  XMLResponse : TStringStream;
  XMLRequest  : TStringStream;
...
begin
...
   IdHTTP1.CookieManager.CookieCollection.Add;
   IdHTTP1.CookieManager.CookieCollection[ IdHTTP1.CookieManager.CookieCollection.Count -1 ].CookieName := 'data';
   IdHTTP1.CookieManager.CookieCollection[ IdHTTP1.CookieManager.CookieCollection.Count -1 ].Value      := '<root user="yyy" company="xxxx">';
   IdHTTP1.CookieManager.CookieCollection[ IdHTTP1.CookieManager.CookieCollection.Count -1 ].Path       := '/';

...
XMLRequest  := TStringStream.Create( XMLRqst, TEncoding.Unicode );
...
idHTTP1.Post( 'http://mysite/api', XMLRequest, XMLResponse );
idHTTP1.Disconnect;

I am never receiving the "data" cookie.

  • How to send properly cookies with http post trough Indy's IdHTTP component in Delphi XE6?
1
Cookies aren't meant to be created by the client. The server creates the cookies for the client, and the client only saves what the server sends, and sends them back to the server on future requests.Jerry Dodge
@JerryDodge this is true - of course it makes no sense to send cookies with names unknown to the server. But a HTTP client must be able to construct and send a cookie to the server with a known name and a value.mjn
@mjn: but what Jerry is trying to explain is that TIdCookieManager handles that for you automatically. That is its sole purpose - to collect cookies sent by the server, and then send those cookies back to the server when appropriate. The only time you should ever be creating cookies manually is if you need to persist them across multiple sessions of your app. TIdCookieManager does not save cookies persistently when the app is shut down, you would have to save them yourself and then re-load them the next time the app is run.Remy Lebeau

1 Answers

4
votes

Here is some working code:

procedure SendACookie;
var
  HTTP: TIdHTTP;
  URI: TIdURI;
  ASource: TStringStream;
begin
  HTTP := TIdHTTP.Create;
  try
    HTTP.CookieManager := TIdCookieManager.Create(HTTP);

    URI := TIdURI.Create('http://localhost');
    try
      HTTP.CookieManager.AddServerCookie('habari=mycookievalue', URI);
    finally
      URI.Free;
    end;

    ASource := TStringStream.Create('');
    try
      WriteLn('POST response:');
      WriteLn(HTTP.Post('http://localhost/cookies/', ASource));
    finally
      ASource.Free;
    end;
  finally
    HTTP.Free;
  end;
end;

Server side (using an Indy-based HTTP framework):

procedure TShowCookiesResource.OnPost(Request: TIdHTTPRequestInfo; Response: TIdHTTPResponseInfo);
var
  I: Integer;
  Cookie: TIdCookie;
  HTML: string;
begin
  HTML := '<html>' + #13#10;

  HTML := HTML + Format('<p>%d cookies found:</p>' + #13#10, [Request.Cookies.Count]);

  for I := 0 to Request.Cookies.Count - 1 do
  begin
    Cookie := Request.Cookies[I];
    HTML := HTML + Format('<p>%s</p>' + #13#10,
      [Cookie.CookieName + ': ' + Cookie.Value]);
  end;

  HTML := HTML + '</html>';

  Response.ContentText := HTML;
  Response.ContentType := 'text/html';
  Response.CharSet := 'utf-8';
end;

Output:


    Hit any key to send a cookie.

    POST response:
    1 cookies found:
    habari: mycookievalue


TL;DR

Use the TIdHTTP.CookieManager.AddServerCookie method to add the cookie to the IdHTTP instance which should be sent with the request.