C++ Http Request with POCO - c++

I'm wondering how I can do a request to a URL (e.g. download a picture and save it) with POCO in C++?
I got this little code so far
#include <iostream>
#include <string>
#include "multiplication.h"
#include <vector>
#include <HTTPRequest.h>
using std::cout;
using std::cin;
using std::getline;
using namespace Poco;
using namespace Net;
int main() {
HTTPRequest *test = new HTTPRequest("HTTP_GET", "http://www.example.com", "HTTP/1.1");
}

Normally POCO has a great advantage to be very simple even when you know nothing about it and you do not need middle/advance C++ knowledge like you need for boost/asio ( e.g what means enable_share_from_this ... )
Under the poco "installation directory" you find the sample directory, (in my case under poco\poco-1.4.6p4\Net\samples\httpget\src ).
On-line help browsing is also easy and fast (for example browsing classes).
If your understanding of C++ in not enough at the present time go to the university library and borrow Scott Meyers books (Effective C++ and after More effective C++ )
So we adapt the sample code httpget.cpp to the minimal required.
Inside the main:
URI uri("http://pocoproject.org/images/front_banner.jpg");
std::string path(uri.getPathAndQuery());
if (path.empty()) path = "/";
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
HTTPResponse response;
if (!doRequest(session, request, response))
{
std::cerr << "Invalid username or password" << std::endl;
return 1;
}
and the function almost untouched:
bool doRequest(Poco::Net::HTTPClientSession& session,
Poco::Net::HTTPRequest& request,
Poco::Net::HTTPResponse& response)
{
session.sendRequest(request);
std::istream& rs = session.receiveResponse(response);
std::cout << response.getStatus() << " " << response.getReason() << std::endl;
if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
{
std::ofstream ofs("Poco_banner.jpg",std::fstream::binary);
StreamCopier::copyStream(rs, ofs);
return true;
}
else
{
//it went wrong ?
return false;
}
}
I let you arrange things for you and see where the image lands on your disk.
Hope it will help

Related

how to make Google search using c++ program

I am wondering and almost searched everywhere on the web but couldn't find anything helpful. I am quite a beginner with c++. Is there any possible way to make a Web search when I type a word in console on program runtime, it should go to google.com and fetch the meaning of that word to my .txt file or directly on my console? Basically, I am trying to implement a dictionary (offline+Online) using c++ and linked lists/trees.
Any sort of help will be much appreciated.
There is a couple of steps to this that you may need to do before you even start writing the C++ code.
Note: C++ is probably not the easiest language to do this in.
You will need a google account.
Go to the website and sign up (free)
You will need to get an API Key
Go to the website and generate (free)
You will need to know the REST command to generate output.
Here the easiest thing to do is to use CURL to test your REST query (or use a tool like PostMan). Though their website provides a simple starting point to test parameters.
Once you have the rest command working on the command line. Convert this to C code using the libcurl API.
You will need to parse the returned value.
The returned value is JSON you will need to either parse this manually or use an existing library. There are several out there. I hear jsoncpp is good I prefer ThorsSerializer but I wrote that so I am biased.
Making a dictionary (non commercial).
Its probably simpler to use the MERRIAM-WEBSTER'S API rather than googles.
Step 1: Register to get an API Key
https://dictionaryapi.com/register/index
Step 2: Get The API Key
Once you have filled out the form.
And confirmed your e-mail
And Logged into dictionaryapi.com
Go to your keys page
Step 3: Verify you can get information from the command line
Documentation here
Note: My key is not going to work for you (I deleted it). You will have to create and use your own.
curl https://www.dictionaryapi.com/api/v3/references/collegiate/json/voluminous?key=568e93fa-c06f-4f96-bf12-948cf301a03f
Step 4: Convert the command line into C code.
#include <string>
#include <iostream>
#include <curl/curl.h>
extern "C" size_t write_callback(char *ptr, size_t size, size_t nmemb, void *dataFromServerVoid)
{
std::string& dataFromServer = *(reinterpret_cast<std::string*>(dataFromServerVoid));
dataFromServer.append(ptr, size * nmemb);
return size * nmemb;
}
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cerr << "Fail: Read Instructions\n";
return -1;
}
std::cout << "Dictionary:\n"
<< " Getting: " << argv[1] << "\n";
CURL* curl = curl_easy_init();
if (curl)
{
static const std::string apiKey = "?key=568e93fa-c06f-4f96-bf12-948cf301a03f";
static const std::string urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const std::string url = urlBase + argv[1] + apiKey;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// The default action is to print any data returned
// to the standard output. But we are going to need to
// processes that data so adding some functions
// and data to capture the output.
std::string dataFromServer;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dataFromServer);
// Get the data from the server.
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
// If the call worked we can print out
// what we retrieved.
if (res == CURLE_OK) {
std::cout << " Got: >" << dataFromServer << "<\n";
}
}
}
Step 5: Build and verify it works.
> g++ -std=c++17 dict.cpp -lcurl
> ./a.out bootstrap
We get:
Dictionary:
Getting: bootstrap
Got: >[{"meta":{"id":"bootstrap:1","uuid":"9c960ec2-a3ce-4f09-a7ba-a4972036314a","sort":"020350800","src":"collegiate","section":"alpha","stems":["bootstrap","bootstraps"],"offensive":false},"hom":1,"hwi":{"hw":"boot*strap","prs":[{"mw":"\u02c8b\u00fct-\u02ccstrap","sound":{"audio":"bootst01","ref":"c","stat":"1"}}]},"fl":"noun","def":[{"sseq":[[["sense",{"sn":"1","dt":[["text","{bc}a looped strap sewed at the side or the rear top of a boot to help in pulling it on"]]}]],[["sense",{"sn":"2","ins":[{"if":"boot*straps","spl":"plural"}],"dt":[["text","{bc}unaided efforts "],["uns",[[["text","often used in the phrase {it}by one\u0027s own bootstraps{\/it}"]]]]]}]]]}],"date":"1875{ds||1||}","shortdef":["a looped strap sewed at the side or the rear top of a boot to help in pulling it on","unaided efforts \u2014often used in the phrase by one\u0027s own bootstraps"]},{"meta":{"id":"bootstrap:2","uuid":"59331df1-c1fd-44ff-bd8d-73d471ad6819","sort":"020350900","src":"collegiate","section":"alpha","stems":["bootstrap"],"offensive":false},"hom":2,"hwi":{"hw":"bootstrap"},"fl":"adjective","def":[{"sseq":[[["sense",{"sn":"1","dt":[["text","{bc}designed to function independently of outside direction {bc}capable of using one internal function or process to control another "],["vis",[{"t":"a {wi}bootstrap{\/wi} operation to load a computer"}]]]}]],[["sense",{"sn":"2","dt":[["text","{bc}carried out with minimum resources or advantages "],["vis",[{"t":"{wi}bootstrap{\/wi} efforts"}]]]}]]]}],"date":"1926{ds||1||}","shortdef":["designed to function independently of outside direction : capable of using one internal function or process to control another","carried out with minimum resources or advantages"]},{"meta":{"id":"bootstrap:3","uuid":"257edd7e-c31a-453a-a15b-e1d022c70d96","sort":"020351000","src":"collegiate","section":"alpha","stems":["bootstrap","bootstrapped","bootstrapper","bootstrappers","bootstrapping","bootstraps"],"offensive":false},"hom":3,"hwi":{"hw":"bootstrap"},"fl":"verb","ins":[{"if":"boot*strapped"},{"if":"boot*strap*ping"}],"def":[{"vd":"transitive verb","sseq":[[["sense",{"dt":[["text","{bc}to promote or develop by initiative and effort with little or no assistance "],["vis",[{"t":"{it}bootstrapped{\/it} herself to the top"},{"t":"\u2026 turns out to be pretty talented at identifying and {wi}bootstrapping{\/wi} promising creative endeavors.","aq":{"auth":"Harry McCracken"}}]]]}]]]}],"uros":[{"ure":"boot*strap*per","fl":"noun"}],"date":"1951","shortdef":["to promote or develop by initiative and effort with little or no assistance"]}]<
Step 6: Extract the data from the JSON
I am going to use ThorsSerializer to get the data. This allows de-serialization of JSON directly into C++ objects without having to parse and interpret any intermediate objects. This makes it really usefull for stable web interfaces (like most REST interfaces).
Step 6a: Install ThorsSerializer
> brew install thors-serializer
A useful tip here. To visualize and quickly see the JSON there is a great command line tool jq. if you stream JSON to this the default action is simply to prity print the JSON (though it has a lot more power)
> brew install jq
> echo "<JSON TEXT>" | jq
Step 6b: Build Definition of what you want:
Looking at the definition of JSON we only need one bit of data "shortdef" which is an array of strings inside a definition object.
// So simply declare an object like the JSON declaraition.
// You can ignore any parts of the JSON you don't want.
struct Definition
{
std::vector<std::string> shortdef;
};
// Now tell the ThorsSerializer the bits it needs to understand.
// The library already knows how to handle all the standard types.
// So no extra declarations needed for std::vector.
ThorsAnvil_MakeTrait(Definition, shortdef);
Step 6C: Write code to extract data from JSON.
using ThorsAnvil::Serialize::jsonImporter;
std::stringstream dataFromServerStream(dataFromServer);
std::vector<Definition> definition;
// ThorsSerializer works for any type of stream.
// Files are supported natively and its not hard
// to wrap sockets as a stream if you want to.
// In this case I have kept it simple.
dataFromServerStream >> jsonImporter(definition);
Step 6c: Put it all together:
#include <vector>
#include <string>
#include <iostream>
#include <curl/curl.h>
#include "ThorSerialize/Traits.h"
#include "ThorSerialize/JsonThor.h"
extern "C" size_t write_callback(char *ptr, size_t size, size_t nmemb, void *dataFromServerVoid)
{
std::string& dataFromServer = *(reinterpret_cast<std::string*>(dataFromServerVoid));
dataFromServer.append(ptr, size * nmemb);
return size * nmemb;
}
struct Definition
{
std::vector<std::string> shortdef;
};
ThorsAnvil_MakeTrait(Definition, shortdef);
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cerr << "Fail: Read Instructions\n";
return -1;
}
std::cout << "Dictionary:\n"
<< "Getting: " << argv[1] << "\n";
CURL* curl = curl_easy_init();
if (curl)
{
static const std::string apiKey = "?key=568e93fa-c06f-4f96-bf12-948cf301a03f";
static const std::string urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const std::string url = urlBase + argv[1] + apiKey;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
std::string dataFromServer;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dataFromServer);
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res == CURLE_OK) {
using ThorsAnvil::Serialize::jsonImporter;
std::stringstream dataFromServerStream(dataFromServer);
std::vector<Definition> definition;
dataFromServerStream >> jsonImporter(std::move(definition));
for(auto def: definition[0].shortdef) {
std::cout << " " << def << "\n";
}
}
}
}
Step 7: Build
g++ -std=c++17 main2.cpp -lcurl -lThorSerialize17 -lThorsLogging17
> ./a.out bootstrap
We get:
Dictionary:
Getting: bootstrap
a looped strap sewed at the side or the rear top of a boot to help in pulling it on
unaided efforts —often used in the phrase by one's own bootstraps
Just as a comparison.
The same code in Javascript. Now my javascript is not good. But this code is still tighter and more readable. So this shows that C++ is not the best language to do this as a beginner.
const fetch = require('node-fetch');
const apiKey = "?key=568e93fa-c06f-4f96-bf12-948cf301a03f";
const urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const url = urlBase + process.argv[2] + apiKey;
fetch(url)
.then(res => res.json())
.then((definition) => {
for(var item in definition[0].shortdef) {
console.log(definition[0].shortdef[item]);
}
})
.catch(err => { throw err });
To run this:
> node dict.js bootstrap
But saying that. If you find an appropriate library this code can be just as concise as the Javascript. But you need an appropriate library (which may be difficult and hard to find/build and install). All of which are made easy with javascript.
Example of simple version:
#include <vector>
#include <string>
#include <iostream>
#include "ThorSerialize/Traits.h"
#include "ThorSerialize/JsonThor.h"
#include "ThorSocketStream/ThorsSimpleStream.h"
struct Definition
{
std::vector<std::string> shortdef;
};
ThorsAnvil_MakeTrait(Definition, date, shortdef);
int main(int argc, char* argv[])
{
using ThorsAnvil::Stream::IThorSimpleStream;
using ThorsAnvil::Serialize::jsonImporter;
static const std::string apiKey = "?key=key=568e93fa-c06f-4f96-bf12-948cf301a03f";
static const std::string urlBase = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/";
const std::string url = urlBase + argv[1] + apiKey;
IThorSimpleStream stream(url);
std::vector<Definition> dataFromServer;
stream >> jsonImporter(dataFromServer)
for(auto const& def: dataFromServer[0].shortdef) {
std::cout << " " << data << "\n";
}
}
But getting the SimpleStream library may take some work to build.

Integration between Node.js and C++

I have a Node.js application that I want to be able to send a JSON-object into a C++ application.
The C++ application will use the Poco-libraries (pocoproject.org).
I want the interaction to be lighting fast, so preferably no files or network-sockets.
I have been looking into these areas:
Pipes
Shared memory
unixSockets
What should I focus on, and can someone point my direction to docs. and samples?
First of all, some more data is needed to give good advice.
In general shared memory is the fastest, since there's no transfer required, but it's also the hardest to keep fine. I'm not sure you'd be able to do that with Node though.
If this program is just running for this one task and closing it might be worth just sending your JSON to the CPP program as a startup param
myCPPProgram.exe "JsonDataHere"
The simplest thing with decent performance should be a socket connection using Unix domain sockets with some low-overhead data frame format. E.g., two-byte length followed by UTF-8 encoded JSON. On the C++ side this should be easy to implement using the Poco::Net::TCPServer framework. Depending on where your application will go in the future you may run into limits of this format, but if it's basically just streaming JSON objects it should be fine.
To make it even simpler, you can use a WebSocket, which will take care of the framing for you, at the cost of the overhead for the initial connection setup (HTTP upgrade request). May even be possible to run the WebSocket protocol over a Unix domain socket.
However, the performance difference between a (localhost only) TCP socket and a Unix domain socket may not even be significant, given all the JavaScript/node.js overhead. Also, if performance is really a concern, JSON may not even be the right serialization format to begin with.
Anyway, without more detailed information (size of JSON data, message frequency) it's hard to give a definite recommendation.
I created a TCPServer, which seems to work. However if I close the server and start it again I get this error:
Net Exception: Address already in use: /tmp/app.SocketTest
Is it not possible to re-attach to the socket if it exists?
Here is the code for the TCPServer:
#include "Poco/Util/ServerApplication.h"
#include "Poco/Net/TCPServer.h"
#include "Poco/Net/TCPServerConnection.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/File.h"
#include <fstream>
#include <iostream>
using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::Net::TCPServer;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::SocketAddress;
using Poco::Util::ServerApplication;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
class UnixSocketServerConnection: public TCPServerConnection
/// This class handles all client connections.
{
public:
UnixSocketServerConnection(const StreamSocket& s):
TCPServerConnection(s)
{
}
void run()
{
try
{
/*char buffer[1024];
int n = 1;
while (n > 0)
{
n = socket().receiveBytes(buffer, sizeof(buffer));
EchoBack(buffer);
}*/
std::string message;
char buffer[1024];
int n = 1;
while (n > 0)
{
n = socket().receiveBytes(buffer, sizeof(buffer));
buffer[n] = '\0';
message += buffer;
if(sizeof(buffer) > n && message != "")
{
EchoBack(message);
message = "";
}
}
}
catch (Poco::Exception& exc)
{
std::cerr << "Error: " << exc.displayText() << std::endl;
}
std::cout << "Disconnected." << std::endl;
}
private:
inline void EchoBack(std::string message)
{
std::cout << "Message: " << message << std::endl;
socket().sendBytes(message.data(), message.length());
}
};
class UnixSocketServerConnectionFactory: public TCPServerConnectionFactory
/// A factory
{
public:
UnixSocketServerConnectionFactory()
{
}
TCPServerConnection* createConnection(const StreamSocket& socket)
{
std::cout << "Got new connection." << std::endl;
return new UnixSocketServerConnection(socket);
}
private:
};
class UnixSocketServer: public Poco::Util::ServerApplication
/// The main application class.
{
public:
UnixSocketServer(): _helpRequested(false)
{
}
~UnixSocketServer()
{
}
protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
ServerApplication::initialize(self);
}
void uninitialize()
{
ServerApplication::uninitialize();
}
void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);
options.addOption(
Option("help", "h", "display help information on command line arguments")
.required(false)
.repeatable(false));
}
void handleOption(const std::string& name, const std::string& value)
{
ServerApplication::handleOption(name, value);
if (name == "help")
_helpRequested = true;
}
void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("A server application to test unix domain sockets.");
helpFormatter.format(std::cout);
}
int main(const std::vector<std::string>& args)
{
if (_helpRequested)
{
displayHelp();
}
else
{
// set-up unix domain socket
Poco::File socketFile("/tmp/app.SocketTest");
SocketAddress unixSocket(SocketAddress::UNIX_LOCAL, socketFile.path());
// set-up a server socket
ServerSocket svs(unixSocket);
// set-up a TCPServer instance
TCPServer srv(new UnixSocketServerConnectionFactory, svs);
// start the TCPServer
srv.start();
// wait for CTRL-C or kill
waitForTerminationRequest();
// Stop the TCPServer
srv.stop();
}
return Application::EXIT_OK;
}
private:
bool _helpRequested;
};
int main(int argc, char **argv) {
UnixSocketServer app;
return app.run(argc, argv);
}
The solution I have gone for, is to use unix domain sockets. The solution will run on a Raspbian-setup and the socket-file is placed in /dev/shm, which is mounted into RAM.
On the C++ side, I use the Poco::Net::TCPServer framework as described elsewhere in this post.
On the Node.js side, I use the node-ipc module (http://riaevangelist.github.io/node-ipc/).

How to transfer a C++ object to a web service using POCO library

I have an image processing application that uses Qt and openCV.
for each frame, I should send the captured cv::Mat image object to the server to process it and get the results.
I should use the REST architecture for its low playload.
What is the tool that I should use to send cv::Mat to the server.
I am using POCO for portability.
I seek for the lightest solution to do that, I need a minimum speed of 10 frames processed by the server in a second.
I mean, is there a method to pass the C++ Object to the server without an explicit serialization?
EDIT
With the POCO library, you can take a look in this answer: HttpRequest PUT content in poco library. He is sending a file on a ifstream.
In this answer you can check how to convert a cv::Mat into a istream: OpenCV cv::Mat to std::ifstream for base64 encoding.
And finally, Thanks to polymorphism, the istream is implicity converted to a ifstream.
You can use the C++ Rest SDK. A code example of the PUT command.
Source of code
Library Github where you can find the full documentation.
#include <http_client.h>
#include <filestream.h>
#include <iostream>
#include <sstream>
using namespace web::http;
using namespace web::http::client;
// Upload a file to an HTTP server.
pplx::task<void> UploadFileToHttpServerAsync()
{
using concurrency::streams::file_stream;
using concurrency::streams::basic_istream;
// To run this example, you must have a file named myfile.txt in the current folder.
// Alternatively, you can use the following code to create a stream from a text string.
// std::string s("abcdefg");
// auto ss = concurrency::streams::stringstream::open_istream(s);
// Open stream to file.
return file_stream<unsigned char>::open_istream(L"myfile.txt").then([](pplx::task<basic_istream<unsigned char>> previousTask)
{
try
{
auto fileStream = previousTask.get();
// Make HTTP request with the file stream as the body.
http_client client(L"http://www.fourthcoffee.com");
return client.request(methods::PUT, L"myfile", fileStream).then([fileStream](pplx::task<http_response> previousTask)
{
fileStream.close();
std::wostringstream ss;
try
{
auto response = previousTask.get();
ss << L"Server returned returned status code " << response.status_code() << L"." << std::endl;
}
catch (const http_exception& e)
{
ss << e.what() << std::endl;
}
std::wcout << ss.str();
});
}
catch (const std::system_error& e)
{
std::wostringstream ss;
ss << e.what() << std::endl;
std::wcout << ss.str();
// Return an empty task.
return pplx::task_from_result();
}
});
/* Sample output:
The request must be resent
*/
}

Segmentation fault in gSoap client

I'm using gSoap for fetch the server's TimeZone from exchange server, My client code is:
#include "soapExchangeServiceBindingProxy.h"
#include "ExchangeServiceBinding.nsmap"
int main()
{
ExchangeServiceBindingProxy service;
service.soap_endpoint = "https://outlook.office365.com/ews/exchange.asmx";
ns1__GetServerTimeZonesType request;
__ns1__GetServerTimeZonesResponse response;
const std::string s("Eastern Standard Time");
request.Ids = (ns2__NonEmptyArrayOfTimeZoneIdType *)&s;
if(service.GetServerTimeZones(&request , response) == SOAP_OK){
std::cout << "Success Response: "<< response.ns1__GetServerTimeZonesResponse << std::endl;
}
else
service.soap_stream_fault(std::cerr);
service.destroy(); // delete data and release memory
return 0;
}
This code compiled successfully but when i tried to run it, it give Segmentation fault, I'm newbie in C++ and gSoap also so i don't know exactly what am i doing wrong here?
If you need more code for this, i'll surly provide it to you, please let me know for this. Any help appreciated. thank you.

Remote control of C++ program in Ubuntu 12.04 via HTTPS

I have an emulator program written in C++ running on Ubuntu 12.04. There are some settings and options needed for running the program, which are given by the main's arguments. I need to query and control these options via HTTPS from a remote machine/mobile device. I was wondering if someone can help me with that.
There should probably be some libraries for the ease, for example libcurl. I'm not sure how suitable it is for my case, but here is any example of connection setup in libcurl. It's not a must to use any libraries though; just the most efficient/simplest way.
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
using namespace curlpp::options;
int main(int, char **)
{
try
{
// That's all that is needed to do cleanup of used resources (RAII style).
curlpp::Cleanup myCleanup;
// Our request to be sent.
curlpp::Easy myRequest;
// Set the URL.
myRequest.setOpt<Url>("http://example.com");
// Send request and get a result.
// By default the result goes to standard output.
myRequest.perform();
}
catch (curlpp::RuntimeError &e)
{
std::cout << e.what() << std::endl;
}
catch (curlpp::LogicError &e)
{
std::cout << e.what() << std::endl;
}
return 0;
}