0

I tied to implement a REST Client with C++ and the Restbed Library

I tried to copy the code from the example but seem to be missing something.

The Example shows a body but my code does not.

I tried playing with the Headers but no luck.

Can anybody with some knowledge of the library point me in the right direction?

Or suggest me a easy to use C++ REST Library that runs on Solaris?

The Example:

/*
 * Example illustrating a HTTP client.
 *
 * Usage:
 *    ./distribution/example/http_client
 */

#include <memory>
#include <future>
#include <cstdio>
#include <cstdlib>
#include <restbed>

using namespace std;
using namespace restbed;

void print( const shared_ptr< Response >& response )
{
    fprintf( stderr, "*** Response ***\n" );
    fprintf( stderr, "Status Code:    %i\n", response->get_status_code( ) );
    fprintf( stderr, "Status Message: %s\n", response->get_status_message( ).data( ) );
    fprintf( stderr, "HTTP Version:   %.1f\n", response->get_version( ) );
    fprintf( stderr, "HTTP Protocol:  %s\n", response->get_protocol( ).data( ) );

    for ( const auto header : response->get_headers( ) )
    {
        fprintf( stderr, "Header '%s' > '%s'\n", header.first.data( ), header.second.data( ) );
    }

    auto length = 0;
    response->get_header( "Content-Length", length );

    Http::fetch( length, response );

    fprintf( stderr, "Body:           %.*s...\n\n", 25, response->get_body( ).data( ) );
}

int main( const int, const char** )
{
    auto request = make_shared< Request >( Uri( "http://www.corvusoft.co.uk:80/?query=search%20term" ) );
    request->set_header( "Accept", "*/*" );
    request->set_header( "Host", "www.corvusoft.co.uk" );

    auto response = Http::sync( request );
    print( response );

    auto future = Http::async( request, [ ]( const shared_ptr< Request >, const shared_ptr< Response > response )
    {
        fprintf( stderr, "Printing async response\n" );
        print( response );
    } );

    future.wait( );

    return EXIT_SUCCESS;
}

My current Implementation

#include "HttpClient.h"
#include "HTTPException.h"
#include <restbed>
#include <iostream>

using namespace std;
using namespace restbed;

void HttpClient::getVersion_0() {
    auto request = make_shared< Request >( Uri( "http://www.golem.de/" ) );
    request->set_header( "Accept", "*/*" );
    request->set_header( "Cache-Control", "no-cache" );
    request->set_header("Accept-Encoding", "gzip,deflate");
    request->set_header("User-Agent", "PKG6/0.0.1");
    request->set_header("Host", "www.golem.de");
    request->set_header("Connection", "Keep-Alive");
    request->set_method("GET");

    auto response = Http::sync( request );

    int code = response->get_status_code();
/*
    if(code != 200){
        throw pkg::exception::HTTPBadResponseException(code);
    }
*/
    print(response);

    /*
    auto future = Http::async( request, [ ]( const shared_ptr< Request >, const shared_ptr< Response > response )
    {

    } );

    future.wait( );

    */
}


void HttpClient::print(const std::shared_ptr<restbed::Response> &response) {
    fprintf( stderr, "\n*** Response ***\n" );
    fprintf( stderr, "Status Code:    %i\n", response->get_status_code( ) );
    fprintf( stderr, "Status Message: %s\n", response->get_status_message( ).data( ) );
    fprintf( stderr, "HTTP Version:   %.1f\n", response->get_version( ) );
    fprintf( stderr, "HTTP Protocol:  %s\n", response->get_protocol( ).data( ) );

    for ( const auto header : response->get_headers( ) )
    {
        fprintf( stderr, "Header '%s' > '%s'\n", header.first.data( ), header.second.data( ) );
    }

    auto length = 0;
    response->get_header( "Content-Length", length );

    Http::fetch( length, response );

    fprintf( stderr, "Body:           %.*s...\n\n", 25, response->get_body( ).data( ) );
}
Toasterson
  • 115
  • 1
  • 2
  • 11
  • I notice you set the 'Accept-Encoding: gzip,deflate' header. If this is returning compressed data, which you do not seem to decompress, you'll most likely have '\0' characters in the body. So when you attempt to print the output it fails to display anything. – Ben Crowhurst Sep 02 '16 at 19:30
  • Is any output printed? If so, what? – Ben Crowhurst Sep 02 '16 at 19:31
  • I tried it without Headers. Only Host and Accept content Headers. But to no avail. It prints (null). Headers and Information about response are printed. Just not body. – Toasterson Sep 02 '16 at 21:01
  • Have you changed the URL in your example to www.corvusoft.co.uk to see what happens? – Ben Crowhurst Sep 06 '16 at 08:36
  • Yes i tried many combinations. Corvusoft gave me a 301 and golem.de gave me an empty body. – Toasterson Sep 06 '16 at 15:05
  • 301 (Moved Permanently). What URL did you use? use www.corvusoft.co.uk, not corvusoft.co.uk. what happens now? – Ben Crowhurst Sep 07 '16 at 01:16
  • Restbed will not manage 301 for you. The framework is built for flexibility, not to abstract the Hyper Text Transfer Protocol. Follow the redirect my friend. – Ben Crowhurst Sep 07 '16 at 01:19
  • Appart from the fact that i have no idea how to follow the redirect. I tired www.corvusoft.co.uk aswell with no luck. Still if the framework is not able to handle the HTTP responses from pkg.openindiana.org then it does not work for me. because i can not change the server side. I am looking at the Framework Beast as alternative. – Toasterson Sep 07 '16 at 07:17
  • There is no fault with the framework, I fear you lack sufficient knowledge of [HTTP](https://www.w3.org/Protocols/). Best of luck my friend. – Ben Crowhurst Sep 07 '16 at 23:41
  • @dparnovskiy answer is correct, sorry we missed this. API has changed since 4.0. – Ben Crowhurst Nov 19 '16 at 01:58

2 Answers2

2

The first example contains error:

auto length = 0;

response->get_header( "Content-Length", length );

get_header actually returns the header value and second parameter is a default value.

So length is always 0

0

I Switched to Beast Library. It has less samples for Server side code but as a client implementation it is sufficient.

Toasterson
  • 115
  • 1
  • 2
  • 11
  • Oh that is saddening to hear. We have decided to pull the client functionality out into a separate project Restless. Should be public before the end of November 2016. All the best with the Beast Library we hear good things. – Ben Crowhurst Nov 05 '16 at 00:56