Download a URL in C++ - c++

I want to be able to download a URL in C++. Something as simple as:
std::string s;
s=download("http://www.example.com/myfile.html");
Ideally, this would include URLs like:
ftp://example.com/myfile.dat
file:///usr/home/myfile.dat
https://example.com/myfile.html
I was using asio in Boost, but it didn't really seem to have the code for handling protocols like ftp and https. Now I discovered QT has more what I need (http://doc.trolltech.com/2.3/network.html).
It's tempting to make the switch to Qt, but it seems a bit heavy and intersects a lot of Boost functionality. Is it worth learning yet another API (Qt) or can Boost do more than I think?

Not a direct answer, but you might like to consider libCURL, which is almost exactly what you describe.
There are sample applications here, and in particular this demonstrates how simple usage can be.

I wouldn't go to Qt just for the networking stuff, since it's really not all that spectacular; there are a lot of missing pieces. I'd only switch if you need the GUI stuff, for which it is top notch.
libCURL is pretty simple to use and more robust than the Qt stuff.

You can use URLDownloadToFile.
#include <Urlmon.h>
HANDLE hr;
hr=URLDownloadToFile(NULL, L"http://www.example.com/myfile.html",L"mylocalfile.html",BINDF_GETNEWESTVERSION,NULL);
According to MSDN, BINDF_GETNEWESTVERSION - is a "Value that indicates that the bind operation retrieves the newest version of the data or object available. In URL monikers, this flag maps to the WinInet flag, INTERNET_FLAG_RELOAD, which forces a download of the requested resource".

The Poco Project has classes for cross-platform HTTP and FTP (and a lot of other stuff). There is overlap with boost. I recently found this, but have not used it.

You can use the URLDownloadToFile or URLOpenBlockingStream, although cURL, libcurl are the proper tools for that kind of jobs.

I got it working without either libcurl nor WinSock: https://stackoverflow.com/a/51959694/1599699
Special thanks to Nick Dandoulakis for suggesting URLOpenBlockingStream! I like it.

Related

Cross platform grab web source C++

I'm looking to grab the source of a webpage and add it to a string, all the guides I see though use curl or winsockets and I need this to be cross-compatible and use C++ only (No external libraries)
Could anyone point me in the right direction please?
Thanks.
You may want to check boost::asio. It offers cross-platform networking, which will cover TCP/IP. boost is not a standard library, but it's de facto second standard C++ library. BTW, a lot of boost stuff ends up in std.
Next thing is HTTP client. Unfortunately, standard C++ library doesn't have HTTP client, but a basic, partial implementation of the protocol is simple enough that you can try to roll your own - you'll probably need only GET request. Try sending GET request over telnet, by typing it manually - you'll see it's very simple.
If SSL/TLS or a complete HTTP support is required, you may be forced to use a 3rd party library, because implementing them is a more than a challenging task.
For C++ only without an external library? No such thing.
Qt is fairly cross platform, supporting Windows, Linux, MacOS, Android, iOS and a bunch of other more exotic platforms, plus embedded.
Qt 4 had a dedicated QHttp class, but it got deprecated and removed in Qt 5. With Qt 5 you will have to use the QNetworkAccessManager class:
A simple download off the network could be accomplished with:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
True, Qt 5 is a big framework, hardly justified for the purpose of that single task, but on the other hand, it is very powerful, very portable application development framework, so odds are it may come in handy in other aspects as well.

How do you copy/paste from the clipboard in C++?

I'm still a C++ newbie who has only recently learned some file manipulation. I looked it up online and the codes given are way beyond my current skill. Is there a simple way to do this, or are there any good tutorials that can explain this from the very basics?
In windows look at the following API:
OpenClipBoard
EmptyClipboard
SetClipboardData
CloseClipboard
GetClipboardData
An extensive discussion can be found here.
Obviously this topic is strongly operating system related. And if you are using some framework (ie MFC/ATL) you generally find some helper infrastructure. This reply refer to the lowest API level in WIndows. If you are planning to use MFC have a look here, if you prefer ATL look here.
There is no cross-platform way to do this in C++
Now that we have that out of the way, Felice Pollano's answer provides the Windows API so you can manipulate the clipboard in Windows.
Apple provides an example application named ClipboardViewer and an entire reference to the NSPasteBoard and the functionality it provides.
As for Linux, it depends on what windowing manager you are running.
There is a cross platform way to do this in C++, provided you are willing to use the Qt Library.
A solution for this is provided here:
https://stackoverflow.com/a/40437290/2158002
You can use ClipboardXX library for copy and pasting simple texts.
Just download clipboardXX.hpp from github and copy it to your project path. Then follow its examples:
#include "clipboard.hpp"
#include <string>
int main() {
clipboardxx::clipboard clipboard;
// copy
clipboard << "text you wanna copy";
// paste
std::string paste_text;
clipboard >> paste_text;
}
If you are looking for a simle way to do this : simulate the keyboard combination ctrl + v and you are done with it. On all platforms.

How to send an IM in C or C++ on Windows

Specifically I am talking about using AIM and sending instant messages to an existing AIM screename. How would I accomplish this? I am trying to do it the simplest way possible -efficiency is not that important.
I thought maybe all I would have to do is open a socket connections some how but I am probably wrong.
I would use libpurple. It's a multi-platform C library that supports many IM services, including AIM.
Check out the source for GAIM/Pidgin, which runs on a variety of platforms including windows. It uses a modified version of libfaim.

Logging facilities and Qt

What logging facilities do you use whit Qt ?
Do you choose qDebug(), qWarning(), qCritical(), qFatal() methods, or maybe something like Log4cpp (Log4cplus etc.), or maybe some custom-maked code ?
If you are just working in a single thread, qDebug and such work pretty well, or you can modify them somewhat by installing your own handler with qInstallMessageHandler in QT 5.0+, or qInstallMsgHandler in old versions.
Note: Older versions of qDebug() etc., where you used qInstallMsgHandler (now deprecated, e.g. http://doc.qt.io/archives/4.6/qtglobal.html#qDebug) were not thread-safe. If you use threads, they would crash/break badly. Internally it was using QTextStream, which was reentrant, but not thread-safe.
Since Qt 5.2 supports categorized logging: http://qt-project.org/doc/qt-5/qloggingcategory.html . This allows you to split up your logging messages into a (hierarchy of) categories, and fine tune which is logged, and what not.
Existing C++ logging libraries are too heavy for my tastes, so I have created a custom front-end based on ideas from Logging in C++ for the Qt qInstallMsgHandlerq back-end. It's cross-platform and thread-safe. Someday I'll clean up the code and release it to the world :)
An interesting alternative for Qt is QxtLogger.
Log4Qt is a port of famous log4j to the Qt world.
QDebug is the best way to go, as it presents out-of-the-box integration with the rest of the framework, doesn't make you dependent on 3rd party code and covers pretty all of the logging needs.
I'm not using Qt, but for logging I'm using a modified version of Dr'Dobb's Logging in C++. The original code can be found here.
My modifications are specific to the Microsoft Windows platform (fopen doesn't allow file read sharing) and can be found here.
Regarding the answer saying "Unfortunately qDebug() etc. are not thread-safe. If you use threads, they will crash/break badly. Internally it uses QTextStream, which is reentrant, but not thread-safe."
I seriously doubt that, qDebug is designed to be used concurrently. File a bug if that isn't true.
Depends on how you want to use that log data.
If it is used for debugging at runtime, qWarning() would do just fine.
If you need to debug retrospective (usually server side code), plain old text files are the best. It is best to organize these log files by day log is written.
You can have a look at: https://github.com/netresultsit/uniqlogger
LGPL
thread-safe
multiple backends: file, colored console, network, rsyslog
file rotation by size and number of files
support compression of previous files
etc.

Help streaming over http in C++

I'm looking to use a web service that offers a streaming api. This api can typically be used by the java method java.net.URL.openStream();
Problem is I am trying to design my program in C++ and have no idea what libraries (I've heard the cUrl library is very good at this sort of thing) to use, or how to use them to do what I want.
The idea is that after opening the file as a stream I can access continually updating data in realtime.
Any help would be much appreciated.
Boost.Asio socket iostreams seem to be what you're after. Your code will look like this:
ip::tcp::iostream stream("www.someserver.com", "http");
if (!stream)
{
// Can't connect.
}
// Use stream as a regular C++ input stream:
std::string text;
std::getline(stream, text);
If you're new to C++ and have no experience with iostreams then this page is an excellent source of information. In particular, check the docs of the istream class to see what kind of operations your Boost.ASIO stream will support. You'll find that they're not so different from those in the Java IO API.
EDIT: Eric is right, you'll have to send some requests to the server (using the same stream) so it's probably less similar to Java's openStream than I thought. The following example shows how to make those requests:
http://blog.think-async.com/2007_01_01_archive.html
It depends what you're after. Manuel's suggestion of boost::asio::ip::tcp::iostream is good if you want something at a lower level, directly returning the "raw" server response (However, I suspect that something is missing in the example provided in his answer: I think that a "GET" request should be written to the stream before reading from it. See this example from the Asio docs).
I have no experience with java.net.URL.openStream(), but it seems that it is at a little higher level in that only returns the body (and not the headers) of the reply, takes care of HTTP redirects, etc. In that case, yes, libcurl may be more what you want. You could also take a look at the cpp-netlib library, which is built on top of Boost.Asio. It is still in its infancy, but its http::client seems to already provide something pretty similar to what is provided by Java URL.openStream()