when you use raw sockets to implement a protocol
for HTTP you need to follow the steps below
Note : i will use code parts from the sample link you have provided (without testing myself)
first find target end point ,you need an IP address and port (default 80 for HTTP) can also be 8080 or any for dedicated services
If you have a domain name or just a host name you need to resolve this to obtain IP address
If you have a URL such as
http://domain.com/services/api
you can not pass this URL to resolver directly
You must use only domain name
http://domain.com
so you need to split this URL to 2 parts as host and resource
consider following; i have 2 variables as domain and resource and passing domain variable to resolver
std::string domain = "http://domain.com";
std::string resource = "/services/api";
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(domain, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
And here i am connecting to the server
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
once the connection established you can use it for other transactions
and the further navigation will be made with headers
A HTTP packed consist of 3 parts : status/request line ,headers ,content
status/request line
header-field:value
header-field:value
header-field:value
header-field:value
content
Now you need to contruct a request header , request specified resource from server
You have to provide
Host field in request header ,resource can not be found otherwise
because server uses that to map local file path to requested resource
consider a web server at IP 123.123.123.123 and there are 100 shared host accounts (web sites) under a CP
if you do not provide host name you will reach default landing page of server/CP
you can also add other http headers to qualify your request
std::string domain = "http://domain.com";
std::string resource = "/services/api";
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << resource << " HTTP/1.0\r\n";
request_stream << "Host: " << domain << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: keep-alive\r\n\r\n";
boost::asio::write(socket, request);
If you noticed that there is a extra (empty) line at the end of header
\r\n
that tells server there is no more headers to read
For a simple GET request you do not need to send a content
Now time has come to get response ,validate the response by cheking the response line
See if you have recevied a status code other than 200 , or something other than a http response
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
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 1;
}
if (status_code != 200)
{
std::cout << "Response returned with status code " << status_code << "\n";
return 1;
}
}
Now read response headers ,check content type ,encoding ,length etc..
boost::asio::read_until(socket, response, "\r\n\r\n");
std::string header;
while (std::getline(response_stream, header) && header != "\r")
std::cout << header << "\n";
std::cout << "\n";
finally the
response
variable contains the content that you expected to receive from server