API-3.0-PHP icon indicating copy to clipboard operation
API-3.0-PHP copied to clipboard

Requisição via QuerySaleRequest está retornando conteúdo comprimido

Open dlepera opened this issue 4 years ago • 10 comments

Olá!

Algumas requisições feitas para consulta via PaymentId estão retornando um conteúdo zipado (comprimido). Isso faz com que a API apresente um erro por tentar fazer o json_decode do conteúdo comprimido:

Argument 1 passed to Cielo\API30\Ecommerce\Sale::populate() must be an instance of stdClass, null given

A solução seria algo mais ou menos assim sempre que for usar o JSON (apenas uma sugestão):

$response = json_decode($response) or json_decode(gzdecode($response));

Desde já agradeço a atenção.

dlepera avatar Oct 29 '20 21:10 dlepera

Muito Obrigado Diego Lepera eu estava com este erro no meu sistema fiz a decodificação como falaste json_decode(gzdecode($response)) o código passou a funcionar corretamente novamente

MauricioGeek avatar Oct 29 '20 22:10 MauricioGeek

Muito Obrigado Diego Lepera eu estava com este erro no meu sistema fiz a decodificação como falaste json_decode(gzdecode($response)) o código passou a funcionar corretamente novamente

Que bom que deu certo :D rsrs

dlepera avatar Oct 30 '20 12:10 dlepera

Pelo que vi o problema parece ser na classe AbstractRequest método sendRequest com o cabeçalho Accept-Encoding: gzip

protected function sendRequest($method, $url, \JsonSerializable $content = null)
    {
        $headers = [
            'Accept: application/json',
            'Accept-Encoding: gzip',
            'User-Agent: CieloEcommerce/3.0 PHP SDK',
            'MerchantId: ' . $this->merchant->getId(),
            'MerchantKey: ' . $this->merchant->getKey(),
            'RequestId: ' . uniqid()
        ];

Retirando Accept-Encoding: gzip do header funcionou normalmente para mim.

Consegue verificar @netojoaobatista ?

edson-nascimento avatar Oct 30 '20 18:10 edson-nascimento

Estou com o mesmo erro aqui. O estranho é que quando faço a primeira solicitação recebo um arquivo, mas se faço exatamente a mesma consulta pela segunda vez, recebo o json esperado como retorno.

jeanvcastro avatar Oct 30 '20 19:10 jeanvcastro

Pelo que vi o problema parece ser na classe AbstractRequest método sendRequest com o cabeçalho Accept-Encoding: gzip

protected function sendRequest($method, $url, \JsonSerializable $content = null)
    {
        $headers = [
            'Accept: application/json',
            'Accept-Encoding: gzip',
            'User-Agent: CieloEcommerce/3.0 PHP SDK',
            'MerchantId: ' . $this->merchant->getId(),
            'MerchantKey: ' . $this->merchant->getKey(),
            'RequestId: ' . uniqid()
        ];

Retirando Accept-Encoding: gzip do header funcionou normalmente para mim.

Consegue verificar @netojoaobatista ?

Inicialmente eu tbm imaginei que poderia ser algo com esse header, mas pelo menos no meu caso não é sempre que a resposta vem "zipada", então supus que esse header não estava causando o problema. Por não ser algo que acontece sempre, eu resolvi momentaneamente usando o gzdecode mesmo. Porém estou no aguardo da solução definitiva :D

A minha solução temporária foi colocar o seguinte trecho na classe AbstractRequest, método readResponse(), na linha 129:

$responseBody = @gzdecode($responseBody) ?: $responseBody;

Se o conteúdo em $responseBody não estiver comprimido, o gzdecode vai retornar false e a variável $responseBody vai manter o seu conteúdo original. Caso contrário, o valor da $responseBody será alterado pelo valor do retorno do gzdecode. Dessa forma, todas as requests que extendem a AbstractRequest e implementam o método unserialize() já receberão a response tratada.

Se precisarem de mais informações estou à disposição!

dlepera avatar Oct 30 '20 19:10 dlepera

Eu tinha o mesmo problema, ralando aqui há dias, o retorno:

¬RMÚ0ý+•UBì$Kn,‹Ú•è.ZhµRՃ‰'ÂjSÛAP”ÿޙÀ–]©ªz¨‰çó½yãû¶ÜÊÖ?Zö^± [ÎïB1æiŠŸqÁ6ëœ7 X69±Ù

:)

Obrigado, @dlepera! Acho q até eu pensar no gzip ia passar uma vida.

alexlana avatar Nov 03 '20 16:11 alexlana

Eu tinha o mesmo problema, ralando aqui há dias, o retorno:

¬RM�Ú0�ý+��UBì$K�n,�Ú�è.ZhµRÕ��'Âj�SÛAP�ÿÞ�À�]©ªz¨��çó½yã�û�¶ÜÊÖ?Z�ö^± [ÎïB1æi��qÁ�6ë�7 X69±�Ù

:)

Obrigado, @dlepera! Acho q até eu pensar no gzip ia passar uma vida.

É nóis rsrs Eu demorei um pouco pra chegar nessa conclusão tbm! Até testes em produção tive que fazer kkkkkkkk

dlepera avatar Nov 03 '20 17:11 dlepera

Alterei o AbstractRequest.php na cópia q estou usando. Tem alguma coisa fora do padrão com o servidor onde está o projeto que estou trabalhando, eu acho. Na hora de verificar os dados do pedido precisa do gzdecode, na hora de realizar a compra não dá certo com o gzdecode...

Ficou assim:

        $response   = curl_exec($curl);
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        if ( strlen( @gzdecode($response) ) > 0 ) // nao oficial
            $response = gzdecode( $response ); // nao oficial

        if ($this->logger !== null) {
            $this->logger->debug('Resposta', [
                sprintf('Código de status: %s', $statusCode),
                json_decode($response)
            ]);
        }

alexlana avatar Nov 03 '20 21:11 alexlana

Pessoal, segue a minha implementação abaixo. Já vi que tem outras acima, mas esta analisa o cabeçalho da string zipada antes de tentar descompactar. Anexo também resultado.

Adicionado no AbstractRequest.php, método sendRequest, logo abaixo do curl_close().

// Solution source: https://stackoverflow.com/questions/10975775/how-to-determine-if-a-string-was-compressed
$is_gzip = 0 === mb_strpos($response , "\x1f" . "\x8b" . "\x08");
if($is_gzip){
      $response = gzdecode($response);
}

image

guircoelho avatar Nov 05 '20 21:11 guircoelho

Tem alguma previsão para a solução definitiva?

dlepera avatar Dec 23 '20 13:12 dlepera