当我将此字符串与套接字一起使用时,我收到错误的请求

问题描述 投票:0回答:1

我正在尝试在 PHP 中实现“Fire and Forget”,并且我使用此代码(可在 here 找到):

$parts = parse_url($url);
try {
    $socket = $this->openSocket($parts['host'], ($parts['port'] ?? $parts['scheme'] === 'https' ? 443 : 80));
} catch (Exception $e) {
    $socket = null;
}

if (!$socket) {
    return false;
}

$jsPostData = json_encode($postData, JSON_THROW_ON_ERROR);

$contentLength = strlen($jsPostData);

$request = "POST {$parts['path']} HTTP/1.1\r\n";
$request .= "Host: {$parts['host']}\r\n";
$request .= "Authorization: Bearer " . $bearerToken . "\r\n";
$request .= "Content-Length: {$contentLength}\r\n";
$request .= "Content-Type: application/json\r\n\r\n";
$request .= $jsPostData;

fwrite($socket, $request);
fclose($socket);        
    

结果是这样的请求:

POST /my_path HTTP/1.1
Host: my_url
Authorization: Bearer my_bearer_token
Content-Length: 263
Content-Type: application/json

{"event":"...."}

我收到错误:

HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Fri, 06 Oct 2023 09:43:17 GMT
Content-Type: text/html
Content-Length: 220

我不知道这是一个非常糟糕的请求还是权限失败。

更新

如果我将此代码与 Guzzle 一起使用,它会起作用:

try {
    $guzzle = new Client();
    $guzzle->post($url, [
        'timeout' => 1,
        'headers' => [
            'Authorization' => "Authorization: Bearer " . $bearerToken,
        ],
        'form_params' => $postData
    ]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
    // do nothing, the timeout exception is intended
}
php sockets http-status-code-400
1个回答
0
投票

在套接字版本中,您显然发送了 2 个额外的标头,这些标头在 Guzzle 版本中不存在。同样在 Guzzle 中,您可以使用

form_params
选项来设置数据,该选项 - 按照文档 将数据以 form-url 编码格式发送到服务器。然而在套接字版本中,您改为发送 JSON。

您应该使基于套接字的查询发送表单 URL 编码的数据。这应该有效:

//sample data
$url = "https://www.example.com/postSomeData";
$postData = ["event" => "xyz", "someOtherField" => "abc"];
//end of sample

$contentType =  "application/x-www-form-urlencoded";
$params = http_build_query($postData);
$parts = parse_url($url);

try {
    $socket = $this->openSocket($parts['host'], ($parts['port'] ?? $parts['scheme'] === 'https' ? 443 : 80));
} catch (Exception $e) {
    $socket = null;
}

if (!$socket) {
    return false;
}

$request = "POST {$parts['path']} HTTP/1.1\r\n";
$request .= "Host: {$parts['host']}\r\n";
$request .= "Content-Type: $contentType\r\n\r\n";
$request .= $params;

//echo($request);

fwrite($socket, $request);
fclose($socket);

这将生成如下请求:

POST /postSomeData HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

event=xyz&someOtherField=abc

模拟:https://3v4l.org/SY6cp

© www.soinside.com 2019 - 2024. All rights reserved.