My code is uploading image to MinIO bucket with simple PUT request. curl
called from shell can upload it successfully:
$url = "http://192.168.1.1:9000/bucket/$fname";
$date = date ('r');
exec ("curl -s -X PUT -T '$fname.jpg' -H 'Host: 192.168.1.1' -H 'Date: $date' -H 'Content-Type: image/jpeg' $url");
I try to replace that to native curl call:
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_URL, $url);
#curl_setopt($curl, CURLOPT_CUMSTOMREQUEST, "PUT"); # Was here, does nothing
curl_setopt($curl, CURLOPT_PUT, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
$headers = array(
"Host: 192.168.1.1",
"Date: ". date ('r'),
"Content-Type: image/jpeg",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
# First way to send data
#$data = file_get_contents ("$fname.jpg");
#curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
# Second way to send data
curl_setopt($curl, CURLOPT_INFILE, "$fname.jpg");
curl_setopt($curl, CURLOPT_INFILESIZE, filesize ("$fname.jpg"));
$resp = curl_exec($curl);
And it does not work. I am tcpdumping the connection and get almost same results. This is dumped header from PHP call:
PUT /bucket/90a705f91c4598bf4788c3694a2789ce HTTP/1.1
Host: 192.168.1.1
Accept: */*
Date: Fri, 29 Jul 2022 02:42:11 0300
Content-Type: image/jpeg
Content-Length: 71920
Expect: 100-continue
This is dumped header from exec curl call:
PUT /bucket/ffb6887fe2a6c32e5fb9a1a0ffe390ed HTTP/1.1
Host: 192.168.1.1
User-Agent: curl/7.64.0
Accept: */*
Date: Fri, 29 Jul 2022 02:41:49 0300
Content-Type: image/jpeg
Content-Length: 66238
Expect: 100-continue
And next packet is a reply from server HTTP/1.1 100 Continue
, same in both cases.
But then, exec curl start to send data, but native call send nothing and fail after timeout. I tried to add "Expect:" header to native call but this works the same except 100-continue reply.
I suppose PHP curl wait for something more than cmd curl and I couldn't find any influencing CURLOPT option. Are there any hints or I just hit the bug?
CodePudding user response:
You might read the manual carefully, it says:
value should be a stream resource (using fopen(), for example) for the following values of the option parameter:
CURLOPT_INFILE The file that the transfer should be read from when uploading.
So the right usage is:
curl_setopt($curl, CURLOPT_INFILE, fopen("$fname.jpg", 'r'));
Notice curl docs says that CURLOPT_PUT
is deprecated, you'd better replace it with CURLOPT_UPLOAD
.