Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

REST Follow Redirects

See more REST Examples

Demonstrates how to follow a 302/303 redirect response.

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Url,
  Chilkat.Rest;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  rest: TRest;
  bTls: Boolean;
  port: Integer;
  bAutoReconnect: Boolean;
  responseText: string;
  statusCode: Integer;
  urlStr: string;
  redirectUrl: TUrl;

begin
  success := False;

  //  This example requires the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  rest := TRest.Create;

  bTls := True;
  port := 443;
  bAutoReconnect := True;
  success := rest.Connect('chilkatsoft.com',port,bTls,bAutoReconnect);
  if (success = False) then
    begin
      WriteLn(rest.LastErrorText);
      Exit;
    end;

  //  Send a POST to a URL that will respond with a 302 redirect..
  rest.AddQueryParam('firstName','John');
  rest.AddQueryParam('lastName','Doe');
  responseText := rest.FullRequestFormUrlEncoded('POST','/echoPost302.asp');
  if (rest.LastMethodSuccess = False) then
    begin
      WriteLn(rest.LastErrorText);
      Exit;
    end;

  statusCode := rest.ResponseStatusCode;

  //  Examine the response status code
  if (statusCode < 300) then
    begin
      WriteLn('Not a redirect.');
      WriteLn(responseText);
      Exit;
    end;

  if (statusCode > 399) then
    begin
      WriteLn('Error response: Status code = ' + statusCode);
      WriteLn(responseText);
      Exit;
    end;

  WriteLn('Redirect status code = ' + statusCode);

  //  The response header will contain a Location field with the redirect URL, such as this:
  //  Location: http://www.chilkatsoft.com/echoPostFinal.asp

  //  The response status code determines how the client should behave.
  //  Here are some common possibilities:

  //  301: Moved Permanently
  //  This and all future requests should be directed to the given URI.  (Keep the original HTTP method for the redirect.  In this case, the 
  //  original request was a POST, so we POST to the redirect URL.)

  //  302: Found (aka Object Moved aka Moved Temporarily)
  //  This is the most popular redirect code, but also an example of industrial practice contradicting the standard. HTTP/1.0 specification (RFC 1945 ) required the client
  //  to perform a temporary redirect (the original describing phrase was �Moved Temporarily�), but popular browsers implemented it as a 303 See Other. Therefore, HTTP/1.1
  //  added status codes 303 and 307 to disambiguate between the two behaviors. However, the majority of Web applications and frameworks still use the 302 status code
  //  as if it were the 303.

  //  303: See Other
  //  The response to the request can be found under another URI using a GET method. When received in response to a PUT, it should be assumed that the server has
  //  received the data and the redirect should be issued with a separate GET message.

  //  307: Temporary Redirect
  //  In this occasion, the request should be repeated with another URI, but future requests can still use the original URI. In contrast to 303, the request method
  //  should not be changed when reissuing the original request. For instance, a POST request must be repeated using another POST request.

  WriteLn(rest.ResponseHeader);

  //  Get the redirect URL
  urlStr := rest.LastRedirectUrl;
  if (rest.LastMethodSuccess = False) then
    begin
      WriteLn('No Location header found for redirect.');
      Exit;
    end;
  redirectUrl := TUrl.Create;
  redirectUrl.ParseUrl(urlStr);

  //  Prep for the redirect..
  rest.ClearAllParts();

  //  Disconnect and re-connect.  
  //  (This can be skipped if both the host and SSL/TLS conditions are the same.)
  rest.Disconnect(100);
  success := rest.Connect(redirectUrl.Host,redirectUrl.Port,redirectUrl.Ssl,bAutoReconnect);
  if (success = False) then
    begin
      WriteLn(rest.LastErrorText);
      Exit;
    end;

  if ((statusCode = 301) or (statusCode = 307)) then
    begin
      //  Redirect using a POST, sending the same params to the new destination
      rest.AddQueryParam('firstName','John');
      rest.AddQueryParam('lastName','Doe');
      responseText := rest.FullRequestFormUrlEncoded('POST',redirectUrl.Path);
      if (rest.LastMethodSuccess = False) then
        begin
          WriteLn(rest.LastErrorText);
          Exit;
        end;

    end;

  if ((statusCode = 302) or (statusCode = 303)) then
    begin
      //  Redirect using a GET, sending the query params found in the redirect URL.
      responseText := rest.FullRequestFormUrlEncoded('GET',redirectUrl.PathWithQueryParams);
      if (rest.LastMethodSuccess = False) then
        begin
          WriteLn(rest.LastErrorText);
          Exit;
        end;

    end;

  //  Show the final status code and the response text.
  WriteLn('Final status code = ' + rest.ResponseStatusCode);

  WriteLn('Final response text (HTML, XML, JSON, or whatever..)');
  WriteLn(responseText);


  rest.Free;
  redirectUrl.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.