skip to Main Content

I have tested POST function in PostMan to do POST function with body parameters as below:

enter image description here

enter image description here

Here is eBay’s document for this function:

  HTTP method:   POST
  URL (Sandbox): https://api.sandbox.ebay.com/identity/v1/oauth2/token

  HTTP headers:
    Content-Type = application/x-www-form-urlencoded
    Authorization = Basic <B64-encoded-oauth-credentials>

  Request body:
    grant_type=authorization_code
    code=<authorization-code-value>
    redirect_uri=<RuName-value>

My first attempt was as follow:

function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
  xRequestBody: TStringStream;
begin
  with objHTTP.Request do begin
    CustomHeaders.Clear;
    ContentType := 'application/x-www-form-urlencoded';
    CustomHeaders.Values['Authorization'] := 'Basic ' + 'V2VpbmluZ0MtV2VpbmluZ0M';
  end;

  xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + ','
                                     + 'code=' + 'v%5E1.1%23i%5E1%23f%5E0%23r%5E1%23I%5E3%23p%5E3' + ','
                                     + 'redirect_uri=' + 'myredirecturlnameinsandbox',
                                        TEncoding.UTF8);

  try
    try
      Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
    except
      on E: Exception do
        ShowMessage('Error on request: ' + #13#10 + e.Message);
    end;
  finally
    xRequestBody.Free;
  end;
end;

Second attempt tried with below code for Body

  xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + '&'
                                     + 'code=' + AAuthCode + '&'
                                     + 'redirect_uri=' + gsRuName,
                                        TEncoding.UTF8);

Both attempts give HTTP/1.1 400 Bad Request.

I have done some searching in Stack Overflow, and this is the closest question. The only different part is body of POST.

IdHTTP how to send raw body

Can anyone please advise me what is correct way to assign POST body part?
Thanks.

3

Answers


  1. The preferred way to send an application/x-www-form-urlencoded request with TIdHTTP is to use the overloaded TIdHTTP.Post() method that takes a TStrings as input. You are not sending your TStringStream data in the proper application/x-www-form-urlencoded format.

    You don’t need to use the TIdHTTP.Request.CustomHeaders property to setup Basic authorization. TIdHTTP has built-in support for Basic, simply use the TIdHTTP.Request.UserName and TIdHTTP.Request.Password properties as needed, and set the TIdHTTP.Request.BasicAuthentication property to true.

    Try this instead:

    function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
    var
      xRequestBody: TStringList;
    begin
      with objHTTP.Request do
      begin
        Clear;
        ContentType := 'application/x-www-form-urlencoded';
        BasicAuthentication := True;
        UserName := ...;
        Password := ...;
      end;
    
      xRequestBody := TStringList.Create;
      try
        xRequestBody.Add('grant_type=' + 'authorization_code');
        xRequestBody.Add('code=' + AAuthCode);
        xRequestBody.Add('redirect_uri=' + 'myredirecturlnameinsandbox');
    
        try
          Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
        except
          on E: Exception do
            ShowMessage('Error on request: ' + #13#10 + e.Message);
        end;
      finally
        xRequestBody.Free;
      end;
    end;
    

    If you want to send your own TStringStream, try this instead:

    function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
    var
      xRequestBody: TStringStream;
    begin
      with objHTTP.Request do
      begin
        Clear;
        ContentType := 'application/x-www-form-urlencoded';
        BasicAuthentication := True;
        UserName := ...;
        Password := ...;
      end;
    
      xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + '&'
                                         + 'code=' + TIdURI.ParamsEncode(AAuthCode){'v%5E1.1%23i%5E1%23f%5E0%23r%5E1%23I%5E3%23p%5E3'} + '&'
                                         + 'redirect_uri=' + 'myredirecturlnameinsandbox',
                                            TEncoding.UTF8);
      try
        try
          xRequestBody.Position := 0;
    
          Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
        except
          on E: Exception do
            ShowMessage('Error on request: ' + #13#10 + e.Message);
        end;
      finally
        xRequestBody.Free;
      end;
    end;
    
    Login or Signup to reply.
  2. I was troubled by this problem, but the answer didn’t work very much. Later, I used packet capturing to see the actual content sent. For friends with the same problems.

    function TFormMain.init_web_account(): Boolean;
    var
      strTmp: Ansistring;
      PostStringData: TstringStream;
      idhttp1: Tidhttp;
      json, json_array1: TQjson;
      itype_version: integer;
      ifunction_version: integer;
      s: string;
      url: ansistring;
      idMultiPartFormDataStream:TIdMultiPartFormDataStream;
    begin
      try
        result := False;
        idhttp1 := TIdHTTP.Create();
        PostStringData := TStringStream.Create;
    
    
    
        //init_string  http://x.x.x.x:8000/user/key?ke1=v1&k2=v2
        strTmp := //
          'strdogsoftid=' + edtDogNumber.Text + //
          '&chipid=' + '' + //
          '&status=' + '0' +  //
          '&reg_user_name=' + edtRegName.Text + //
          '&reg_init_date=' + formatdatetime('yyyy-mm-dd', dtpRegCodeGenDate.Date) + //
          '&lease_expiration=' + formatdatetime('yyyy-mm-dd', dtp_lease_expiration.Date) + //
          '&renew_last_date=' + '' + //
          '&mobile=' + '' + //
          '&weixin=' + '' + //
          '&memo=' + '' + //
          '&function_version=' + IntToStr(rgVersion.ItemIndex) + //
          '&type_version=' + IntToStr(itype_version); //
    
        url := 'http://x.x.x.x:8000/user/' + edtDogNumber.Text;
        PostStringData.Clear;
        PostStringData.WriteString(strTmp);
    
    
        try
    
          idhttp1.Request.ContentType := 'application/x-www-form-urlencoded';
    
    
    
          s := idhttp1.Post(url, PostStringData); 
          result := True;
    
    
        except
          on E: Exception do
          begin
            showmessage(s);
            result := False; 
            exit;
          end;
    
        end;
      finally
        PostStringData.Free;
        idhttp1.Free;
    
      end;
    end;
    
    Login or Signup to reply.
  3. If you use TNetHTTPClient you can use the "System.Net.Mime" unit to manage the multipart form data by HTTP Post and manage request too.

    I use Delphi 10.4.2

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search