I'm wondering the most simple way to send a request to a API on my server then receive the API's response (json array) wihtout using any libraries. I've tried using libs like cURL & boost without any luck which is the reason i want to stay away from them. I've searched for many days for a answer and have not been able to find anything, which is why i've resorted to coming to the stack overflow community!
Even though the question is about not using a library I 'am taking this opportunity to show how easy it is to use a library than the user thinks.
Its better to use pre-built libraries and stop reinventing the wheel. You can use curlcpp library. Its a wrapper for libcurl. Using this library HTTP requests can be made easily. Learning curve is also less and it provides C++ style access which makes it more comfortable to work with.
The following code is taken from their gitHub page - https://github.com/JosephP91/curlcpp
It makes a simple GET request to Google and retrieves the HTML response. You can use this example to hit apis too.
#include "curl_easy.h"
#include "curl_exception.h"
using curl::curl_easy;
using curl::curl_easy_exception;
using curl::curlcpp_traceback;
int main(int argc, const char **argv) {
curl_easy easy;
// Add some option to the curl_easy object.
easy.add<CURLOPT_URL>("http://www.google.it");
easy.add<CURLOPT_FOLLOWLOCATION>(1L);
try {
// Execute the request.
easy.perform();
} catch (curl_easy_exception error) {
// If you want to get the entire error stack we can do:
curlcpp_traceback errors = error.get_traceback();
// Otherwise we could print the stack like this:
error.print_traceback();
// Note that the printing the stack will erase it
}
return 0;
}
Related
I am trying to play around Google Pub/Sub and I need to integrate it in C++ code-base.
As there is no native support for Google Pub/Sub in C++, I am using it through gRPC. Thus, I have generated corresponding pubsub.grpc.pb.h, pubsub.grpc.pb.cc, pubsub.pb.h and pubsub.pb.cc files via protoc.
Question part: because of lack of documentation it would be very helpful to have an example in C++. I have found an example for publisher part, but not for the subscriber part. I tried to dive into the generated code and examples in other languages, but quite many question arise. Is there any example for the subscriber part? Or may be someone already had such kind of experience?
Just like you are making Publish requests, you can make StreamingPull requests for messages. Note that this is a simple proof of concept, and, in practice, you’d probably want to make this code more robust; e.g. create multiple streams, have the message processing happen on a thread pool, implement some kind of flow control, etc…
#include <iostream>
#include <memory>
#include <grpc++/grpc++.h>
#include "google/pubsub/v1/pubsub.grpc.pb.h"
auto main() -> int {
using grpc::ClientContext;
using grpc::ClientReaderWriter;
using google::pubsub::v1::Subscriber;
using google::pubsub::v1::StreamingPullRequest;
using google::pubsub::v1::StreamingPullResponse;
auto creds = grpc::GoogleDefaultCredentials();
auto stub = std::make_unique<Subscriber::Stub>(
grpc::CreateChannel("pubsub.googleapis.com", creds));
// Open up the stream.
ClientContext context;
std::unique_ptr<ClientReaderWriter<
StreamingPullRequest, StreamingPullResponse>> stream(
stub->StreamingPull(&context));
// Send initial message.
StreamingPullRequest request;
request.set_subscription(
"projects/pubsub-cpp-api-1504713535863/subscriptions/testing");
request.set_stream_ack_deadline_seconds(10);
stream->Write(request);
// Receive messages.
StreamingPullResponse response;
while (stream->Read(&response)) {
// Ack messages.
StreamingPullRequest ack_request;
for (const auto &message : response.received_messages()) {
ack_request.add_ack_ids(message.ack_id());
}
stream->Write(ack_request);
}
}
This is the newest Cloud Pub/Sub API, and is the currently recommended way of pulling messages from the service; this is especially true for users who expect high throughput and low latency. Currently, there is no existing client library for C++, but there is an open issue on GitHub for it. The existing client libraries for other languages (e.g. Java) already use this API, so you may be able to replicate their functionality in your own C++ code.
For simpler use-cases, you could also use the older Pull API, which makes many independent requests for messages. Note that, for high throughput and low latency, you should most likely be making many simultaneous asynchronous RPCs: see gRPC documentation.
#include <iostream>
#include <memory>
#include <grpc++/grpc++.h>
#include "google/pubsub/v1/pubsub.grpc.pb.h"
auto main() -> int {
using grpc::ClientContext;
using google::pubsub::v1::Subscriber;
using google::pubsub::v1::PullRequest;
using google::pubsub::v1::PullResponse;
auto creds = grpc::GoogleDefaultCredentials();
auto stub = std::make_unique<Subscriber::Stub>(
grpc::CreateChannel("pubsub.googleapis.com", creds));
PullRequest request;
request.set_subscription(
"projects/pubsub-cpp-api-1504713535863/subscriptions/testing");
request.set_max_messages(50);
request.set_return_immediately(false);
PullResponse response;
ClientContext ctx;
auto status = stub->Pull(&ctx, request, &response);
if (!status.ok()) {
// ...
}
// Do something with "response".
}
As a last resort, you could use a Push subscription, which would only require you to implement an HTTP endpoint on your client. However, this is not usually recommended unless you are fanning in from multiple subscriptions, or for cases where your client cannot make outgoing requests.
There is c++ library called pubsuber for accessing google pubsub.
For more information look here.
I am trying to make this working code to check if URL exists (coded Visual C++):
void urlexists()
{
try
{
LPCWSTR pfile(NULL);
HRESULT hRez = URLDownloadToFile(NULL, _T("http://google.com"), (pfile), 0, NULL);
if (hRez != 0)
return;
}
catch (...)
{
return;
}
}
and make it portable for linux distros. What should I do? I didn't found nothing on Internet
As far as the process goes, if you make a GET request to the URL, you will get a 200/OK code back if the resource exists. You will receive a 404 if it does not. Your file will be in the body of the request if the request succeeds. You then copy the request body to the file on disk.
There isn't a good way to make this portable without writing a libcurl, winhttp, and possibly a core foundation implementation. You either need to abstract this and write an implementation for each platform, or use a library that does it for you. There are a few options. Boost has an http client you could use. Also, the AWS SDK for C++ has an http implementation that will do this for you.
Your other option is to read the HTTP spec, open the socket yourself and make the request manually. Fair warning however, this is non-trivial especially if TLS is involved.
If you want to write it yourself, I recommend libcurl for your linux implementation. You are more than welcome to use the examples here as a starting point. https://github.com/awslabs/aws-sdk-cpp/tree/master/aws-cpp-sdk-core/include/aws/core/http
I am having problems with oauth. Let me start by saying that I have only been studying C++ for about a month. I am working on a Etrade API application. I have been struggling with this for a few weeks. Ok Etrade has provided the header, DLL and library files. I am having trouble just calling a simple function. Etrade list examples on how to call a Function for Java, and PHP but no C++. I just need a example for one function and I can pretty much go from there. here is a link to the API help
https://us.etrade.com/ctnt/dev-portal/getContent?contentUri=V0_Code-SDKGuides-VC
the arguments for the first function are
m_environment IN Optional. Possible values are SANDBOX (default) and LIVE.
m_strConsumerKey IN OAuth consumer key provided by E*TRADE
m_strConsumerSecret IN OAuth consumer secret provided by E*TRADE
m_strToken OUT Returned by the function if successful
m_strTokenSecret OUT Returned by the function if successful
m_strCallback IN Optional; default value is "oob"
Here is my code first function (oauth)
int main(int argc, char **argv)
{
}
bool COAuthSDK::GetRequestToken(CClientDetails &objClientDetails)
{
return GetRequestToken;
}
You're missing the point. ETrade provides you with COAuthSDK::GetRequestToken; You're supposed to call it, not re-implement it yourself. The m_ arguments are members of the CClientDetails object that you, as the client, have to provide.
Just a heads up. The Authorize URL in the docs(v0) is wrong! Doh! If you are having problems with that step, try the following URL.
Here is the correct URL: https://us.etrade.com/e/t/etws/authorize
Notice there is an additional 't' in the URL
BTW, I wrote a simple Node app called Trading Robo Monkey. If you have never used OAuth before, you can try to see if that was your problem by looking at the JS code
https://github.com/shikhirsingh/ETrade-API-Robo-Trading-Monkey-4-NodeJS
I'm trying to use the libcurl in a C/C++ application to post files to DropBox.
I would like to use the "/files (POST)" API as documented here...
https://www.dropbox.com/developers/reference/api#files-POST
I am having problems with properly authenticating (OAuth) this call. It is unclear to me how to properly create the authentication signature.
From some a sample I saw, it looked like they were reading in the whole file to create the HMAC-SHA1 encoding on. This seems problematic on large files.
Does anyone have experience or insight using this API or something similar?
I have just use the libouth and libcurl to get information from sina weibo. here is my example for you refer. you can also refer the liboauth test programmer in the tests dir, oauthtest.c
if (use_post)
{
req_url = oauth_sign_url2(test_call_uri, &postarg, OA_HMAC, NULL, c_key, c_secret, t_key, t_secret);
reply = oauth_http_post(req_url,postarg);
}
I suggest using BOOST ASIO . Makes uploading and downloading a breeze.
I am a beginner in writing web application, so please co-operate if its a silly question. Our web application is hosted using tomcat 6. I have some C++ code to be executed in server when user click on corresponding button. Client side is written in html/JS and hosted using tomcat.
So, My problem is I dont know how this C++ code will be executed when a button is clicked in html page. Can anyone please help me?
[updated]
I can change from tomcat to any other server but code has to be in c++. So if you have any other server(wamp or smthing) or links to do the same. Please let me know
Tomcat, a Java Servlet container is definitely not the most appropriate vehicle to execute C++ code in. You could try to use JNI to make a servlet run the C++ code, but it seems to me that there are much easier and reliable ways, like good old CGI's. Tomcat can do CGI, as explained here, with some limitations and restrictions.
Update: I think we can agree that the CGI route is the way to go. Most webservers allow you to run cgi's, and it will definitely be simpler than with Tomcat. I also suggest you delegate the work of connecting your code to the web server to a library, like gnu cgicc (nice tutorial here) or cgic. A plain old WAMP (you'll just use the WA part here) and that sample code should get you up to speed in no time. The rest will be pretty standard Web development.
https://stackoverflow.com/questions/175507/c-c-web-server-library answers may well help you out.
Given that Tomcat is no longer a requirement, using a different http front end may well make your life easier.
If you do decide to use Tomcat Which C++ Library for CGI Programming? may help you pick a library.
Barring that, if you use Apache, you can write a plugin module itself, instead of CGI, which will give you much better performance. (Other web servers generally have similar plug-in methodologies also...)
Good Luck
I'm not sure any of these answers addressed the question. Coding a CGI using C++ would mean reading environment variables that are set by the web server, regardless of whether or not you use a third party library or which web server is run, including tomcat. The following example is a quick-and-dirty way to grab the most interesting input, the query string. If you are starting out, it's I think better to start with basics so if you decide to use some sort of external library it will seem less mystical. This should give you enough to hit google and work out what's happening.
#include <stdlib.h>
#include <iostream>
using namespace std;
int
main(int argc, char** argv)
{
string method = getenv("REQUEST_METHOD");
string query;
if (method == "GET")
query = getenv("QUERY_STRING");
else if (method == "POST")
cin >> query;
else
query = "Not sure what to do with method " + method;
cout << "Content-Type: text/html" << endl << endl
<< "<html>" << endl
<< query << endl
<< "</html>" << endl;
}
Note Content-Type in the output. That's a HTTP header. You can add any number of headers before the double endl. For a light bulb moment try changing Content-Type to text/plain.
Compile the example code to shiney_cpp_cgi, copy it to your cgi dir (for tomcat that's generally tomcat_root/webapps/ROOT/WEB-INF/cgi), then hit it with your browser as such to use the GET method:
myserver.mydomain:myport/cgi-bin/shiney_cpp_cgi?foo=bar
To send in a post request, use CURL as such:
curl --data 'foo=bar' myserver.mydomain:myport/cgi-bin/shiney_cpp_cgi
To serve C++ from tomcat, you can edit tomcat_root/conf/web.xml and change executable to an empty string. By default, tomcat will try to run your C++ as a perl script, which perl will (hopefully!) not be able to parse.
<servlet>
<servlet-name>cgi</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
...
<init-param>
<param-name>executable</param-name>
<param-value></param-value>
</init-param>
...
</servlet>