PHP cURL 未正确设置 content-length
PHP cURL doesn't set content-length properly
我正在尝试通过 cURL 上传文件,但缺少某些内容。我将此请求强制为 HTTP 1.0,因为如果我使用 HTTP 1.1,cURL 会添加 Expect: 100 header,这就是额外 header 的原因。这是一个简单的测试代码:
<?php
if(isset($_POST["id"])) {
$data = array("id" => $_POST["id"]);
$data["file"] = "@".realpath($_FILES["file"]["tmp_name"]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453',
'Connection: keep-alive'
));
curl_setopt($ch, CURLOPT_URL, "http://localhost:8080/test-api/upload");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
$response = curl_exec($ch);
var_dump($response);
exit;
}
?>
我基于 Jersey 的服务器接收到它,我可以看到这些 header:
INFO: 25 * Server has received a request on thread http-nio-8080-exec-1
25 > POST http://localhost:8080/test-api/upload
25 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
25 > connection: keep-alive
25 > content-length: 261
25 > content-type: multipart/form-data; boundary=------------------------53f7ba34739b4d9e
25 > host: localhost:8080
看到content-length了吗?太短了。当我通过我的 Postman REST 客户端发送相同的文件和相同的请求时,我得到这些 headers:
INFO: 26 * Server has received a request on thread http-nio-8080-exec-3
26 > POST http://localhost:8080/test-api/upload
26 > accept-encoding: gzip, deflate
26 > accept-language: hu-HU,hu;q=0.8,en-US;q=0.6,en;q=0.4
26 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
26 > cache-control: no-cache, no-cache
26 > connection: keep-alive
26 > content-length: 144954
26 > content-type: multipart/form-data; boundary=----WebKitFormBoundarye5Tg0kEqi10nEBwv
26 > cookie: ff_uvid=126143952; _ga=GA1.1.459454356.1439469592; CAKEPHP=9mffidqo8203ugktan4roc0u82
26 > host: localhost:8080
26 > origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
26 > user-agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36
content-length 现在设置为 属性。这里可能有什么问题?
您必须实际插入文件内容,这与 cli 版本的 curl 不同。
尝试:
$data["file"] = file_get_contents($_FILES["file"]["tmp_name"]);
听起来您使用的是 PHP 5.6.0 或更高版本。从此版本开始,默认情况下禁用文件上传的 @
前缀。您可以使用
启用它
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
这个选项是在 5.5 中添加的,但为了向后兼容,默认是 false
; 5.6 更改了默认不兼容。
从 5.5 开始执行文件上传的首选方法是 CurlFile class。
$data["file"] = new CurlFile(realpath($_FILES["file"]["tmp_name"]));
我正在尝试通过 cURL 上传文件,但缺少某些内容。我将此请求强制为 HTTP 1.0,因为如果我使用 HTTP 1.1,cURL 会添加 Expect: 100 header,这就是额外 header 的原因。这是一个简单的测试代码:
<?php
if(isset($_POST["id"])) {
$data = array("id" => $_POST["id"]);
$data["file"] = "@".realpath($_FILES["file"]["tmp_name"]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453',
'Connection: keep-alive'
));
curl_setopt($ch, CURLOPT_URL, "http://localhost:8080/test-api/upload");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
$response = curl_exec($ch);
var_dump($response);
exit;
}
?>
我基于 Jersey 的服务器接收到它,我可以看到这些 header:
INFO: 25 * Server has received a request on thread http-nio-8080-exec-1
25 > POST http://localhost:8080/test-api/upload
25 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
25 > connection: keep-alive
25 > content-length: 261
25 > content-type: multipart/form-data; boundary=------------------------53f7ba34739b4d9e
25 > host: localhost:8080
看到content-length了吗?太短了。当我通过我的 Postman REST 客户端发送相同的文件和相同的请求时,我得到这些 headers:
INFO: 26 * Server has received a request on thread http-nio-8080-exec-3
26 > POST http://localhost:8080/test-api/upload
26 > accept-encoding: gzip, deflate
26 > accept-language: hu-HU,hu;q=0.8,en-US;q=0.6,en;q=0.4
26 > authorization: Bearer 0e39ffba-66cd-4933-9e94-fcdf600c2453
26 > cache-control: no-cache, no-cache
26 > connection: keep-alive
26 > content-length: 144954
26 > content-type: multipart/form-data; boundary=----WebKitFormBoundarye5Tg0kEqi10nEBwv
26 > cookie: ff_uvid=126143952; _ga=GA1.1.459454356.1439469592; CAKEPHP=9mffidqo8203ugktan4roc0u82
26 > host: localhost:8080
26 > origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
26 > user-agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36
content-length 现在设置为 属性。这里可能有什么问题?
您必须实际插入文件内容,这与 cli 版本的 curl 不同。 尝试:
$data["file"] = file_get_contents($_FILES["file"]["tmp_name"]);
听起来您使用的是 PHP 5.6.0 或更高版本。从此版本开始,默认情况下禁用文件上传的 @
前缀。您可以使用
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
这个选项是在 5.5 中添加的,但为了向后兼容,默认是 false
; 5.6 更改了默认不兼容。
从 5.5 开始执行文件上传的首选方法是 CurlFile class。
$data["file"] = new CurlFile(realpath($_FILES["file"]["tmp_name"]));