72155

Delphi TIdHTTP POST does not encode plus sign

Question:

I have a TIdHTTP component on a form, and I am sending an http POST request to a cloud-based server. Everything works brilliantly, except for 1 field: a text string with a plus sign, e.g. 'hello world+dog', is getting saved as 'hello world dog'.

Researching this problem, I realise that a '+' in a URL is regarded as a space, so one has to encode it. This is where I'm stumped; it looks like the rest of the POST request is encoded by the TIdHTTP component, except for the '+'.

Looking at the request through Fiddler, it's coming through as 'hello%20world+dog'. If I manually encode the '+' (hello world%2Bdog), the result is 'hello%20world%252Bdog'.

I really don't know what I'm doing here, so if someone could point me in the right direction it would be most appreciated.

Other information:

I am using Delphi 2010. The component doesn't have any special settings, I presume I might need to set something? The header content-type that comes through in Fiddler is 'application/x-www-form-urlencoded'.

Then, the Delphi code:

Request:='hello world+dog'; URL :='http://............./ExecuteWithErrors'; TSL:=TStringList.Create; TSL.Add('query='+Request); Try begin IdHTTP1.ConnectTimeout:=5000; IdHTTP1.ReadTimeout :=5000; Reply:=IdHTTP1.Post(URL,TSL);

Answer1:

You are using an outdated version of Indy and need to upgrade.

TIdHTTP's webform data encoder was changed several times in late 2010. Your version appears to predate all of those changes.

In your version, TIdHTTP uses TIdURI.ParamsEncode() internally to encode the form data, where a space character is encoded as %20 and a + character is left un-encoded, thus:

hello%20world+dog

In October 2010, the encoder was updated to encode a space character as & before calling TIdURI.ParamsEncode(), thus:

hello&world+dog

In early December 2010, the encoder was updated to encode a space character as + instead, thus:

hello+world+dog

In late December 2010, the encoder was <em>completely re-written</em> to follow W3C's HTML specifications for application/x-www-form-urlencoded. A space character is encoded as + and a + character is encoded as %2B, thus:

hello+world%2Bdog

In all cases, the above logic is applied only if the hoForceEncodeParams flag is enabled in the TIdHTTP.HTTPOptions property (which it is by default). If upgrading is not an option, you will have to disable the hoForceEncodeParams flag and manually encode the TStringList content yourself:

Request:='hello+world%2Bdog';

Recommend

  • conditional labeling in rows
  • Generate one file for a list of parsed files using source_gen in dart
  • How to search through a NSMutableArray
  • NumPy won't upgrade from 1.5.1 to 1.6.2 on OS X 10.7
  • The case of the disappearing constraint: Oddities of a higher-rank type
  • Multiple y-axis background colors for chart
  • mySQL count occurrences with JOIN
  • C++ bitwise copy of object failing? Why?
  • Is there no simple way to set WPF StatusBar text?
  • How to use Batch Build for Vb.net Project in Visual studio 2008
  • Java random numbers with no duplicates for a lottery using methods and arrays [duplicate]
  • WPF Prism RegisterTypeForNavigation with viewmodel type
  • Lock file for access on windows
  • Is it possible to setup Gulp in a distributed fashion?
  • error using selenium chromedriver on windows 7 64 bit
  • No session share and avoid navigation buttons in browser while opening application window
  • using php to create an xml file from a mysql db
  • Call a specific instance of a service in Azure Service Fabric
  • How do I convert between time formats?
  • Different sized images (with the same name) in one drawable folder
  • Validating a Firebase Key [duplicate]
  • Eric5: The OK button of 'new project' dialog is disable
  • Map Annotation Disclosure Indicator - Xamarin.Form
  • How to convert days into months using datetime in Python3?
  • Protractor Page objects - TypeError: Object # has no method 'methodName'
  • dmtracedump doesn't work, HELP!
  • How can I filter an array of dictionaries in 'updateSearchResultsForSearchController' to s
  • Optimization of optim() in R ( L-BFGS-B needs finite values of 'fn')
  • how to add dashed border on highcharts “area” graph for every point
  • separate tokens in batch file
  • .Net core Hosted Services guaranteed to complete
  • Getting the type of a “Type” in C# reflection
  • How do I use libcurl to printf a remote FTP directory listing?
  • Runtime complexity of getting the length of a string in different representations
  • Google Spreadsheet Script to Blink a range of Cells
  • Support of :after in IE7
  • JavaScript Regex to Match Boundaries of Words with diacritics
  • What is the best way to cache and reuse immutable singleton objects in Java?
  • How to get rgb from transparent pixel in js
  • Computing the discrete fourier transform of audio data with FFTW