chkaufmann 17 Posted May 15, 2019 For a HTTP Post request I create a TIdMultiPartFormDataStream and then I use AddFormField() to put my values. Now I noticed, that "=" is replaced by "=3D" and Content-Transfer-Encoding is set to "quoted-printable". Using the $_POST[] variable in my PHP script, the 3D remains and I get wrong results. Now I'm not sure where I should change that? Should the request be without Content-Transfer-Encoding? or with a different one? Or should I change my PHP script and expect a "quoted-printable" string? I didn't find any information for PHP if I can get the Content-Transfer-Encoding from somewhere. I always thought PHP does handle such things automatically. Christian Share this post Link to post
Alberto Miola 10 Posted May 15, 2019 (edited) I usually use this kind of code: StringStream := TStringStream.Create(Params, TEncoding.UTF8); try Result := FIdHTTP.Post('http://abc.de/my/service/', StringStream); finally StringStream.Free; end; In the above code, I set this property for the FIdHTTP object: //Set the Content-Type FIdHTTP.Request.CustomHeaders.AddValue('Content-Type', 'application/x-www-form-urlencoded'); And here's how the variable Params looks like: Params := 'id=1&name=test'; Server-side, the values can be easily saved with this code: $id = $_POST["id"] //this is '1' $name = $_POST["name"] //this is 'test' Is there a better way? Yes, for sure. I don't know what's the best approach but this is the solution that I usually use to send POST requests via program. It works well Edited May 15, 2019 by Alberto Miola Share this post Link to post
Remy Lebeau 1394 Posted May 15, 2019 3 hours ago, chkaufmann said: For a HTTP Post request I create a TIdMultiPartFormDataStream and then I use AddFormField() to put my values. Now I noticed, that "=" is replaced by "=3D" and Content-Transfer-Encoding is set to "quoted-printable". Yes, text fields are encoded using MIME's "quoted-printable" format by default. You can use the TIdFormDataField.ContentTransfer property to change the encoding. Supported values are: a blank string (7-bit US-ASCII without sending a 'Content-Transfer-Encoding' header), '7bit', '8bit', 'binary', 'quoted-printable', and 'base64'. 3 hours ago, chkaufmann said: Using the $_POST[] variable in my PHP script, the 3D remains and I get wrong results. I would consider that to be a bug in PHP, if it is not decoding the MIME encoding that is declared in the posted data. In this case, I would suggest setting the TIdFormDataField.ContentTransfer to '8bit' to send the text data in its raw charset form. For instance, this is actually required if you want to send text data in UTF-8. Funny, I just answered a similar question on StackOverflow just this morning: Delphi Indy Post Encoding and PHP. 3 hours ago, chkaufmann said: Now I'm not sure where I should change that? Should the request be without Content-Transfer-Encoding? or with a different one? Usually a different one. If no ContentTransfer is specified, US-ASCII is used, which will lose data if the text has non-ASCII characters in it. 3 hours ago, chkaufmann said: Or should I change my PHP script and expect a "quoted-printable" string? "quoted-printable" is part of the MIME standard. All MIME implementations are required to support it. However, RFC 7578 deprecates the use of the 'Content-Transfer-Encoding' header in 'multipart/form-data' submissions over HTTP, but TIdMultipartFormDataStream has not been updated to account for that yet. 3 hours ago, chkaufmann said: I didn't find any information for PHP if I can get the Content-Transfer-Encoding from somewhere. I always thought PHP does handle such things automatically. See https://bugs.php.net/bug.php?id=48219 Share this post Link to post
Remy Lebeau 1394 Posted May 15, 2019 34 minutes ago, Alberto Miola said: I usually use this kind of code: StringStream := TStringStream.Create(Params, TEncoding.UTF8); try Result := FIdHTTP.Post('http://abc.de/my/service/', StringStream); finally StringStream.Free; end; In the above code, I set this property for the FIdHTTP object: //Set the Content-Type FIdHTTP.Request.CustomHeaders.AddValue('Content-Type', 'application/x-www-form-urlencoded'); You should not use the Request.CustomHeaders property to set the 'Content-Type' header, use the Request.ContentType property instead. And the official way to send an 'application/x-www-form-urlencoded' post with TIdHTTP is to use the overloaded version of the TIdHTTP.Post() method that takes a TStrings as input, not the overload that takes a TStream as input. The TStrings overload takes a list of 'name=value' strings and posts them in 'application/x-www-form-urlencoded' format for you. 34 minutes ago, Alberto Miola said: Is there a better way? Yes, for sure. Absolutely. See above. 34 minutes ago, Alberto Miola said: this is the solution that I usually use to send POST requests via program. It works well You are using the wrong approach and should update your code to let TIdHTTP do the hard work for you. Especially in regards to how the 'name=value' strings get formatted. TIdHTTP follows the HTML5 standard in that regard, which saves you the trouble of having to deal with it manually. 1 Share this post Link to post
chkaufmann 17 Posted May 16, 2019 Thanks Remy. I set the type to '8bit' and all works fine now, even when post variables contain cyrillic characters. Share this post Link to post