首页 > 解决方案 > Guzzle - cURL 错误 18:传输已关闭,剩余未完成的读取数据

问题描述

我正在尝试解决调用外部 API 的问题。使用 Postman,一切正常。当我尝试使用 Guzzle 时,会出现此错误。

我已经尝试过使用 HTTP 1.0 版,但它只是减少了我的响应,而且我没有收到正确的 JSON。响应中也没有 Content-Length 标头。

任何建议表示赞赏。

代码:

private const TIMEOUT = 90;
private const CONNECT_TIMEOUT = 90;
private const SSL_VERIFY = false;

// ...

private function getDefaultHeaders(): array
{
    $headers = [
        'accept' => '*/*',
        'Content-Type' => 'application/json',
        'Accept-Encoding' => 'gzip, deflate',
        'Connection' => 'keep-alive',
    ];

    if ($this->authorizationProvider->isAuthorizationEnabled()) {
        $headers['Authorization'] = $this->authorizationProvider->getAuthorizationHeader();
    }

    return $headers;
}

// ...

$response = $this->client->request(
    Request::METHOD_POST,
    $uri,
    [
        'body' => json_encode($body),
        'headers' => $this->getHeaders(),
        'timeout' => self::TIMEOUT,
        'connect_timeout' => self::CONNECT_TIMEOUT,
        'verify' => self::SSL_VERIFY,
    ]
);

例外:

GuzzleHttp\Exception\RequestException {#494
  -request: GuzzleHttp\Psr7\Request {#488
    -method: "GET"
    -requestTarget: null
    -uri: GuzzleHttp\Psr7\Uri {#484
      -scheme: "https"
      -userInfo: ""
      -host: "arch.xxx.com"
      -port: null
      -path: "/api/1/xxx/123456/xxx"
      -query: ""
      -fragment: ""
    }
    -headers: array:6 [
      "User-Agent" => array:1 [
        0 => "GuzzleHttp/6.5.1 curl/7.52.1 PHP/7.2.34"
      ]
      "Host" => array:1 [
        0 => "arch.xxx.com"
      ]
      "accept" => array:1 [
        0 => "application/json"
      ]
      "Content-Type" => array:1 [
        0 => "application/json"
      ]
      "accept-encoding" => array:1 [
        0 => "gzip, deflate"
      ]
      "Expect" => array:1 [
        0 => "100-continue"
      ]
    ]
    -headerNames: array:6 [
      "user-agent" => "User-Agent"
      "host" => "Host"
      "accept" => "accept"
      "content-type" => "Content-Type"
      "accept-encoding" => "accept-encoding"
      "expect" => "Expect"
    ]
    -protocol: "1.1"
    -stream: GuzzleHttp\Psr7\Stream {#487
      -stream: stream resource @329
        wrapper_type: "PHP"
        stream_type: "TEMP"
        mode: "w+b"
        unread_bytes: 0
        seekable: true
        uri: "php://temp"
        options: []
      }
      -size: 0
      -seekable: true
      -readable: true
      -writable: true
      -uri: "php://temp"
      -customMetadata: []
    }
  }
  -response: GuzzleHttp\Psr7\Response {#495
    -reasonPhrase: "OK"
    -statusCode: 200
    -headers: array:20 [
      "Content-Type" => array:1 [
        0 => "application/json"
      ]
      "Access-Control-Allow-Origin" => array:1 [
        0 => "*"
      ]
      "Access-Control-Allow-Headers" => array:1 [
        0 => "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,soapaction,dnt,x-customheader,keep-alive,user-agent,x-requested-with,if-modified-since,cache-control,content-type,content-range,range,X-NewRelic-ID,x-newrelic-id"
      ]
      "Access-Control-Allow-Methods" => array:1 [
        0 => "GET, POST, OPTIONS"
      ]
      "Access-Control-Expose-Headers" => array:1 [
        0 => "*"
      ]
      "Access-Control-Max-Age" => array:1 [
        0 => "1728000"
      ]
      "X-Frame-Options" => array:1 [
        0 => "SAMEORIGIN"
      ]
      "X-Content-Type-Options" => array:1 [
        0 => "nosniff"
      ]
      "X-XSS-Protection" => array:1 [
        0 => "1; mode=block"
      ]
      "X-UA-Compatible" => array:1 [
        0 => "IE=edge,chrome=1"
      ]
      "Accept-Ranges" => array:1 [
        0 => "bytes"
      ]
      "Vary" => array:1 [
        0 => "Accept-Encoding"
      ]
      "Expires" => array:1 [
        0 => "Fri, 05 Nov 2021 14:23:24 GMT"
      ]
      "Cache-Control" => array:1 [
        0 => "max-age=0, no-cache, no-store"
      ]
      "Pragma" => array:1 [
        0 => "no-cache"
      ]
      "Date" => array:1 [
        0 => "Fri, 05 Nov 2021 14:23:24 GMT"
      ]
      "Transfer-Encoding" => array:1 [
        0 => "chunked"
      ]
      "Connection" => array:2 [
        0 => "keep-alive"
        1 => "Transfer-Encoding"
      ]
      "Server-Timing" => array:3 [
        0 => "cdn-cache; desc=MISS"
        1 => "edge; dur=23"
        2 => "origin; dur=10997"
      ]
      "x-encoded-content-encoding" => array:1 [
        0 => "gzip"
      ]
    ]
    -headerNames: array:20 [
      "content-type" => "Content-Type"
      "access-control-allow-origin" => "Access-Control-Allow-Origin"
      "access-control-allow-headers" => "Access-Control-Allow-Headers"
      "access-control-allow-methods" => "Access-Control-Allow-Methods"
      "access-control-expose-headers" => "Access-Control-Expose-Headers"
      "access-control-max-age" => "Access-Control-Max-Age"
      "x-frame-options" => "X-Frame-Options"
      "x-content-type-options" => "X-Content-Type-Options"
      "x-xss-protection" => "X-XSS-Protection"
      "x-ua-compatible" => "X-UA-Compatible"
      "accept-ranges" => "Accept-Ranges"
      "vary" => "Vary"
      "expires" => "Expires"
      "cache-control" => "Cache-Control"
      "pragma" => "Pragma"
      "date" => "Date"
      "transfer-encoding" => "Transfer-Encoding"
      "connection" => "Connection"
      "server-timing" => "Server-Timing"
      "x-encoded-content-encoding" => "x-encoded-content-encoding"
    ]
    -protocol: "1.1"
    -stream: GuzzleHttp\Psr7\Stream {#493
      -stream: stream resource @331
        wrapper_type: "PHP"
        stream_type: "TEMP"
        mode: "w+b"
        unread_bytes: 0
        seekable: true
        uri: "php://temp"
        options: []
      }
      -size: null
      -seekable: true
      -readable: true
      -writable: true
      -uri: "php://temp"
      -customMetadata: []
    }
  }
  -handlerContext: array:30 [
    "errno" => 18
    "error" => "transfer closed with outstanding read data remaining"
    "appconnect_time" => 0.042203
    "url" => "https://arch.xxx.com/api/1/xxx/123456/xxx"
    "content_type" => "application/json"
    "http_code" => 200
    "header_size" => 1040
    "request_size" => 237
    "filetime" => -1
    "ssl_verify_result" => 0
    "redirect_count" => 0
    "total_time" => 11.115178
    "namelookup_time" => 0.012257
    "connect_time" => 0.020937
    "pretransfer_time" => 0.042225
    "size_upload" => 0.0
    "size_download" => 52470.0
    "speed_download" => 4720.0
    "speed_upload" => 0.0
    "download_content_length" => -1.0
    "upload_content_length" => -1.0
    "starttransfer_time" => 11.101096
    "redirect_time" => 0.0
    "redirect_url" => ""
    "primary_ip" => "2.1.2.1"
    "certinfo" => []
    "primary_port" => 443
    "local_ip" => "192.168.200.181"
    "local_port" => 33130
    "curl_version" => "7.52.1"
  ]
  #message: "cURL error 18: transfer closed with outstanding read data remaining (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)"
  #code: 200
  #file: "/var/www/api/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php"
  #line: 201
  trace: {
    /var/www/api/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:201 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:155 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:105 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php:43 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php:28 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php:51 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php:37 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Middleware.php:29 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php:70 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Middleware.php:59 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/HandlerStack.php:71 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Client.php:361 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Client.php:163 {}
    /var/www/api/vendor/guzzlehttp/guzzle/src/Client.php:183 {}
    /var/www/api/src/RestConnectorService.php:126 {
      Api\RestConnectorService->sendGetRequest(string $uri): ResponseInterface …
      ›     'connect_timeout' => self::CONNECT_TIMEOUT,
      ›     'verify' => self::SSL_VERIFY,
      › ]
      arguments: {
        $method: "GET"
        $uri: "https://arch.xxx.com/api/1/xxx/123456/xxx?"
        $options: array:5 [ …5]
      }
    }el/HttpKernel.php:68 {}
    /var/www/api/vendor/symfony/http-kernel/Kernel.php:201 {}
    /var/www/api/public/index.php:25 {}
  }
}

标签: phphttpcurlguzzle

解决方案


推荐阅读