Jump to content
dpallas

HTTP/1.1 400 Bad Request

Recommended Posts

Hi everybody
I have the following code:
 

Var
  dpHttp   : TIdHttp;
  dpSSL    : TIdSSLIOHandlerSocketOpenSSL;
  BaseURL  : String;
  Body     : String;
  Bearer   : String;
  PostData : TStringStream;
  sResponse: TStringStream;
begin
  BaseURL:='https://uat.mreceipts.com/api/v2.1/authorization/redeem/';
  Body:='{"Type" : "webecr", "Code" : "23916589" }';
  Bearer:=Edaccess.Text;
  sResponse:=TStringStream.Create('',TEncoding.UTF8);
  PostData := TStringStream.Create(Body,TEncoding.UTF8);

  dpHttp:=TIdHTTP.Create;
  dpHttp.Request.Accept     :='application/json';
  dpHttp.Request.Host       :=BaseURL;
  dpHttp.Request.ContentType:='application/json';
  dpHttp.Request.Charset    :='UTF-8';

  dpHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Bearer);

  dpSSL:=TIdSSLIOHandlerSocketOpenSSL.Create;
  dpSSL.SSLOptions.Method   :=sslvSSLv3;
  dpSSL.SSLOptions.SSLVersions:=[sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];

  dpHttp.IOHandler:=dpSSL;
  try
    dpHttp.Post(BaseURL,PostData, sResponse);
  except
    // Result:=211;
  end;
  sResponse.Free;
  dpHttp.Free;
  dpSSL.Free;
  PostData.Free

When I run it, it shows the message HTTP/1.1 400 Bad Request.
The bearer token is correct.
Does anyone have any idea why this is happening?
Thank you
 

Share this post


Link to post
2 hours ago, dpallas said:

When I run it, it shows the message HTTP/1.1 400 Bad Request.
The bearer token is correct.
Does anyone have any idea why this is happening?

There is no way to diagnose that without knowing what the server considers to be bad.  If the response body doesn't contain an error message with more detail, then you will have to contact the server admin so they can look at the request on their end.

 

That being said, here are a few notes about your code...

2 hours ago, dpallas said:

  BaseURL:='https://uat.mreceipts.com/api/v2.1/authorization/redeem/';
  ...
  dpHttp.Request.Host       :=BaseURL;

 

This is wrong.  The Request.Host property should be just the hostname by itself (ie 'uat.mreceipts.com'). But you don't need to set the Request.Host property manually at all, TIdHTTP can handle that internally for you, so you should remove this property assignment completely.

2 hours ago, dpallas said:

  sResponse: TStringStream;

 

You don't need that object at all, since you are just discarding it without reading anything from it.  You can pass nil to the AResponseContent parameter of TIdHTTP.Post() if you want to ignore the response body.

2 hours ago, dpallas said:

  dpHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Bearer);

 

When sending authentication manually, make sure to set the Request.BasicAuthentication property to False so TIdHTTP won't try to send an 'Authorization: Basic ...' request header.

2 hours ago, dpallas said:

  dpSSL.SSLOptions.Method   :=sslvSSLv3;
  dpSSL.SSLOptions.SSLVersions:=[sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];

 

The Method and SSLVersions properties are mutually exclusive.  Setting one updates the other.  So you do not need to set them both.  In this case, use only the SSLVersions property since you are enabling multiple TLS versions.  You can remove the assignment of the Method property.

Edited by Remy Lebeau

Share this post


Link to post

In addition to Remy points, i want to focus on that your JSON is not standard, and many parsers might see it as broken, JSON should be in compact form and doesn't/shouldn't have spaces.

Share this post


Link to post
2 minutes ago, Kas Ob. said:

your JSON is not standard, and many parsers might see it as broken, JSON should be in compact form and doesn't/shouldn't have spaces.

The JSON spec allows whitespace between tokens.  Any parser that can't handle that is broken.

  • Like 1

Share this post


Link to post
26 minutes ago, Remy Lebeau said:

The JSON spec allows whitespace between tokens.  Any parser that can't handle that is broken.

From the latest RFC https://www.rfc-editor.org/rfc/rfc8259#section-2 

Quote

   Insignificant whitespace is allowed before or after any of the six
   structural characters.

Which wasn't the case in the older RFC(s), and even now it is still not defined concretely, protocols that digitally sign payloads require no spaces like ACME, as it should parse it before and still generate the same exact after parsing to match the hash.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×