Simple wget¶
This example is a very simple implementation of a wget
style
clone. It’s very similar to the previous example, but introduces the
uri
class.
The code¶
#include <boost/network/protocol/http/client.hpp>
#include <boost/network/uri.hpp>
#include <string>
#include <fstream>
#include <iostream>
namespace http = boost::network::http;
namespace uri = boost::network::uri;
namespace {
std::string get_filename(const uri::uri &url) {
std::string path = uri::path(url);
std::size_t index = path.find_last_of('/');
std::string filename = path.substr(index + 1);
return filename.empty()? "index.html" : filename;
}
} // namespace
int
main(int argc, char *argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " url" << std::endl;
return 1;
}
try {
http::client client;
http::client::request request(argv[1]);
http::client::response response = client.get(request);
std::string filename = get_filename(request.uri());
std::cout << "Saving to: " << filename << std::endl;
std::ofstream ofs(filename.c_str());
ofs << static_cast<std::string>(body(response)) << std::endl;
}
catch (std::exception &e) {
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}
Running the example¶
You can then run this to copy the Boost website:
$ cd ~/cpp-netlib-build
$ make simple_wget
$ ./example/simple_wget http://www.boost.org/
$ cat index.html
Diving into the code¶
As with wget
, this example simply makes an HTTP request to the
specified resource, and saves it on the filesystem. If the file name
is not specified, it names the resultant file as index.html
.
The new thing to note here is use of the uri
class. The uri
takes a string as a constructor argument and parses it. The uri
parser is fully-compliant with RFC 3986. The URI is provided in
the following header:
#include <boost/network/uri.hpp>
Most of the rest of the code is familiar from the previous example. To retrieve the URI resource’s file name, the following function is provided:
std::string get_filename(const uri::uri &url) {
std::string path = uri::path(url);
std::size_t index = path.find_last_of('/');
std::string filename = path.substr(index + 1);
return filename.empty()? "index.html" : filename;
}
The uri
interface provides access to its different components:
scheme
, user_info
, host
, port
, path
, query
and
fragment
. The code above takes the URI path to determine the
resource name.
Next we’ll develop a simple client/server application using
http::server
and http::client
.