I've developed an application that connects to the PayPal API with libcurl, which I use through the OCurl bindings for OCaml from a process running on a Debian server. The code always works when inside the Paypal sandbox (endpoint https://api-3t.sandbox.paypal.com/nvp
) but never works when connecting to the actual Paypal servers (endpoint https://api-3t.paypal.com/nvp
).
Libcurl always returns CURLE_RECV_ERROR
. The general consensus is that this error happens when there is a network problem, so I have investigated that.
I ran the exact same request with the command-line curl
tool from the exact same server, using the exact same process uid/gid, and it consistently works. Tracking the transfers with tcpdump
does not reveal any significant difference in the structure of transactions made by the working command-line curl
and the non-working application, so it all appears as if the HTTP request is successfully performed in both cases. Then again, it's HTTPS, so I cannot be certain.
Here is the OCaml code that performs the request:
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
Here is the equivalent curl
command line:
curl -X POST https://api-3t.paypal.com/nvp -d SOMEDATA
EDIT: By increasing the libcurl verbosity, I determined that the underlying error is this:
GnuTLS recv error (-9): A TLS packet with unexpected length was received.
What could be the cause of this error? How can I investigate to find out?
EDIT 2: It appears that the difference between command-line and library use is that the command-line version is linked to OpenSSL and the library is linked to GnuTLS.
How do I link both to OpenSSL?