LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-08-2016, 02:32 PM   #1
shachter
Member
 
Registered: Jul 2007
Posts: 101

Rep: Reputation: 2
C++ rest api


Fellow Nerds,

I am writing a C++ program that needs to contact the Stripe server
(https://stripe.com/documents/api#intro). It is a REST interface.
The development (and, for the moment, the deployment) platform is
Centos 6.6 and the program has to be compiled with the -m32 option
because it links with proprietary 32-bit libraries to which we do
not have the source.

Stripe provides APIs in Ruby, Python, PHP, and Java -- all interpreted
languages -- and also documents what it calls its "Curl" API, which
means, as I understand it, "here are the URLs, you connect to them
and send and retrieve data using any language you like". This could
literally be using the curl program in a shell script, or it could
be connecting to the URLs from within a program some other way.

Calling std::system for every Stripe transaction is, of course,
bogus. I am looking for a C++ class library that would enable me to
use the Stripe REST interface without forking a process (two
processes, actually) for each and every transaction. The other
alternative I thought of would be to keep a PHP interpreter running
at all times as a server, and connect to it using unix-domain (or even
Internet-domain) sockets, but I don't know if PHP can do that.

What C++ class library do you recommend for doing this? Search
engines have led me to Microsoft's Casablanca project, but I don't see
a CentOS package for it, and I couldn't build it from source on CentOS
using -m32. As always, thank you in advance for any and all replies.

Jay F. Shachter
6424 N Whipple St
Chicago IL 60645-4111
(1-773)7613784 landline
(1-410)9964737 GoogleVoice
jay@m5.chicago.il.us
http://m5.chicago.il.us

"Quidquid latine dictum sit, altum videtur"
 
Old 03-08-2016, 02:38 PM   #2
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,223

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
Any C or C++ HTTP request library. libcurl would be an obvious suggestion.

REST means standard HTTP.

Last edited by dugan; 03-08-2016 at 03:42 PM.
 
Old 03-09-2016, 11:01 PM   #3
shachter
Member
 
Registered: Jul 2007
Posts: 101

Original Poster
Rep: Reputation: 2
Yes, I have started using libcurl, since posting the above.

But I have not been able to get it to work. I have read the fabulous
manual, and still I have not been able to get it to work.

I need to write a program that accomplishes in C what the following
command line invocation accomplishes:

curl --trace-ascii - "https://xxxxx:@api.stripe.com/v1/charges" -d "customer=xxx&currency=USD&amount=123"

where the Stripe ID and the Stripe customer ID have obviously been
redacted.

When I run the above program with "--trace-ascii -", I see the
following, in pertinent part:

POST /v1/charges HTTP/1.1
Authorization: Basic c2tfdGVzdF9sSzhyQkdHcWFQSDJPZkxqNng0RlM5YTM6
User-Agent: 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
Host: api.stripe.com
Accept: */*
Content-Length: 51
Content-Type: application/x-www-form-urlencoded
=> Send data, 51 bytes (0x33)
customer=xxx&currency=USD&amount=123
<= Recv header, 17 bytes (0x11)
HTTP/1.1 200 OK
<= Recv header, 15 bytes (0xf)
Server: nginx
<= Recv header, 37 bytes (0x25)
Date: Thu, 10 Mar 2016 04:05:21 GMT
<= Recv header, 32 bytes (0x20)

et cetera. The point is, that curl does the post, then sends the post
data, then receives an OK response, followed by headers and (not shown
above) data. In other words, the program succeeds.

I have tried to accomplish the same within a C++ program, using
libcurl. This is, in pertinent part, what I have, which, according to
my reading of the fabulous manual, ought to work:

curl_global_init(CURL_GLOBAL_ALL);
CURL *curlhandle = curl_easy_init();

curl_easy_setopt(curlhandle, CURLOPT_URL, "https://xxxxx:@api.stripe.com/v1/charges");
std::string postfields = "customer=xxx&currency=USD&amount=123";
curl_easy_setopt(curlhandle, CURLOPT_POSTFIELDS, postfields.c_str());
curl_easy_setopt(curlhandle, CURLOPT_POSTFIELDSIZE, (long)postfields.length());
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);

CURLcode retval = curl_easy_perform(curlhandle);
curl_easy_cleanup(curlhandle);
curl_global_cleanup();

(I have not registered a callback function to receive the returned
data; for the moment, I am satisfied to let the returned data be
written to standard output, like the curl program does.)

It does not work. The curl utility outputs the retrieved data,
whereas my attempt to create the libcurl equivalent, produces a "Bad
Request" error message. Here it is in detail:

POST /v1/charges HTTP/1.1
Authorization: Basic c2tfdGVzdF9sSzhyQkdHcWFQSDJPZkxqNng0RlM5YTM6
Host: api.stripe.com
Accept: */*
Content-Length: 51
Content-Type: application/x-www-form-urlencoded

HTTP/1.1 400 Bad Request
Server: nginx
Date: Thu, 10 Mar 2016 02:35:47 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 522
Connection: keep-alive

(data then follow, containing a JSON representation of the error message)

It does not appear that the POST fields are being sent. What am I
missing? What does one do in libcurl that I have not done?

In case you were about to suggest it, I did run ltrace on the
successful curl program, and grep the output for curl_easy. The
output is not helpful, I see curl_easy_init() called with 5
arguments, rather than 0, and I see curl_easy_setopt() being called a
hundred times (this may be an exaggeration, but if so, it is only a
slight one) with 5 arguments rather than 3. But ltrace does not show
me the symbolic constants in the argument list to the curl_easy_*
functions, it does not show me their significance or how they were
computed, it does not tell me how to write my C++ program so that it
does what the curl program does.

As always, thank you in advance for any and all replies.
 
Old 03-10-2016, 03:12 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Please use [code] and [/code] tags whenever you quote source code or program-output.

Edit: you could as well quote the 'JSON error message' too.

Edit: try to find out the used SSL version in both case (SSL2, SSL3, TLS1, TLS1.1, TLS1.2).

Last edited by NevemTeve; 03-10-2016 at 03:27 AM.
 
Old 03-10-2016, 09:29 AM   #5
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,223

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
Quote:
It does not appear that the POST fields are being sent.
That's all you need to focus on right now. The comments here should be a hint:

http://stackoverflow.com/questions/7...nt-only-header

Maybe give the libcurl request a user-agent?

Last edited by dugan; 03-10-2016 at 09:48 AM.
 
Old 03-10-2016, 11:19 AM   #6
shachter
Member
 
Registered: Jul 2007
Posts: 101

Original Poster
Rep: Reputation: 2
Indeed, it seems that the poster on the Stack Overflow site,
to whose question you directed me, was experiencing the
exact same problem I was, and that he solved it.

He does not, however, say how he solved it. He says,
"this was the option that solved my problem", words to
that effect -- and does not say what the option was.

If I knew how to contact that person, I would ask him
how he solved his problem, hoping that he remembers,
after 5 years. But as far as I can determine, Stack
Overflow gives me no way of contacting him. Unfortunately,
therefore, my question remains unanswered: thru use of
libcurl, I am successfully sending a POST request to
an HTTPS site, but it appears that the POST data are not
being sent. What am I doing wrong? As always, thank
you in advance for any and all replies.

jay at m5 dot chicago dot il dot us
 
Old 03-10-2016, 11:20 AM   #7
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,223

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
What part of "Maybe give the libcurl request a user-agent?" did you miss?

From what you've already writen here, I can see that the curl request sent a user agent but the libcurl request did not.The comments on the stackoverflow post, which I specifically said to pay attention to, and which you failed to acknowledge at all, said that the POST request was not sent because the server said not to. Adding a user agent, therefore, would be the next reasonable step to try.

If that does not work, then you should set up a proxy such as Fiddler, Charles, mitmxproxy or zaproxy, use it to capture requests from both curl and libcurl, and then compare them to see how they are different. You would then determine why those differences are there and how to eliminate them.

And stop implying that you want private help via email. You want answers handed to you? Then you ask Stripe, not us, for support. Come to think of it, you should probably have just done that in the first place.

Last edited by dugan; 03-15-2016 at 12:32 AM.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
openstack-nova-{compute,network,api,metadata-api} as it says pid file exists but dead Bhargavnagaraju Linux - Newbie 0 05-28-2015 05:47 PM
Tcl to login to a Rest API interface Jykke Programming 1 04-03-2015 02:02 PM
Need help on my LED REST API aoiregion Programming 2 07-26-2014 01:48 AM
LXer: Secure programming with the OpenSSL API, Part 1: Overview of the API LXer Syndicated Linux News 0 06-29-2012 12:30 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:23 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration