Closed bbogart closed 1 year ago
It seems like you found a bug. I can reproduce it here. If you use the RequestBuilder class to formulate your request, your application should work.
I have to add some new test-cases for the direct methods (this code actually fails in the test covering it, but that test is designed to just validate that the example code compiles) and fix it.
Thanks a lot for reporting this issue!
OK! Thank you; also it would be great if there were a couple very simple complete examples that start from scratch, i.e. connect to end point, connect to end-point and print data, connect to endpoint and parse results, etc. building up to the examples already included.
That's a good idea. I'll look into that when the bug is fixed.
> If you use the RequestBuilder class to formulate your request, your application should work.
Hello Again,
It look me a little white to get back to this, but even with RequestBuilder I'm not having any luck, I'm just getting "Caught exception: Failed to connect" rather than "Caught exception: Failed to connect (closed)"
Tried the two following programs, same result:
#include <iostream>
#include "restc-cpp/restc-cpp.h"
#include "restc-cpp/RequestBuilder.h"
using namespace std;
using namespace restc_cpp;
void DoSomethingInteresting(Context& ctx) {
try {
auto reply = RequestBuilder(ctx)
.Get("https://jsonplaceholder.typicode.com/posts/1")
.Execute();
} catch (const exception& ex) {
clog << "Caught exception: " << ex.what() << endl;
}
}
int main() {
// Create a REST client
auto RESTClient = RestClient::Create();
// Create a co-routine that runs in a thread
RESTClient->Process( DoSomethingInteresting );
cout << "RESTClient->IsClosed: " << RESTClient->IsClosed() << endl;
// Wait for the thread to finish and return.
// RESTClient->CloseWhenReady(true);
cout << "RESTClient->IsClosed: " << RESTClient->IsClosed() << endl;
return 0;
}
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/fusion/adapted.hpp>
#include "restc-cpp/restc-cpp.h"
#include "restc-cpp/RequestBuilder.h"
using namespace std;
using namespace restc_cpp;
// C++ structure that match the JSON entries received
// from http://jsonplaceholder.typicode.com/posts/{id}
struct Post {
int userId = 0;
int id = 0;
string title;
string body;
};
// Since C++ does not (yet) offer reflection, we need to tell the library how
// to map json members to a type. We are doing this by declaring the
// structs/classes with BOOST_FUSION_ADAPT_STRUCT from the boost libraries.
// This allows us to convert the C++ classes to and from JSON.
BOOST_FUSION_ADAPT_STRUCT(
Post,
(int, userId)
(int, id)
(string, title)
(string, body)
)
// The C++ main function - the place where any adventure starts
int main() {
// Create an instance of the rest client
auto rest_client = RestClient::Create();
// Create and instantiate a Post from data received from the server.
Post my_post = rest_client->ProcessWithPromiseT<Post>([&](Context& ctx) {
// This is a co-routine, running in a worker-thread
// Instantiate a Post structure.
Post post;
try {
// Serialize it asynchronously. The asynchronously part does not really matter
// here, but it may if you receive huge data structures.
SerializeFromJson(post,
// Construct a request to the server
RequestBuilder(ctx)
.Get("http://jsonplaceholder.typicode.com/posts/1")
// Add some headers for good taste
.Header("X-Client", "RESTC_CPP")
.Header("X-Client-Purpose", "Testing")
// Send the request
.Execute());
} catch (const exception& ex) {
clog << "Caught exception: " << ex.what() << endl;
}
// Return the post instance trough a C++ future<>
return post;
})
// Get the Post instance from the future<>, or any C++ exception thrown
// within the lambda.
.get();
// Print the result for everyone to see.
cout << "Received post# " << my_post.id << ", title: " << my_post.title;
}
I committed a fix for this problem some days ago. Have you pullet the latest changes from github?
Forgot to pull; I confirm things are working with and without using the request builder method.
Hello,
I'm using a simplified version of the "Fetch raw data" example:
And always get the "Failed to connect (closed)" exception, but if I use wget on the same machine, the connection, url and returned json data seem fine:
Running on Ubuntu 20.04, boost 1.71.0-6ubuntu6, openssl 1.1.1f-1ubuntu2.16
I did compile restc-cpp with openssl (from ccmake):
OPENSSL_CRYPTO_LIBRARY /usr/lib/x86_64-linux-gnu/libcrypto.so
OPENSSL_INCLUDE_DIR /usr/include
OPENSSL_SSL_LIBRARY /usr/lib/x86_64-linux-gnu/libssl.so
Compiling my test code with:
g++ gitExample.cpp -o gitExample -ggdb -std=c++14 `curl-config --libs` -lrestc-cpp -lz -lssl -lcrypto -lpthread -lboost_system -lboost_program_options -lboost_filesystem -lboost_date_time -lboost_context -lboost_coroutine -lboost_chrono -lboost_log -lboost_thread -lboost_log_setup -lboost_regex -lboost_atomic -lpthread
It looks like the issue is that the connection cannot be made because the client is already closed, but changing the code to the following leads to the same exception:
Prints:
RESTClient->IsClosed: 0 Caught exception: Failed to connect (closed) RESTClient->IsClosed: 1
Any hints as to what is going on?