【问题标题】:PHP CURL does not automatically add Content-Length headerPHP CURL 不会自动添加 Content-Length 标头
【发布时间】:2020-04-23 19:10:26
【问题描述】:

我已经被这个问题困扰了一段时间了。 我有一个简单的代理代码来将查询从这个 PHP 脚本重定向到另一个应用程序。

问题是 GET 的工作就像一个魅力,但 POST 不是。我发现当我从 php-curl 进行 POST 查询时,它没有附加 Content-Length 标头。因此,实际的应用程序无法从请求中检索数据,并且显然无法响应。所以我决定手动设置它,但现在实际的应用程序没有收到完整的正文,但由于某种原因只收到了一部分,即使内容长度是正确的。

所以我有两个问题:

  1. 为什么 curl 不自动设置标题?因为从我在文档中读到的应该是。
  2. 如何正确计算内容长度?因为在测试期间,我什至会尝试根据我在对实际应用进行查询时从邮递员那里获得的 Content-Length 标头对其进行硬编码。

代码有点简单:

function forward(FromRequest $request)
{
    $curl = curl_init();

    curl_setopt($curl, CURLOPT_URL, IT_HOST . $request->getUrl());
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getMethod());
    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        "cache-control: no-cache",
        "content-type: application/json",
        $request->getAuthHeader(),
        ));

    if ($request->getMethod() === 'POST') {
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getData());
    }


    $response = curl_exec($curl);
    $err = curl_error($curl);

    curl_close($curl);

    if ($err) {
        var_dump($err);
        throw new FromRequestException('Cant make a request');
    }

    return $response;
}

此外,$request->getData() 正确地从当前请求中提取数据: $request->data = file_get_contents("php://input");

【问题讨论】:

  • 您是否尝试在 $request->getData() 返回的字符串中添加换行符,以便知道请求已完成?
  • @JasonBoss 实际上没有,我没有。我会立即尝试 UPD。它没有帮助:(
  • 告诉我们$request->getData()返回什么,var_dump($request->getData());,你得到了什么?
  • 我收到string(32) "{"days_up_to":12,"territory":[]}"
  • @hanshenrik 在上面添加了一条评论,正如我所说,我已经做了一个调试,打印出所有可能出错的东西,但事实并非如此,数据是正确的,如果我不是,则不是 null做到这一点

标签: php curl php-curl


【解决方案1】:

当我执行此特定代码时,我无法重现该问题:

<?php
    $curl = curl_init();

    curl_setopt($curl, CURLOPT_URL, "http://127.0.0.1:9999");
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        "cache-control: no-cache",
        "content-type: application/json",
        "auth-header: foo",
        ));

        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, '{"days_up_to":12,"territory":[]}');


    $response = curl_exec($curl);
    $err = curl_error($curl);

PHP/libcurl 发送此特定请求:

POST / HTTP/1.1
Host: 127.0.0.1:9999
Accept: */*
cache-control: no-cache
content-type: application/json
auth-header: foo
Content-Length: 32

{"days_up_to":12,"territory":[]}

如果您查看请求的第 7 行,就会发现 Content-Length 标头存在。

【讨论】:

  • 你的php版本是什么?
  • @WardS PHP 7.3.7 和 libcurl 7.66.0 - 但我已经使用 php/curl_ 很多年了,我知道即使在 php 5 天后,curl 也会自动添加 @987654324 @ header for CURLOPT_POSTFIELDS.. 仍然,你在哪个 php 和 libcurl-version 上?
  • PHP 7.2 和 libcurl 7.58.0
  • @WardS 你能在 facebook 上联系我吗?联系方式在这里:stackoverflow.com/users/1067003/hanshenrik?tab=profile - 我想亲眼看看你在描述什么,如果你在我有时间/无聊的时候抓住我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
相关资源
最近更新 更多