BenjiK
BenjiK

Reputation: 65

Translate of https request from java to delphi

Have the following java code:

    // Set your API key: remember to change this to your live API key in production
    String apiKeyUserName = "your api username";
    String apiKeyPassword = "your api password";

    // Set the query params
    DefaultHttpClient httpclient = new DefaultHttpClient();

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("fromPostcode", "2000"));
    params.add(new BasicNameValuePair("toPostcode", "3000"));
    params.add(new BasicNameValuePair("networkId", "01"));
    params.add(new BasicNameValuePair("lodgementDate", "2013-08-01"));
    String query = URLEncodedUtils.format(params, "UTF-8");

    String urlPrefix = "api.auspost.com.au";
    String validateURL = "https://" + urlPrefix + "/DeliveryDates.xml?";

    HttpGet httpGet = new HttpGet(validateURL + query);
    httpGet.addHeader("Cookie", "OBBasicAuth=fromDialog");
    httpGet.addHeader(BasicScheme.authenticate(
        new UsernamePasswordCredentials(apiKeyUserName, apiKeyPassword),
        "US-ASCII",false));

HttpResponse response = httpclient.execute(httpGet);

Want to translate this into an Delphi. For the request I used TIdHttp as below:

procedure RequestDeliveryDate;
var
  IdHTTP: TIdHTTP;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  lResponse: String;
  requestURL: String;
begin
  IdHTTP := TIdHTTP.Create();
  IdHTTP.Request.BasicAuthentication := True;
  IdHTTP.Request.Username := 'your api username';
  IdHTTP.Request.Password := 'your api password';
  IdHTTP.Request.CharSet := 'utf-8';

  LHandler := TIdSSLIOHandlerSocketOpenSSL.Create();
  IdHTTP.IOHandler := LHandler;

  requestURL := 'https://api.auspost.com.au/DeliveryDates.xml?fromPostcode=2000' +
                                                            '&toPostcode=3000' +
                                                            '&networkId=01' +
                                                            '&lodgementDate=2018-02-23' +
                                                            '&numberOfDates=01';
  screen.Cursor := crHourGlass;
  try
    lResponse := IdHTTP.Get(requestURL);
    screen.Cursor := crDefault;
  except
    on E: Exception do
    begin
      screen.Cursor := crDefault;
      ShowMessage(E.Message);
    end;
  end;
  IdHTTP.Free;
end;

Let's presume that I do supply the right api user name and password. When I call the above code I get the following error: "This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required."

What I'm doing wrong? Any suggestion?

Upvotes: 0

Views: 199

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595369

As @ElliottFrisch stated in comments, you are not sending the Cookie header. There are two ways to do that:

  • use the CustomHeaders property:

    IdHTTP.Request.CustomHeaders.AddValue('Cookie', 'OBBasicAuth=fromDialog');
    
  • use the CookieManager property to fake an actual cookie and let TIdHTTP generate the Cookie header for you (be sure to assign a TIdCookieManager component beforehand, and set TIdHTTP. AllowCookies=True):

    url := TIdURI.Create('https://api.auspost.com.au/DeliveryDates.xml');
    try
      IdHTTP.CookieManager.AddServerCookie('OBBasicAuth=fromDialog', url);
    finally
      url.Free;
    end;
    

You are also leaking the TIdSSLIOHandlerSocketOpenSSL object. I suggest assigning the TIdHTTP as its Owner. And the call to IdHTTP.Free should be in a try..finally for good measure.

Try this:

procedure RequestDeliveryDate;
var
  IdHTTP: TIdHTTP;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  requestURL, query, lResponse: String;
  //url: TIdURI;
begin
  requestURL := 'https://api.auspost.com.au/DeliveryDates.xml';
  query := '?fromPostcode=2000' +
           '&toPostcode=3000' +
           '&networkId=01' +
           '&lodgementDate=2018-02-23' +
           '&numberOfDates=01';

  try
    IdHTTP := TIdHTTP.Create;
    try
      IdHTTP.Request.BasicAuthentication := True;
      IdHTTP.Request.Username := 'your api username';
      IdHTTP.Request.Password := 'your api password';

      IdHTTP.Request.CustomHeaders.AddValue('Cookie', 'OBBasicAuth=fromDialog');    
      {
      url := TIdURI.Create(requestURL);
      try
        IdHTTP.CookieManager.AddServerCookie('OBBasicAuth=fromDialog', url);
      finally
        url.Free;
      end;
      }

      LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
      IdHTTP.IOHandler := LHandler;

      screen.Cursor := crHourGlass;
      try
        lResponse := IdHTTP.Get(requestURL + query);
      finally
        screen.Cursor := crDefault;
      end;
    finally
      IdHTTP.Free;
    end;
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
end; 

Upvotes: 2

Related Questions