Concat boost::asio::read() response - c++

Juste a short question... I use sync_client.cpp, an exemple given by boost.asio, for try this librairy.
Code :
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <string.h>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(argv[1], "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << argv[2] << " HTTP/1.0\r\n";
request_stream << "Host: " << argv[1] << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line. The response streambuf will automatically
// grow to accommodate the entire line. The growth may be limited by passing
// a maximum size to the streambuf constructor.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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 1;
}
if (status_code != 200)
{
std::cout << "Response returned with status code " << status_code << "\n";
return 1;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, 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;
// Read until EOF, writing data to output as we go.
boost::system::error_code error;
while (boost::asio::read(socket, response,
boost::asio::transfer_at_least(1), error))
std::cout << &response;
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
return 0;
}
But this code, show the result in the prump. I want to put the response in a different var for work on it after.
I'm newbie and sorry for my english.
Thank a lot !
EDIT :
It's good i have found a solution.
std::stringstream s;
while (boost::asio::read(socket, response,
boost::asio::transfer_at_least(1), error))
s << &response;
const std::string htmlContent = s.str();

Related

How to access web service using Boost::Asio?

I wonder whether there is a possibility to access a web service using boost asio library.
I have tried following code (in IOS, C++11) which I got from boost asio documentation.
But it throws the following.
try
{
boost::asio::io_service io_service;
std::string address = "http://www.thomas-bayer.com/axis2/services/BLZService/";
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(address,boost::asio::ip::resolver_query_base::numeric_service);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
endpoint_iterator->host_name() = "www.thomas-bayer.com/axis2/services/BLZService/";
std::cout<<"Print Query --"<<std::endl;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "POST: HTTP/1.0\r\n";
request_stream << "Host: " << address << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line. The response streambuf will automatically
// grow to accommodate the entire line. The growth may be limited by passing
// a maximum size to the streambuf constructor.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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 " << status_code << "\n";
return;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, 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;
// Read until EOF, writing data to output as we go.
boost::system::error_code error;
while (boost::asio::read(socket, response,
boost::asio::transfer_at_least(1), error))
std::cout << &response;
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
Exception: connect: Can't assign requested address
Or
Exception: resolve: Host not found (authoritative)
What is wrong with the code? Or I am doing completely wrong?
Thanks
The name resolution fails, because you are confusing what is a request, a URL, a protocol, hostname and an IP address.
Do the requestion on a FQDN. You need to supply a service unless you know it. The service in this case follows from the the protocol¹, `http:// is usually served on port 80:
std::string const address = "www.thomas-bayer.com";
tcp::resolver::query query(address, "80", boost::asio::ip::resolver_query_base::numeric_service);
Note that on most systems you can equivalently use:
std::string const address = "www.thomas-bayer.com";
tcp::resolver::query query(address, "http");
See where the http:// and www.thomas-bayer.com parts went?
Now /axis2/services/BLZService/ is the query path, as you would write in a GET request:
request_stream << "GET /axis2/services/BLZService/ HTTP/1.1\r\n";
Notes:
POST is not a header (so no colon!) it's a HTTP "verb" (GET, POST, DELETE, PUT...)
The "Host" header is a host name:
request_stream << "Host: " << address << "\r\n";
was correct iff address was really the logical name for the host
setting the hostname like this:
endpoint_iterator->host_name() = "www.thomas-bayer.com/axis2/services/BLZService/";
is something I've never seen before and I'm not sure what it should achieve. Perhaps it's just wrong?
¹ by convention, it could be other
Fixes
#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::tcp;
void test() try {
boost::asio::io_service io_service;
std::string const address = "www.thomas-bayer.com";
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(address, "80", boost::asio::ip::resolver_query_base::numeric_service);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
std::cout << "Print Query --" << std::endl;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET /axis2/services/BLZService HTTP/1.0\r\n";
request_stream << "Host: " << address << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line. The response streambuf will automatically
// grow to accommodate the entire line. The growth may be limited by
// passing a maximum size to the streambuf constructor.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that response is OK.
std::istream response_stream(&response);
std::string http_version, status_message;
unsigned int status_code;
std::getline(response_stream >> http_version >> status_code, 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 " << status_code << "\n";
return;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, 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;
// Read until EOF, writing data to output as we go.
boost::system::error_code error;
while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error))
std::cout << &response;
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
} catch (std::exception &e) {
std::cout << "Exception: " << e.what() << "\n";
}
int main() { test(); }

Read http file content to string with Boost [C++]

I have to read the content of a file (in a webserver) to string in Visual Studio C++. I have a code which is working well on one webserver. But if I use another webserver, my program reads only the first 200 characters. Everything is same but the webserver.
This is the working URL: http://www.fxcoder.hu/fxc_esopus/clients.dat
And this is the max. 200 characters URL: http://www.forexhelpmate.com/app/webroot/forex/clients.dat
The clients.dat file is same on each server too.
My code:
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::ostringstream ostringstream_content;
int GetPageContent(char* argv[]){
try{
boost::asio::io_service io_service;
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(argv[0], "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end){
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error) throw boost::system::system_error(error);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << argv[1] << " HTTP/1.0\r\n";
request_stream << "Host: " << argv[0] << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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 1;
}
if (status_code != 200){
std::cout << "Response returned with status code " << status_code << "\n";
return 1;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, header) && header != "\r")
std::cout << header << "\n";
std::cout << "\n";
// Write whatever content we already have to output.
if (response.size() > 0){
ostringstream_content << &response;
}
// Read until EOF, writing data to output as we go.
while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)) std::cout << &response;
if (error != boost::asio::error::eof) throw boost::system::system_error(error);
}
catch (std::exception& e){
std::cout << "Exception: " << e.what() << "\n";
}
return 0;
}
What differences between the two web server could cause this problem?
Why would the second server only read the first 200 characters?
Thank you in advance.
Relative
Hungary, EU
You stream the first part to ostringstream_content and the rest to std::cout.
The following correctly downloads both files for me
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int GetPageContent(char const *argv[]) {
try {
boost::asio::io_service io_service;
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(argv[0], "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end) {
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << argv[1] << " HTTP/1.0\r\n";
request_stream << "Host: " << argv[0] << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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::cerr << "Invalid response\n";
return 1;
}
if (status_code != 200) {
std::cerr << "Response returned with status code " << status_code << "\n";
return 1;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, header) && header != "\r")
std::cerr << header << "\n";
std::cerr << "\n";
std::cerr << "Writing content data\n";
// Write whatever content we already have to output.
if (response.size() > 0) {
std::cout << &response;
}
// Read until EOF, writing data to output as we go.
while (true) {
size_t n = boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error);
if (!error)
{
if (n)
std::cout << &response;
}
if (error == boost::asio::error::eof)
break;
if (error)
throw boost::system::system_error(error);
}
}
catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << "\n";
}
std::cerr << "Done\n";
return 0;
}
int main(){
char const* argv[] = { "www.fxcoder.hu", "/fxc_esopus/clients.dat" };
//char const* argv[] = { "www.forexhelpmate.com", "/app/webroot/forex/clients.dat" };
return GetPageContent(argv);
}

boost::asio return http 301 error code while no error with fiddler

I would like to read a source code of an thml page with boost::asio.
Here is my sample code :
#include "stdafx.h"
#include <boost/algorithm/string/replace.hpp>
#include <boost/asio.hpp>
#include <vector>
#include <string>
#include <algorithm>
#include <sstream>
#include <ostream>
int _tmain(int argc, _TCHAR* argv[])
{
std::string strHost = "www.fdj.fr";
std::string strPort = "80";
std::string strUrlPath = "https://www.fdj.fr/jeux/jeux-de-tirage/keno/resultats";
std::string strUserAgent = "Fiddler";
//std::vector<std::string> header;
unsigned int TimeOut = 5000;
//do_get(strHost, strPort, strUrlPath, header, TimeOut);
try
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(strHost, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << strUrlPath << " HTTP/1.0\r\n";
request_stream << "User-Agent: " << strUserAgent << "\r\n";
request_stream << "Host: " << strHost << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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 1;
}
/*if (status_code != 200)
{
std::cout << "Response returned with status code " << status_code << "\n";
//return 1;
}*/
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, 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;
// Read until EOF, writing data to output as we go.
while (boost::asio::read(socket, response,
boost::asio::transfer_at_least(1), error))
std::cout << &response;
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
char a;
std::cin>>a ;
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
return 0;
}
The request sended is :
GET https://www.fdj.fr/jeux/jeux-de-tirage/keno/resultats HTTP/1.0
User-Agent: Fiddler
Host: www.fdj.fr
Accept: */*
Connection: close
If i run my programm i have :
If i run this request in fiddler ( by copy/paste) i have :
return code=200
(Accepted) and the page is loaded !
Anyone have an idea why i have this 301 error ?
I think it's due to an boost::asio parameters, but which ?
Thanks a lot,
Best regards,
Nixeus
There are two things happening here:
You are attempting to load an HTTPS URI over plain HTTP. This results in a 301 redirect that points you back to the original page over HTTPS. This indicates that the hosting server does not provide this resource over insecure HTTP.
Your HTTP implementation does not support redirects. You are making a request and delivering the first response. A full HTTP client would check for a 301 response and retry using the URI in the location header of the 301.
To fix this you will need to implement support for TLS/HTTPS and ideally HTTP redirects.

Http error 301 when reading website with asio/boost

I would like to get the source html code of a website in C++.
I tried with libcurl and curlpp but I don't succeed to link and build the libs...
So, I found a sample code in the boost website for reading websites.
I tried, but I have the 301 error code (Moved Permanently).
If I go on my website ( https://www.fdj.fr/jeux/jeux-de-tirage/keno/resultats ) I have no problem, and the website appear to be OK.
Anyone have some ideas ?
Here is my code:
std::string strHost= "fdj.fr";
std::string strUrlPath = "https://www.fdj.fr/jeux/jeux-de-tirage/keno/resultats";
try
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(strHost, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << strUrlPath << " HTTP/1.0\r\n";
request_stream << "Host: " << strHost << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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 1;
}
if (status_code != 200)
{
std::cout << "Response returned with status code " << status_code << "\n";
//return 1;
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Process the response headers.
std::string header;
while (std::getline(response_stream, 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;
// Read until EOF, writing data to output as we go.
while (boost::asio::read(socket, response,
boost::asio::transfer_at_least(1), error))
std::cout << &response;
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
}

Why my C++ Boost ASIO HTTP Client Returning Incomplete Response?

I'm new to C++ and I'm just trying to implement a simple HTTP Client using Boost ASIO Sync Http Client; I copied the example from Boost's site, just modified it to return the response as string rather than writing to console.
My code is making a call and it's returning a response but it is partial - it cuts off after the 10th line... I'm puzzled can someone please help me?
Here is my code and if you have Boost set up, you should be able to just copy/paste and run it.
I'm on Windows 7, using Visual Studio 2010 with Boost 1.47.
Thanks in advance.
-serkan
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_inserter.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
using boost::asio::ip::tcp;
typedef boost::gregorian::date Calendar;
std::string httpClient(std::string host, std::string path){
std::string res = "";
try{
boost::asio::io_service io_service;
// Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(host, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while(error && endpoint_iterator != end){
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if(error){ throw boost::system::system_error(error); }
// 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.
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << host << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
// Send the request.
boost::asio::write(socket, request);
// Read the response status line.
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
// Check that 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";
}
if(status_code != 200){
std::cout << "Response returned with status code " << status_code << "\n";
}
// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket, response, "\r\n\r\n");
// Write whatever content we already have to output.
if(response.size() > 0){
std::ostringstream oss;
oss << &response;
res = oss.str();
}
// Read until EOF, writing data to output as we go.
while(boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)){
//std::cout << &response; // don't want to print just return
}
if(error != boost::asio::error::eof){ throw boost::system::system_error(error); }
}catch(std::exception& e){
std::cout << "Exception: " << e.what() << "\n";
}
return res;
}
int main(int argc, char* argv[]){
std::cout << httpClient("download.finance.yahoo.com", "/d/quotes.csv?s=aapl,aig,msft,jpm,WFC,BAC,C,GS,USB,AXP,MS,MET,BK,PNC,PRU,SPG,AFL,TRV,COF,STT,ACE,BBT,CME,SCHW&f=sl1d1t1");
return 0;
}
It should return:
"AAPL",384.62,"11/11/2011","4:00pm"
"AIG",23.85,"11/11/2011","4:01pm"
"MSFT",26.91,"11/11/2011","4:00pm"
"JPM",33.28,"11/11/2011","4:01pm"
"WFC",25.65,"11/11/2011","4:00pm"
"BAC",6.21,"11/11/2011","4:00pm"
"C",29.33,"11/11/2011","4:00pm"
"GS",101.66,"11/11/2011","4:00pm"
"USB",25.94,"11/11/2011","4:00pm"
"AXP",50.37,"11/11/2011","4:00pm"
"MS",16.36,"11/11/2011","4:00pm"
"MET",33.07,"11/11/2011","4:00pm"
"BK",21.51,"11/11/2011","4:00pm"
"PNC",53.87,"11/11/2011","4:01pm"
"PRU",54.05,"11/11/2011","4:01pm"
"SPG",127.97,"11/11/2011","4:02pm"
"AFL",44.87,"11/11/2011","4:01pm"
"TRV",58.43,"11/11/2011","4:04pm"
"COF",45.02,"11/11/2011","4:01pm"
"STT",41.24,"11/11/2011","4:02pm"
"ACE",71.24,"11/11/2011","4:01pm"
"BBT",23.58,"11/11/2011","4:00pm"
"CME",263.57,"11/11/2011","4:00pm"
"SCHW",12.36,"11/11/2011","4:00pm"
But it returns:
Date: Sat, 12 Nov 2011 21:34:23 GMT
P3P: policyref="http://p3p.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"
Cache-Control: private
Connection: close
Content-Type: application/octet-stream
"AAPL",384.62,"11/11/2011","4:00pm"
"AIG",23.85,"11/11/2011","4:01pm"
"MSFT",26.91,"11/11/2011","4:00pm"
"JPM",33.28,"11/11/2011","4:01pm"
"WFC",25.65,"11/11/
You have commented out the line
//std::cout << &response;
Now, I understand that you don't want the function to print out the result but to return it. However, the loop that contains that commented-out line reads out the rest of the response, and now you are just throwing it away. You need to capture it into your return-value variable. A simple fix is to replace the commented-out line with
std::ostringstream oss;
oss << &response;
res += oss.str();
But that's not the cleanest way to do it – you should probably just let the stuff accumulate in response and convert it into a string at the end.