Curl 返回錯誤 52 或 56,REST API 呼叫超過 5 分鐘
所以我一直在努力解決這個問題大約一個星期。這是執行失敗:
我在 PHP 中使用 CURL 從 API 中提取數據。隨著對 API 呼叫的響應變大(一次提取超過 15k 條記錄),我注意到任何需要 5 分鐘或更長時間(幾秒鐘內)的 API 呼叫都無法在我的 CentOS 和 Suse 伺服器上返回。所以,我通過 CURL 測試了 CLI 的 API 呼叫,我遇到了同樣的問題。奇怪的是,如果我通過 OS X 執行 CURL 命令,該命令執行良好並在大約 7 分鐘後返回。
這是我通過 CURL 執行的命令(經過審查的憑據):
curl -m 0 -k --trace-ascii trace.txt --trace-time -X GET -H "tenant-code: 1cmPx7tqVDVTdN1GSelwycFUmICmASnLCmNQsV72" -H "Authorization: Basic JxHAsXeUiHMRkS8Msiu6pWb3PvY20p6am3QvXCY3knXTAntlxTBS3EyEDgly" -H "Content-Type: application/json" -H "Cache-Control: no-cache" 'https://api.endpoint.com/API/v1/system/users/search?groupid=555' > dump.txt
以下是 CURL 為每個平台輸出的版本:
CentOS(這是我真正需要它工作的地方)-
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
使用-
curl 7.19.7 (x86_64-suse-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8j zlib/1.2.7 libidn/1.10 Protocols: tftp ftp telnet dict ldap ldaps http file https ftps Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
作業系統 X-
curl 7.37.1 (x86_64-apple-darwin14.0) libcurl/7.37.1 SecureTransport zlib/1.2.5 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz
這些是我從 Centos 得到的錯誤程式碼:
curl: (56) SSL read: errno -5961
我找不到文件中引用的程式碼。 https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/SSL_functions/sslerr.html
我從 Suse 得到一個稍微不同的錯誤:
curl: (52) SSL read: error:00000000:lib(0):func(0):reason(0), errno 104
錯誤 104 讓我相信伺服器正在停止/重置連接,但伺服器端日誌沒有顯示它被丟棄並且 OS X 可以毫無問題地提取數據。我什至嘗試欺騙使用者代理以確保這不是問題。
所以,在這一點上,我假設 SSL 包 SecureTransport 正在做一些 OpenSSL 和 NSS 沒有做的事情。問題是什麼,如果不是,問題是什麼?
在 MacOSX 機器上執行 curl 命令,但不要重定向輸出,讓它流式傳輸到您的 shell 視窗。觀察是否似乎涉及任何緩衝,IE,你是從一開始就得到輸出,一次一點,還是你在 5 分鐘內甚麼也沒有得到,然後一次全部數據?
在超時的機器上再次執行 curl 命令,並比較行為。如果 API 伺服器上的某個後台程序正在緩衝您的輸出,則在它完成查詢之前您可能無法獲得結果。您的客戶端應用程序、客戶端的作業系統、伺服器的作業系統、伺服器的 REST api 以及它們之間的 SSL 之間的某些東西可能具有非零超時值,並且如果該計時器在 5 分鐘內沒有看到任何數據流動,它可能會關閉您的連接而無需多說原因。我看到這種情況在基於 HTTP 的服務中經常發生。在 perl 中,我習慣性地將 a
$|=1;
放在程式碼的頂部以禁用伺服器端的輸出緩衝。Cisco ASA 等第 3 方設備也可能存在 NAT 規則超時和触發問題。我在嘗試從 ASA 外部的客戶端讀取 AMANDA 備份時遇到此問題。如果客戶端通過 ASA 將其大小估計值返回給 AMANDA 伺服器的時間過長,則 ASA 會丟棄其動態 NAT 規則並且備份會失敗。如果工作的 MacOSX 在它和 API 伺服器之間沒有防火牆,但失敗的 MacOSX 確實有防火牆,那麼這個建議值得研究。
如果 MacOSX 將超時值設置為 0(永遠等待),而 Linux 預設設置為 60 或 90 秒的限制,我一點也不會感到驚訝。