1
votes

I'm sending a number of parameters to an API using the TIdHTTP.Get() method.

I pull values for the actual API parameters from string variables or component Text properties (like a ComboBox, for example). Everything is fine until any of those values contains a space.

For example, one of the parameters is a full name field (example: 'John Smith')

Since it contains a space between the first and last name, once I send it to the API using te TIdHTTP.Get() method, it throws a 400 Bad Request error and fails.

If I eliminate the space from the value for that/any particular parameter, it goes through fine.

Code I'm using to test:

httpObject := TIdHTTP.Create;
    
httpObject.HTTPOptions := [hoForceEncodeParams];
httpobject.MaxAuthRetries := 3;
httpObject.ProtocolVersion := pv1_1;
httpObject.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
httpObject.Request.UserAgent := 'Mozilla/3.0 (compatible;Indy Library)';
httpObject.Request.ContentType := 'application/x-www-form-urlencoded; charset=utf-8';
    
URL := 'url string containing the parameters'; //string variable
httpObject.Get(URL);

API documentation says:

image

How can I address this?

Using Delphi Community Edition (which is 10.3) and its accompanying Indy components.

2
Why are you specifying a Content-Type if you use the GET method? - Olivier
@Olivier API documentation indicates to do so. Edited my question and added part of the doc. Commenting out that line of code, and/or the hoForceEncodeParams one doesn't fix it. - t1f
That's not standard. The POST method should be used in that case. - Olivier
@Olivier My thought exactly, vaguely remembering that is for POST. However, as I mentioned, if I don't use that - it still fails the same. Could the API be badly designed forcing it to accept only GET using that ContentType? Or is the doc simply badly written maybe? I haven't designed one so far so no clue if it might be badly built - t1f
@Olivier just tried using POST. Same failure. o.O - t1f

2 Answers

2
votes

You have stated that you are submitting the data as Content-Type: application/x-www-form-urlencoded

That format does not allow spaces. You need to properly encode what you are submitting.

Two ways you can do this:

With Indy:

Encoded := TIdURI.URLEncode(str);

With TNetEncoding

Encoded := TNetEncoding.URL.Encode(str);
3
votes

You are sending parameters in the URL, not in the request body, so setting the Request.ContentType property and enabling the hoForceEncodeParams option are completely unnecessary and can be omitted.

You need to encode the parameter values when you build up a URL to send a request to. You can use the TIdURI class for that, eg:

uses
  ..., IdHTTP, IdURI;

URL := 'http://server/shipment?param1='+TIdURI.ParamsEncode(value1)+'&param2='+TIdURI.ParamsEncode(value2)...;
httpObject.Get(URL);