CONNECT - Making the GetRest Library
To enable the REST feature with binary distributions of MariaDB, the function calling the cpprestsdk package is not included in CONNECT, thus allowing CONNECT normal operation when the cpprestsdk package is not installed. Therefore, it must be compiled separately as a library (so or dll) that will be loaded by CONNECT when needed.
This library will contain only one file shown here:
/************* Restget C++ Program Source Code File (.CPP) *************/ /* Adapted from the sample program of the Casablanca tutorial. */ /* Copyright Olivier Bertrand 2019. */ /***********************************************************************/ #include <cpprest/filestream.h> #include <cpprest/http_client.h> using namespace utility::conversions; // String conversions utilities using namespace web; // Common features like URIs. using namespace web::http; // Common HTTP functionality using namespace web::http::client; // HTTP client features using namespace concurrency::streams; // Asynchronous streams typedef const char* PCSZ; extern "C" int restGetFile(char* m, bool xt, PCSZ http, PCSZ uri, PCSZ fn); /***********************************************************************/ /* Make a local copy of the requested file. */ /***********************************************************************/ int restGetFile(char *m, bool xt, PCSZ http, PCSZ uri, PCSZ fn) { int rc = 0; auto fileStream = std::make_shared<ostream>(); if (!http || !fn) { strcpy(m, "Missing http or filename"); return 2; } // endif if (xt) fprintf(stderr, "restGetFile: fn=%s\n", fn); // Open stream to output file. pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn)) .then([=](ostream outFile) { *fileStream= outFile; if (xt) fprintf(stderr, "Outfile isopen=%d\n", outFile.is_open()); // Create http_client to send the request. http_client client(to_string_t(http)); if (uri) { // Build request URI and start the request. uri_builder builder(to_string_t(uri)); return client.request(methods::GET, builder.to_string()); } else return client.request(methods::GET); }) // Handle response headers arriving. .then([=](http_response response) { if (xt) fprintf(stderr, "Received response status code:%u\n", response.status_code()); // Write response body into the file. return response.body().read_to_end(fileStream->streambuf()); }) // Close the file stream. .then([=](size_t n) { if (xt) fprintf(stderr, "Return size=%zu\n", n); return fileStream->close(); }); // Wait for all the outstanding I/O to complete and handle any exceptions try { if (xt) fprintf(stderr, "Waiting\n"); requestTask.wait(); } catch (const std::exception &e) { if (xt) fprintf(stderr, "Error exception: %s\n", e.what()); sprintf(m, "Error exception: %s", e.what()); rc= 1; } // end try/catch if (xt) fprintf(stderr, "restget done: rc=%d\n", rc); return rc; } // end of restGetFile
This file exists in the source of CONNECT as restget.cpp
. If you have no access to the source, use your favorite editor to make it by copy/pasting from the above.
Then, on Linux, compile the GetRest.so library:
g++ -o GetRest.so -O3 -Wall -std=c++11 -fPIC -shared restget.cpp -lcpprest
Note: You can replace -O3
by -g
to make a debug version.
This library should be placed where it can be accessed. A good place is the directory where the libcpprest.so
is, for instance /usr/lib64
. You can move or copy it there.
On windows, using Visual Studio, make an empty win32 dll project named GetRest and add it the above file. Also add it the module definition file restget.def
:
LIBRARY REST EXPORTS restGetFile @1
Important: This file must be specified in the property linker input page.
Once compiled, the release or debug versions can be copied in the cpprestsdk
corresponding directories, bin or debug\bin.
That is all. It is a once-off job. Once done, it will work with all new MariaDB versions featuring CONNECT version 1.07.
Note: the xt tracing variable is true when connect_xtrace setting includes the value “MONGO” (512).
Caution: If your server crashes when using this feature, this is likely because the GetRest lib is linked to the wrong cpprestsdk lib (this may only apply on Windows)
A Release version of GetRest must be linked to the release version of the cpprestsdk lib (cpprest_2_10.dll) but if you make a Debug version of GetRest, make sure it is linked to the Debug version of cpprestsdk lib (cpprest_2_10d.dll)
This may be automatic if you use Visual Studio to make the GetRest.dll.