简体   繁体   English

PHP 中的 protobuf 响应中出现错误“意外的电线类型”

[英]Error "Unexpected wire type" in a protobuf response in PHP

I am executing a POST request to a server, which responds "properly", but when trying to call the mergeFromString() function I receive the following error:我正在向服务器执行 POST 请求,该服务器“正确”响应,但是当尝试调用mergeFromString() function 时,我收到以下错误:

Google\Protobuf\Internal\GPBDecodeException: Error occurred during parsing: Unexpected wire type. Google\Protobuf\Internal\GPBDecodeException:解析期间发生错误:意外的线路类型。 in Google\Protobuf\Internal\Message.php on line 353在第 353 行的 Google\Protobuf\Internal\Message.php

I am using CURL with PHP:我将 CURL 与 PHP 一起使用:

$handle = curl_init($url);

$curl_options = [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HEADER => true,
    CURLOPT_VERBOSE => true
];

curl_setopt_array($handle, $curl_options);

$curlResponse = curl_exec($handle);

$responseMessage = new MyMessage();
$responseMessage->mergeFromString($curlResponse);

curl_close($handle);

The result of var_dump($curlResponse) is as follows: var_dump($curlResponse)的结果如下:

╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"

In plain text it should look something like this:在纯文本中,它应该看起来像这样:

1: 1
2: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrig
3: 1619765852

My.proto file for the response is as follows:响应的 My.proto 文件如下:

message MyMessage{
    // I'm only interested in property 2
    string prop = 2;
}

Environment:环境:

"protobuf-php / protobuf": "^ 0.1.3",
"google / protobuf": "^ 3.16"

However, tests using Protoman ( A Postman-like API client for protobuf-based messages ) are successful.但是,使用 Protoman(基于 protobuf 的消息的类似 Postman 的 API 客户端)的测试是成功的。 I did the tests with the same proto files that I use in PHP.我使用在 PHP 中使用的相同原型文件进行了测试。

In this case the error is because the string is invalid.在这种情况下,错误是因为字符串无效。
And it is invalid because the value (string) returned by CURL includes all the data from the HTTP request, for example:并且它是无效的,因为 CURL 返回的值(字符串)包括来自 HTTP 请求的所有数据,例如:

HTTP/2 200 
content-type: application/x-protobuf
date: Wed, 02 Jun 2021 23:12:37 GMT
content-length: 172

╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"

I didn't notice this because I thought those details were due to the CURLOPT_VERBOSE => true option.我没有注意到这一点,因为我认为这些细节是由于CURLOPT_VERBOSE => true选项造成的。

Now, how to extract the body from the value returned by CURL is a bit complex, in this question you will see why.现在,如何从 CURL 返回的值中提取 body 有点复杂,在这个问题中你会明白为什么。

My solution is as follows (I repeat, read the question I mentioned, maybe a simpler solution will work for you):我的解决方案如下(我重复一遍,阅读我提到的问题,也许更简单的解决方案对你有用):

// I can't trust the Content-Length header (it may or may not be present).
// However, I can reliably calculate the length of the headers and use it instead.

$responseHeadersLength = 0;

$handle = curl_init($url);

$curl_options = [
    // ...
    CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$responseHeadersLength) {
            $len = strlen($header);
            $responseHeadersLength += $len;
            return $len;
    }
];

curl_setopt_array($handle, $curl_options);

$response = curl_exec($handle);

$body = trim(substr($response, $responseHeadersLength));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM