-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathExample2.cpp
More file actions
151 lines (123 loc) · 4.96 KB
/
Example2.cpp
File metadata and controls
151 lines (123 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// This file is adapted almost verbative where possible from
// the boost asio async http example
//
// async_client.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Modified by John R. Bandela
#include "asio_helper.hpp"
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <tuple>
void get_http(boost::asio::io_service& io,std::string server, std::string path){
using namespace asio_helper::handlers;
// This allows us to do await
asio_helper::do_async(io,[=,&io](asio_helper::async_helper helper){
using boost::asio::ip::tcp;
// This allows us to use the predefined handlers
// such as read_handler, write_handler, etc
using namespace asio_helper::handlers;
tcp::resolver resolver_(io);
tcp::socket socket_(io);
boost::asio::streambuf request_;
boost::asio::streambuf response_;
// Form the request. We specify the "Connection: close" header so that the
// server will close the socket after transmitting the response. This will
// allow us to treat all data up until the EOF as the content.
std::ostream request_stream(&request_);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Start an asynchronous resolve to translate the server and service names
// into a list of endpoints.
tcp::resolver::query query(server, "http");
// Do async resolve
tcp::resolver::iterator endpoint_iterator;
boost::system::error_code ec;
std::tie(ec,endpoint_iterator) = helper.await<resolve_handler>(
[&](resolve_handler::callback_type cb){
resolver_.async_resolve(query,cb);
});
if(ec) {throw boost::system::system_error(ec);}
// Do async connect
std::tie(ec,std::ignore) = helper.await_async_connect(socket_,endpoint_iterator);
if(ec){throw boost::system::system_error(ec);}
// Connection was successful, send request
std::tie(ec,std::ignore) = helper.await_async_write(socket_,request_);
if(ec){throw boost::system::system_error(ec);}
// Read the response status line
std::tie(ec,std::ignore) = helper.await_async_read_until(socket_,response_,"\r\n");
if(ec){throw boost::system::system_error(ec);}
// Check that the response is OK
std::istream response_stream(&response_);
std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
std::cout << "Invalid response\n";
return;
}
if (status_code != 200)
{
std::cout << "Response returned with status code ";
std::cout << status_code << "\n";
return;
}
// Read the response headers, which are terminated by a blank line.
std::tie(ec,std::ignore) = helper.await_async_read_until(socket_, response_, "\r\n\r\n");
if(ec){throw boost::system::system_error(ec);}
// Process the response headers.
std::istream response_stream2(&response_);
std::string header;
while (std::getline(response_stream2, header) && header != "\r")
std::cout << header << "\n";
std::cout << "\n";
// Write whatever content we already have to output.
if (response_.size() > 0)
std::cout << &response_;
// Continue reading remaining data until EOF.
bool done = false;
while(!done){
std::tie(ec,std::ignore) = helper.await_async_read(socket_, response_,
boost::asio::transfer_at_least(1));
if(ec && ec != boost::asio::error::eof){throw boost::system::system_error(ec);}
done = (ec == boost::asio::error::eof);
// Write all of the data so far
std::cout << &response_;
}
});
}
int main(int argc, char* argv[])
{
try
{
if (argc != 3)
{
std::cout << "Usage: example2 <server> <path>\n";
std::cout << "Example:\n";
std::cout << " Example2 www.boost.org /LICENSE_1_0.txt\n";
return 1;
}
boost::asio::io_service io_service;
get_http(io_service,argv[1],argv[2]);
io_service.run();
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
return 0;
}