Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CURL Issue while doing a resumable upload

I have a script that uses the resumable upload prototype in the PHP Drive API, and it had been working for 3 or 4 months since I implemented it. On Saturday 17, the script stopped working, and the crontab didn't run the script due to having this problem:

[17-Oct-2015 05:15:07 America/Chicago] PHP Fatal error:  Uncaught exception 'Google_IO_Exception' with message 'HTTP Error: Unable to connect: 'fopen(): SSL: Broken pipe'' in /root/scriptEnCrontab/libs/src/Google/IO/Stream.php:141
Stack trace:
#0 /root/scriptEnCrontab/libs/src/Google/IO/Abstract.php(136): Google_IO_Stream->executeRequest(Object(Google_Http_Request))
#1 /root/scriptEnCrontab/libs/src/Google/Http/MediaFileUpload.php(164): Google_IO_Abstract->makeRequest(Object(Google_Http_Request))
#2 /root/scriptEnCrontab/respaldoDrive_cgi.php(183): Google_Http_MediaFileUpload->nextChunk('\x8EGu\xA9Y\xE9\xEEQ\x9B\xE1\xAD\x98Xw\xEB...')
#3 /root/scriptEnCrontab/respaldoDrive_cgi.php(96): insertFile(Object(Google_Client), Object(Google_Service_Drive), '/root/respaldo/...', 'RespaldoScripts...', '0B2Xiur2QhdC6fk...')
#4 {main}
  thrown in /root/scriptEnCrontab/libs/src/Google/IO/Stream.php on line 141

After few tweaks, upgrades and installing cURL, the problem changed to either

[20-Oct-2015 18:57:21 America/Chicago] PHP Fatal error:  Uncaught exception 'Google_IO_Exception' with message 'Couldn't resolve host 'www.googleapis.com'' in /root/scriptEnCrontab/libs/src/Google/IO/Curl.php:115
Stack trace:
#0 /root/scriptEnCrontab/libs/src/Google/IO/Abstract.php(136): Google_IO_Curl->executeRequest(Object(Google_Http_Request))
#1 /root/scriptEnCrontab/libs/src/Google/Http/MediaFileUpload.php(164): Google_IO_Abstract->makeRequest(Object(Google_Http_Request))
#2 /root/scriptEnCrontab/respaldoDrive_cgi.php(186): Google_Http_MediaFileUpload->nextChunk('C\x9D\t\xD9\x95\x1F\xAF\xF5!qJ\xCAq\x8CB...')
#3 /root/scriptEnCrontab/respaldoDrive_cgi.php(101): insertFile(Object(Google_Client), Object(Google_Service_Drive), '/root/respaldo/...', 'PaginasWeb.tgz', '0B2Xiur2QhdC6fk...')
#4 {main}
  thrown in /root/scriptEnCrontab/libs/src/Google/IO/Curl.php on line 115

or

[26-Oct-2015 11:36:24 America/Chicago] PHP Fatal error:  Uncaught exception 'Google_IO_Exception' with message 'Operation timed out after 100000 milliseconds with 0 bytes received' in /root/scriptEnCrontab/libs/src/Google/IO/Curl.php:115
Stack trace:
#0 /root/scriptEnCrontab/libs/src/Google/IO/Abstract.php(136): Google_IO_Curl->executeRequest(Object(Google_Http_Request))
#1 /root/scriptEnCrontab/libs/src/Google/Http/MediaFileUpload.php(164): Google_IO_Abstract->makeRequest(Object(Google_Http_Request))
#2 /root/scriptEnCrontab/respaldoDrive_cgi.php(187): Google_Http_MediaFileUpload->nextChunk('S\x98\x85\xC7\xFE\x0E\x8E8\xEE\xE9\n\xF9\x86{\x19...')
#3 /root/scriptEnCrontab/respaldoDrive_cgi.php(99): insertFile(Object(Google_Client), Object(Google_Service_Drive), '/root/respaldo/...', 'RespaldoScripts...', '0B2Xiur2QhdC6fk...')
#4 {main}
  thrown in /root/scriptEnCrontab/libs/src/Google/IO/Curl.php on line 115

I can't seem to make any of this to work with either version 1.1.6, 1.1.5 or 1.1.4, even though it had been working with the 1.1.4 version without cURL installed.

EDIT: Now I don't have the googleapis resolve problem, but now it's always the Operation timeout error. Here's the verbose from a run I did with the IPv4 CURL setting:

* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 308 Resume Incomplete
< X-GUploader-UploadID: AEnB2Uqz5qHxRUf_l-0Eg72_ZVU7fNQ-aMdzSQEzufNGQa2kPM55YHEru0NA3OJQNFidKV7NvUJDQNO9uhVad1q9xHxiTqtqMg
< Range: bytes=0-1992294399
< X-Range-MD5: 91233d77f053f5b383c37ddacf30c29d
< Content-Length: 0
< Date: Fri, 30 Oct 2015 17:21:27 GMT
< Server: UploadServer
< Content-Type: text/html; charset=UTF-8
< Alternate-Protocol: 443:quic,p=1
< Alt-Svc: quic=":443"; p="1"; ma=604800
* HTTP error before end of send, stop sending
<
* Closing connection #0
* About to connect() to www.googleapis.com port 443 (#0)
*   Trying 216.58.217.42...
* connected
* Connected to www.googleapis.com (216.58.217.42) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /root/scriptEnCrontab/libs/src/Google/IO/cacerts.pem
  CApath: /etc/ssl/certs
* SSL connection using ECDHE-RSA-RC4-SHA
* Server certificate:
*        subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=*.googleapis.com
*        start date: 2015-10-21 22:31:24 GMT
*        expire date: 2016-01-19 00:00:00 GMT
*        subjectAltName: www.googleapis.com matched
*        issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*        SSL certificate verify ok.
> PUT /upload/drive/v2/files?uploadType=resumable&upload_id=AEnB2Uqz5qHxRUf_l-0Eg72_ZVU7fNQ-aMdzSQEzufNGQa2kPM55YHEru0NA3OJQNFidKV7NvUJDQNO9uhVad1q9xHxiTqtqMg HTTP/1.1
Host: www.googleapis.com
Accept: */*
content-range: bytes 1992294400-2044723199/4840357256
content-type: application/json; charset=UTF-8
content-length: 52428800

My PHP version is 5.4.45-0+deb7u1 and cURL version is: 7.26.0. Thanks for the current help Francois.

like image 331
Rg14 Avatar asked Mar 07 '26 21:03

Rg14


1 Answers

tl;dr Add this in your code:

$google_config = new Google_Config();
$google_config->setClassConfig('Google_IO_Curl', 'options',
  array(
    CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
  )
);
$google_client = new Google_Client($google_config);

Long version:

The fact your script "Couldn't resolve host 'www.googleapis.com'" hints DNS problems. "www.googleapis.com" has both IPv4 and IPv6 addresses. My guess is that either Google's or your own network has recent changes or bugs that cause problems with IPv6. The above code forces resolving host names to IPv4 addresses.

If this does not solve your issue, please provide relevant parts from a debug output of your script. Share your PHP and cURL versions too. To enable cURL verbose output of Google PHP Drive API, add in your code:

$google_config = new Google_Config();
$google_config->setLoggerClass('Google_Logger_File');
$google_config->setClassConfig('Google_IO_Curl', 'options',
  array(
    CURLOPT_VERBOSE => TRUE,
  )
);
$google_client = new Google_Client($google_config);

You can see what IP version is used in the output. Compare:

* About to connect() to www.googleapis.com port 443 (#0)
*   Trying 74.125.136.95... * connected

With:

* About to connect() to www.googleapis.com port 443 (#0)
*   Trying 2a00:1450:4013:c01::5f... * connected

Landed on this question via a Google search because I experienced the exact same issue. A script in crontab started failing yesterday with "Operation timed out after 100000 milliseconds with 0 bytes received" errors. Some runs went through successfully though, and I'm still not 100 % sure why. I've forced IPv4 like explained above, and did not see new errors so far.

like image 197
François Avatar answered Mar 09 '26 09:03

François