0

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

1
  • The files are similar, not the same. Commented Dec 15, 2014 at 22:01

1 Answer 1

1

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);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.