c++ Http request SSL error - c++

OK so I'm working on this c++ project where I read from a site, needs to be google, to get answers to display to the user and I am using the code from this link calling a website second solution the second solution as the base for my project. Requesting the xml from Google's search results will not work as the answers are not in the xml so I made a google custom search to output to a json using the google custom search api. My problem is when is requesting the url, link to my google custom search example here, of the json it gives an ssl error from my program. How do I solve this ssl problem? Seems I need to GET https not http or I need code to verify the ssl certificate. Not sure how to do this as I'm new to protocols and networking and such on c++.
Cannot use third part libraries.
And I apologize ahead of time for my problem and being a noob on this subject.

The given code uses plain sockets, no SSL is mentioned in the code, so it will not work with HTTPS or any other SSL based protocol. In order to connect to HTTPS web page, one has to use OpenSSL or any other library providing this layer for TCP sockets (unless you're gonna deal with encryption on your own which I doubt). Here is an example by using Boost library:
/*
Compile with
g++ -std=c++11 -lpthread -lboost_system -lssl -lcrypto -ogoog goog.cpp
*/
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
using std::cout;
using std::endl;
using std::vector;
using std::string;
using boost::asio::ip::tcp;
using boost::asio::ip::address;
using boost::asio::io_service;
using boost::asio::connect;
using boost::asio::buffer;
using boost::system::error_code;
using boost::system::system_error;
using boost::asio::ssl::context;
int main()
{
const char* PORT = "443";
const string HOST = "googleapis.com";
const string REQUEST = "GET https://www.googleapis.com/customsearch/v1?q=when%20is%20george%20washingtons%20birthdate&cx=014855184903748195002:umdboiolvoi&key=AIzaSyDxFosFrZlMpgdFeTsPWZfp925MbaBX49s HTTP/1.1\r\n\r\n";
try
{
io_service ios;
tcp::resolver resolver(ios);
tcp::resolver::query query(HOST, PORT);
tcp::resolver::iterator iterator = resolver.resolve(query);
context ctx(context::sslv23);
boost::asio::ssl::stream<tcp::socket> sock(ios, ctx);
sock.set_verify_mode(boost::asio::ssl::verify_none);
connect(sock.lowest_layer(), iterator);
sock.handshake(boost::asio::ssl::stream_base::client);
const int BUFLEN = 2048;
vector<char> buf(BUFLEN);
sock.write_some(boost::asio::buffer(REQUEST, REQUEST.size()));
while (true)
{
size_t len = sock.read_some(boost::asio::buffer(buf, BUFLEN));
cout << "main(): buf.data()=";
cout.write(buf.data(), len);
}
}
catch (system_error& exc)
{
cout << "main(): exc.what()=" << exc.what() << endl;
}
return EXIT_SUCCESS;
}
It connects to Google APIs (no certificate verification is performed) over SSL socket, sends GET request, fetches the page and prints to stdout. However, it is done in the infinite loop, so it's up to you to parse the JSON answer and determine when to exit the reading loop.

Related

I get error when i'm trying to send email using libquickmail

When I'm trying to send email using https://sourceforge.net/projects/libquickmail
I get error
Unable to resolve SMTP server host name.
#include "quickmail.h"
#pragma comment(lib, "libquickmaillight.dll.a")
int main()
{
quickmail_initialize();
quickmail mailobj = quickmail_create("LOGIN#yandex.ru", "libquickmail test e-mail");
quickmail_set_body(mailobj, "This is a test e-mail.\nThis mail was sent using libquickmail.");
const char *errmsg = quickmail_send(mailobj, "smtp.yandex.com", 465, "LOGIN#yandex.ru", "PASSWORD");
if (errmsg != NULL) {
fprintf(stderr, "Error sending e-mail: %s\n", errmsg);
}
quickmail_destroy(mailobj);
}
Compiler is MSVC14.
What did I do wrong?
Try to use quickmail_send_secure instead of quickmail_send
First of all, I see you are using port 465 wich probably means you want to use SSL encryption.
To use SSL encryption you need to use quickmail_send_secure(). As libquickmaillight doesn't support encryption you will need to link against libquickmail instead.
Your error Unable to resolve SMTP server host name indicates a DNS lookup error. Make sure ping smtp.yandex.com in a Command Prompt works on your system.
Also the difference between the full and the light library is that the full library uses libcurl. There is a chance not building against libquickmaillight may also fix your DNS issue as libcurl may be better at looking up DNS stuff (e.g. when you're using IPv6).
I had the same problem. visual Studio 2015 enterprise.
The solution for a program in WINDOWS was WSAStartup :
The WSAStartup function initiates use of the Winsock DLL by a process.
https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup
Before the use of libquickmail:
WSADATA data;
WSAStartup(MAKEWORD(2, 2), &data);
.....
and
WSACleanup();
at the end

Storing result in a file in C++

I'm writing a program to ping an IP.
I must ping a specific address for 1000s.
Now I want save the TTL to a file to draw it's histogram.
How I can do it? How can I just save the TTL to file?
Here's what I've tried:
#include "stdafx.h"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "conio.h"
#include <string>
#include <windows.h>
#include <iostream>
#include <fstream>
using namespace std;
static string host;
static string ping_again;
void ping()
{
cout << "Host: ";
host="www.yahoo.com";
system (("ping " + host).c_str);
}
int main()
{
ping();
return(0);
}
You've chosen to run the ping executable directly with system() and what you are missing is the capture of the output of the command, so you can parse the TTL.
Capturing stdout could have been done with popen instead of system, however, from your list of includes you seem to be on Windows, and that’s where it gets complicated. Check out this question: What is the equivalent to Posix popen() in the Win32 API?, and note that you can call popen if you application is a console application, otherwise the answers will refer you to an MSDN example which painfully details how you should invoke a process and redirect its input/output.
Once you redirect and capture the output you should parse the strings to extract the TTL. Note that the output of ping.exe may be different for different versions of Windows, and that you have little control what ping.exe you are actually invoking.
The alternative and the better approach is to use the ICMP APIs directly instead of invoking a ping executable on hosts where your application runs. Start with IcmpSendEcho and note that it provides the RTT in the reply structure.

How do I address a very specific web url?

I am writing code in C++ (using the Poco net libraries) to try to create a program for fun which will email me every few hours with updates to the TwitchPlaysPokemon stream (stupid, I know). Here is my code:
#include <iostream>
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketStream.h"
#include "Poco/StreamCopier.h"
using namespace std;
using namespace Poco::Net;
using namespace Poco;
int main(int argc, char *argv[])
{
string url = "www.reddit.com";
string fullPage;
SocketAddress sa(url, 80);
StreamSocket socket(sa);
SocketStream str(socket);
str << "GET / HTTP/1.1\r\n"
"Host: " << url << "\r\n"
"\r\n";
str.flush();
StreamCopier::copyStream(str, cout);
}
This exact code works perfectly fine. It grabs the raw html of www.reddit.com and prints it to the console. However, I'm trying to get information from one of two places for my program:
Either:
Here (url = "http://www.reddit.com/live/sw7bubeycai6hey4ciytwamw3a")
or
Here (url = "https://sites.google.com/site/twitchplayspokemonstatus/")
Either of these will be fine for my purposes. The problem is that when I plug these values in as the url in my program, the program has no idea what I'm talking about. Specifically, I get the following:
so clearly it cannot find the host. This is where I am stuck, as I know very little about internet protocol, hosts, etc. I tried to see if there was a specific IP address for this website (using cmd prompt ping), but it couldn't figure it out either ( it says "Ping request could not find the host www.reddit.com/live/sw7bubeycai6hey4ciytwamw3a"). The Poco library accepts written out urls (www.reddit.com), IPv4, and IPv6 addresses as the host input to SocketAddress (where I use the variable url, the other variable is the port which I've been told should basically always be 80?)
Question: I need help figuring out how I should be identifying the host to the Poco library. In other words, how do I properly refer to the host for either of those two sites listed above in such a way that my code can recognize it and grab the HTML from the page.
It sounds as though you may not understand HTTP correctly. Here's a brief refresher.
To get the contents of the URL http://www.example.com/path/page.html, the corresponding HTTP request would be sent to www.example.com on port 80, and would have the contents:
GET /path/page.html HTTP/1.1\r\n
Host: www.example.com\r\n
\r\n
The critical part that it doesn't look like you're doing correctly here is splitting the URL into the hostname and path components. Having a single url variable won't work (unless you manually split it on the first slash).

any good and simple RPC library for inter-process calls? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I need to send a (probably one) simple one-way command from client processes to server process with arguments of builtin C++ types (so serialization is pretty simple). C++, Windows XP+.
I'm looking for a library that doesn't require complicated configuration, provides simple interface, doesn't require hours to days of learning and doesn't have commercial usage restrictions. Simple solution for simple problem.
Boost.Interprocess is too low-level for this simple task because doesn't provide RPC interface. Sockets are probably an overkill too because I don't need to communicate between machines. The same about DCOM, CORBA et al. Named pipes? Never used them, any good library over WinAPI? OpenMPI?
I don't think sockets are really overkill. The alternatives all have their own problems and sockets are far better supported than named pipes, shared memory, etc., because almost everyone is using them. The speed of sockets on local system is probably not an issue.
There's Apache Thrift:
http://incubator.apache.org/thrift/
There are a few RPC implementations wrapped around Google's protobuf library as the marshaling mechanism:
https://github.com/google/protobuf/blob/master/docs/third_party.md#rpc-implementations
There's XML-RPC:
http://xmlrpc-c.sourceforge.net/
If your messages are really simple, I might consider using UDP packets, then there are no connections to manage.
You might like ZeroMQ for something like this. Perhaps not as much a complete RPC, as a raw byte messaging framework you could use to make an RPC. It's simple, lightweight and with an impressive performance. You can easilly implement an RPC on top of it. Here's an example server straight from the manual:
//
// Hello World server in C++
// Binds REP socket to tcp://*:5555
// Expects "Hello" from client, replies with "World"
//
#include <zmq.hpp>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main () {
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:5555");
while (true) {
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
printf ("Received Hello");
// Do some 'work'
sleep (1);
// Send reply back to client
zmq::message_t reply (5);
memcpy ((void *) reply.data (), "World", 5);
socket.send (reply);
}
return 0;
}
This example uses tcp://*.5555, but uses more efficient IPC techniques if you use:
socket.bind("ipc://route.to.ipc");
or even faster inter thread protocol:
socket.bind("inproc://path.for.client.to.connect");
If you only need to support Windows I'd use the Windows built-in RPC, I've written two introductory articles about this:
http://www.codeproject.com/KB/IP/rpcintro1.aspx
http://www.codeproject.com/KB/IP/rpcintro2.aspx
You could use the ncalrpc protocol if you only need local inter-process communication.
Boost.MPI. Simple, fast, scalable.
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
#include <sstream>
namespace mpi = boost::mpi;
int main(int argc, char* argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
std::stringstream ss;
ss << "Hello, I am process " << world.rank() << " of " << world.size() << ".";
world.send(1, 0, ss.str());
}
If you are working on windows only, and really need a C++ interface, use COM/DCOM. It is based on RPC (in turn based on DCE RPC).
It is extremely simple to use -- provided you take the time to learn the basics.
ATL: http://msdn.microsoft.com/en-us/library/3ax346b7(VS.71).aspx
Interface Definition Language: http://msdn.microsoft.com/en-us/library/aa367091(VS.85).aspx
You probably don't even need a library. Windows has an IPC mechanism built deeply into its core APIs (windows.h). You can basically post a windows message into the message-queue of a different processes main window. Windows even defines a standard message to do just that: WM_COPYDATA.
MSDN docu on WM_COPYDATA
MSDN demo code
More demo code the following StackOverflow response
The sending process basically does:
FindWindow
SendMessage
The receiving process (window):
On Vista and later has to modify its message filter using ChangeWindowsMessageEx
Override its WindowProc
In order to handle the incoming WM_COPYDATA
I know that we are far away from easy to use. But of course you can stick to CORBA. E.g. ACE/TAO
I'm told RPC with Raknet is nice and simple.
Also, you might look at msgpack-rpc
Update
While Thrift/Protobuf are more flexible, I think, but there are require to write some code in specific format. For example, Protobuf needs some .proto file, which can be compile with specific compiler from package, that genegate some classes. In some cases it might be more difficult that other parts of code.
msgpack-rpc is much simpler. It doesn't require write some extra code. Here is example:
#include <iostream>
#include <msgpack/rpc/server.h>
#include <msgpack/rpc/client.h>
class Server: public msgpack::rpc::dispatcher {
public:
typedef msgpack::rpc::request request_;
Server() {};
virtual ~Server() {};
void dispatch(request_ req)
try {
std::string method;
req.method().convert(&method);
if (method == "id") {
id(req);
} else if (method == "name") {
name(req);
} else if (method == "err") {
msgpack::type::tuple<> params;
req.params().convert(&params);
err(req);
} else {
req.error(msgpack::rpc::NO_METHOD_ERROR);
}
}
catch (msgpack::type_error& e) {
req.error(msgpack::rpc::ARGUMENT_ERROR);
return;
}
catch (std::exception& e) {
req.error(std::string(e.what()));
return;
}
void id(request_ req) {
req.result(1);
}
void name(request_ req) {
req.result(std::string("name"));
}
void err(request_ req) {
req.error(std::string("always fail"));
}
};
int main() {
// { run RPC server
msgpack::rpc::server server;
std::auto_ptr<msgpack::rpc::dispatcher> dispatcher(new Server);
server.serve(dispatcher.get());
server.listen("0.0.0.0", 18811);
server.start(1);
// }
msgpack::rpc::client c("127.0.0.1", 18811);
int64_t id = c.call("id").get<int64_t>();
std::string name = c.call("name").get<std::string>();
std::cout << "ID: " << id << std::endl;
std::cout << "name: " << name << std::endl;
return 0;
}
Output
ID: 1
name: name
More complicated examples you can find here https://github.com/msgpack/msgpack-rpc/tree/master/cpp/test
I'm using XmlRpc C++ for Windows found here
Really easy to use :) But the only side effect that this is only a client!
There's also Microsoft Messaging Queueing, which is fairly straightforward to use when all processes are on the local machine.
The simplest solution for interprocess-communication is to use the filesystem. Requests and responses can be written as temp files. You can work out a naming convention for request and response files.
This will not give you the best performance, but maybe it will be good enough.

Read HTML source to string

I hope you don't frown on me too much, but this should be answerable by someone fairly easily. I want to read a file on a website into a string, so I can extract information from it.
I just want a simple way to get the HTML source read into a string. After looking around for hours I see all these libraries and curl and stuff. All I need is the raw HTML data. I don't even need a definite answer. Just something that will help me refine my search.
Just to be clear I want the raw code in a string I can manipulate, don't need any parsing etc.
You need an HTTP Client library, one of many is libcurl. You would then issue a GET request to a URL and read the response back how ever your chosen library provides it.
Here is an example to get you started, it is C so I am sure you can work it out.
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
But you tagged this C++ so if you want a C++ wrapper for libcurl then use curlpp
#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
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;
}
HTTP is built on top of TCP. If you know socket programming, you can write a simple networking application that opens a socket to the desired server and issues an HTTP GET command. Whatever the server responds with, you'll have to remove the HTTP headers that precede the actual document you want.
If that sounds complicated, then just stick with libcurl.
if it is a hack - then just grab the source from show source, and save as txt. then you can open it with a normal file io stream.
all thos pesky libraries are a hint that it is a common and non-trivial excercise to do it right... :)
If all you want to do is grab the entire HTML code without any kind of parsing and extern libraries, my sugestion would be copying the code with a IO stream into a string.
It is the simplest way that I have in mind but be aware that it isn't the most efficient way to do it.