Recent

Author Topic: Curl post  (Read 715 times)

michoux

  • New member
  • *
  • Posts: 9
Curl post
« on: July 15, 2019, 03:26:14 pm »
Hello all.

I am searching for lazarus solution to post a file content to php web.
With curl I do following:
curl -X POST --data-binary @path/to/my-file.txt http://example.com/

Is there a lazarus option for this?

Thanks

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: Curl post
« Reply #1 on: July 15, 2019, 05:53:25 pm »
Try:
Code: Pascal  [Select]
  1. uses fphttpclient
  2. ..
  3.   TFPHTTPClient.SimplePost('http://example.com/', 'path/to/my-file.txt');

Some servers need a User-Agent, others might redirect you from, say, http to https. For more control try:
Code: Pascal  [Select]
  1. uses fphttpclient
  2. ..
  3.   with TFPHTTPClient.Create(nil) do
  4.   try
  5.     AllowRedirect := True;
  6.     AddHeader('User-Agent','curl/7.37.0');
  7.     Post('http://example.com/', 'path/to/my-file.txt');
  8.   finally
  9.     Free;
  10.   end;

michoux

  • New member
  • *
  • Posts: 9
Re: Curl post
« Reply #2 on: August 12, 2019, 03:22:31 pm »
As I know the post or simple post will post a file which is already on the server.
I am posting a local file from my PC

michoux

  • New member
  • *
  • Posts: 9
Re: Curl post
« Reply #3 on: August 12, 2019, 07:50:18 pm »
curl command works great but I want to get rid of windows black window that alway show when running curl.exe

bytebites

  • Full Member
  • ***
  • Posts: 190
Re: Curl post
« Reply #4 on: August 12, 2019, 08:07:44 pm »
As I know the post or simple post will post a file which is already on the server.

Not true aka false.

michoux

  • New member
  • *
  • Posts: 9
Re: Curl post
« Reply #5 on: August 14, 2019, 08:29:21 am »
Here is how my scripts on server works.
I can call it this way with file
http://mysite.com/send.php?xml=file.xml

Or I simply call curl with syntax from above
curl -X POST --data-binary @path/to/my-file.txt http://mysite.com/send.php

I have tried simplepost but it only accepts files from server, so I need  to first upload file from local PC to server in same location as my php scripts resides and then call
http://mysite.com/send.php?xml=./file.xml



Here is my php which I call

*****************************
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

include_once('xml.php');   

$filename = utyGetString($_GET, 'xml', 'php://input');
$xmlData = file_get_contents($filename);

if (strlen($xmlData) > 0)
{
   $xml = new MyXML();
   echo $xml->ReadXML($xmlData);
}
else
{
   echo MyXML::WriteErrorXML('XML Data Empty');
}
?>
*********************************
« Last Edit: August 14, 2019, 09:59:25 am by michoux »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8092
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Curl post
« Reply #6 on: August 14, 2019, 11:18:08 am »
Here is how my scripts on server works.
I can call it this way with file
http://mysite.com/send.php?xml=file.xml

Or I simply call curl with syntax from above
curl -X POST --data-binary @path/to/my-file.txt http://mysite.com/send.php
Those two are not the same, the former issues a GET request with parameter named xml containing a string file.xml, the second one issues a POST request with the content of path/to/my-file.txt as raw request body.
TFPHTTPClient.SimplePost does the same as the latter.
Here is my php which I call

*****************************
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

include_once('xml.php');   

$filename = utyGetString($_GET, 'xml', 'php://input');
$xmlData = file_get_contents($filename);
So you indeed only receive the filename from the request instead of the file content. Thus, the file that the code will read must already exist in the server. It's the server side that's incorrectly coded if you want to be able to send file from anywhere else other than the server.

michoux

  • New member
  • *
  • Posts: 9
Re: Curl post
« Reply #7 on: August 14, 2019, 11:42:27 am »
Thanks for the feedback.

But with curl I can post a local file.
curl -X POST --data-binary @path/to/my-file.txt http://mysite.com/send.php

I was looking for something similar as curl.

Regards Michoux

Leledumbo

  • Hero Member
  • *****
  • Posts: 8092
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Curl post
« Reply #8 on: August 14, 2019, 01:29:12 pm »
Thanks for the feedback.

But with curl I can post a local file.
curl -X POST --data-binary @path/to/my-file.txt http://mysite.com/send.php

I was looking for something similar as curl.

Regards Michoux
No, you did not, try on real server separated from your developing computer. Read the documentation of file_get_contents, the first parameter is filename, which can also be a URL, but not something from a post request body. Your code explicitly states that it reads from $_GET, not $_POST, so you're reading only the filename, and because you're running the server on the same computer, it gives a false assumption that you successfully send the file from local.

rvk

  • Hero Member
  • *****
  • Posts: 3785
Re: Curl post
« Reply #9 on: August 14, 2019, 01:42:02 pm »
No, you did not, try on real server separated from your developing computer. Read the documentation of file_get_contents, the first parameter is filename, which can also be a URL, but not something from a post request body. Your code explicitly states that it reads from $_GET, not $_POST, so you're reading only the filename, and because you're running the server on the same computer, it gives a false assumption that you successfully send the file from local.
Actually... I see a function utyGetString() which uses php://input.

Definition for php://input
Quote
php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype="multipart/form-data".

Although I've never seen it like this.

What is utyGetString() ??
(maybe that one creates a temporary file with the content of php://input returning the name of that temp-file)
« Last Edit: August 14, 2019, 01:43:56 pm by rvk »

michoux

  • New member
  • *
  • Posts: 9
Re: Curl post
« Reply #10 on: August 14, 2019, 02:56:08 pm »
I am NOT running my web server on localhost but on "real" server and curl works ok for me.

Regards Michoux

rvk

  • Hero Member
  • *****
  • Posts: 3785
Re: Curl post
« Reply #11 on: August 14, 2019, 03:05:39 pm »
As I know the post or simple post will post a file which is already on the server.
I am posting a local file from my PC
You could use something like FileFormPost.
But that sends form info too.

« Last Edit: August 14, 2019, 03:08:58 pm by rvk »

rvk

  • Hero Member
  • *****
  • Posts: 3785
Re: Curl post
« Reply #12 on: August 14, 2019, 03:16:35 pm »
I'm not sure if there is already some function but something like this could/should post it without form-data.

Code: Pascal  [Select]
  1. var
  2.   F: TFileStream;
  3.   Response: TStringStream;
  4.   HTTP: TFPHTTPClient;
  5. begin
  6.   F := TFileStream.Create('c:\temp\test.txt', fmOpenRead or fmShareDenyWrite);
  7.   Response := TStringStream.Create;
  8.   HTTP := TFPHTTPClient.Create(nil);
  9.   try
  10.     HTTP.RequestBody := F;
  11.     HTTP.Post('http://domain/ttt.php', Response);
  12.     ShowMessage(Response.DataString);
  13.   finally
  14.     F.Free;
  15.     HTTP.Free;
  16.     Response.Free;
  17.   end;
  18. end;

Code: PHP  [Select]
  1. <?php
  2. ini_set('display_errors', 1);
  3. # $filename = utyGetString($_GET, 'xml', 'php://input'); ?????????????????
  4. $xmlData = file_get_contents('php://input');
  5. echo $xmlData;
  6. ?>

This php will just read the input and echo it back for the program to display.

Edit: Had this first implemented as helper procedure but that might complicate it too much.
« Last Edit: August 14, 2019, 03:47:11 pm by rvk »

michoux

  • New member
  • *
  • Posts: 9
Re: Curl post
« Reply #13 on: August 14, 2019, 04:21:29 pm »
rvk - Thanks a lot, this. woooooorks :)

Just need to correct
TFileStream.Create;
to
TFileStream.Create('');

Sorry for my not-knowledge - I use to program in Pascal/Delphi 20 years ago :)

Thanks again to all for this help ..

Regards Michoux
« Last Edit: August 14, 2019, 04:24:58 pm by michoux »

rvk

  • Hero Member
  • *****
  • Posts: 3785
Re: Curl post
« Reply #14 on: August 14, 2019, 04:46:35 pm »
Just need to correct TFileStream.Create; to TFileStream.Create('');
You mean TStringStream.Create('') ??
The definition of TStringStream.Create is this:
Code: Pascal  [Select]
  1.   TStringStream = class(TBytesStream)
  2.   public
  3.     constructor Create(const AString: string = ''); overload;
The = '' after AString: string means that the AString is optional. And if left out the '' will be used. So .Create(''); isn't strictly necessary. .Create; works fine too.

It seems there isn't much need for posting a file raw in the body (otherwise there would have been a function for it).
Normally the SimpleFileFormPost() is used and then a "fieldname" is provided (could be anything).
In PHP you could then access $_FILES to retrieve the files and content (in that case the content is already written to a temp-file).

But posting it as raw body and using php://input is also possible. The only downside is that you can't provide a filename (which is possible with the form-date and $_FILES).

No problems about your knowledge. We're glad to help.