PHP CURL не добавляет автоматически заголовок Content-Length - PullRequest
0 голосов
/ 23 апреля 2020

Я застрял с этой проблемой некоторое время. У меня есть простой прокси-код для перенаправления запросов из этого сценария PHP в другое приложение.

Дело в том, что GET работает как шарм, а POST - нет. Я понял, что когда я делаю POST-запрос из php -curl, он не прикрепляет заголовок Content-Length. Таким образом, настоящее приложение не может извлечь данные из запроса и, очевидно, не отвечает. Поэтому я решил установить его вручную, но теперь само приложение по какой-то причине не получает полный текст, а только его часть, хотя длина содержимого правильная.

Итак, у меня есть 2 вопроса:

  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");

1 Ответ

0 голосов
/ 23 апреля 2020

Я не могу воспроизвести проблему, когда я выполняю этот указанный c код:

<?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 отправляет этот указанный c запрос:

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 присутствует.

...