使用PayPal API的CURLE_RECV_ERROR

时间:2011-08-26 15:45:31

标签: debugging curl ocaml paypal ssl

我开发了一个使用libcurl连接到PayPal API的应用程序,我通过OCurl绑定来使用来自Debian服务器上运行的进程的OCaml。代码在Paypal沙箱(端点https://api-3t.sandbox.paypal.com/nvp)内部始终有效,但在连接到实际的Paypal服务器(端点https://api-3t.paypal.com/nvp)时永远无效。

Libcurl始终返回CURLE_RECV_ERROR。普遍的共识是,当出现网络问题时会发生此错误,因此我对此进行了调查。

我使用命令行curl工具从完全相同的服务器运行完全相同的请求,使用完全相同的进程uid / gid,并且它始终有效。使用tcpdump跟踪转移并未显示工作命令行curl和非工作应用程序所做事务结构中的任何重大差异,因此全部显示好像在两种情况下都成功执行了HTTP请求。再说一遍,它是HTTPS,所以我无法确定。

以下是执行请求的OCaml代码:

let c = new Curl.handle in
let buffer = Buffer.create 1763 in

c # set_url "https://api-3t.paypal.com/nvp" ;
c # set_post true ;
c # set_postfields "SOMEDATA" ;
c # set_postfieldsize (String.length "SOMEDATA") ;
c # set_writefunction (fun x -> Buffer.add_string buffer x ; String.length x) ;
c # perform ;
c # cleanup ;

Buffer.contents buffer

以下是等效的curl命令行:

curl -X POST https://api-3t.paypal.com/nvp -d SOMEDATA

编辑:通过增加libcurl详细程度,我确定了潜在的错误:

GnuTLS recv error (-9): A TLS packet with unexpected length was received.

导致此错误的原因是什么?我该如何调查才能找到答案?

编辑2:命令行和库使用之间的区别似乎是命令行版本链接到OpenSSL,并且库链接到GnuTLS。

如何将两者都链接到OpenSSL?

2 个答案:

答案 0 :(得分:1)

首先,进一步调试这些问题的关键是使用curl的调试工具,即VERBOSE设置(以及可能的DEBUGFUNCTION设置,用于以您的方式打印数据)。

c # set_verbose true ;

这将错误识别为GnuTLS的一个问题,也讨论了here,并通过将SSLVERSION设置为3来强制使用SSLv3来解决。

c # set_sslversion 3 ;

答案 1 :(得分:0)

我总是将curl#set_postfieldsize称为传递给curl#set_postfields的数据长度。我的代码是:

let make_get url =
  let curl = new Curl.handle in
  curl#set_writefunction String.length; (* ignore result *)
  curl#set_tcpnodelay true;
  curl#set_verbose false;
  curl#set_post false;
  curl#set_url url;
  curl

let make_post url =
  let curl = make_get url in
  curl#set_post true;
  curl#set_httpheader [
  "Content-Type: text/xml; charset=\"UTF-8\"";
  "SOAPAction: \"\"";
  ];
  curl#set_postfields xml;
  curl#set_postfieldsize (String.length xml);
  curl

我希望这会有所帮助。