2019-07-30 22:45:04 +02:00
|
|
|
/************* 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>
|
|
|
|
#if defined(MARIADB)
|
|
|
|
#include <my_global.h>
|
|
|
|
#else
|
2019-08-17 16:58:58 +02:00
|
|
|
#include "mini-global.h"
|
|
|
|
#define _OS_H_INCLUDED // Prevent os.h to be called
|
2019-07-30 22:45:04 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
#include "global.h"
|
|
|
|
|
2019-08-17 16:58:58 +02:00
|
|
|
static uint xt = 0; // Used by lamda expressions
|
2019-07-30 22:45:04 +02:00
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* Make a local copy of the requested file. */
|
|
|
|
/***********************************************************************/
|
|
|
|
int restGetFile(PGLOBAL g, PCSZ http, PCSZ uri, PCSZ fn)
|
|
|
|
{
|
2019-08-17 16:58:58 +02:00
|
|
|
int rc = 0;
|
|
|
|
auto fileStream = std::make_shared<ostream>();
|
2019-07-30 22:45:04 +02:00
|
|
|
|
2019-08-17 16:58:58 +02:00
|
|
|
if (!http || !fn) {
|
|
|
|
strcpy(g->Message, "Missing http or filename");
|
|
|
|
return 2;
|
|
|
|
} // endif
|
2019-07-30 22:45:04 +02:00
|
|
|
|
2019-08-17 16:58:58 +02:00
|
|
|
xt = GetTraceValue();
|
|
|
|
xtrc(515, "restGetFile: fn=%s\n", fn);
|
2019-07-30 22:45:04 +02:00
|
|
|
|
|
|
|
// Open stream to output file.
|
2019-08-17 16:58:58 +02:00
|
|
|
pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
|
|
|
|
.then([=](ostream outFile) {
|
|
|
|
*fileStream= outFile;
|
|
|
|
|
|
|
|
if (xt & 515)
|
|
|
|
htrc("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 & 515)
|
|
|
|
htrc("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 & 515)
|
|
|
|
htrc("Return size=%u\n", n);
|
|
|
|
|
|
|
|
return fileStream->close();
|
|
|
|
});
|
2019-07-30 22:45:04 +02:00
|
|
|
|
|
|
|
// Wait for all the outstanding I/O to complete and handle any exceptions
|
2019-08-17 16:58:58 +02:00
|
|
|
try {
|
2019-07-30 22:45:04 +02:00
|
|
|
requestTask.wait();
|
2019-08-17 16:58:58 +02:00
|
|
|
xtrc(515, "In Wait\n");
|
|
|
|
} catch (const std::exception &e) {
|
|
|
|
xtrc(515, "Error exception: %s\n", e.what());
|
|
|
|
sprintf(g->Message, "Error exception: %s", e.what());
|
2019-07-30 22:45:04 +02:00
|
|
|
rc= 1;
|
|
|
|
} // end try/catch
|
|
|
|
|
2019-08-17 16:58:58 +02:00
|
|
|
xtrc(515, "restget done: rc=%d\n", rc);
|
2019-07-30 22:45:04 +02:00
|
|
|
return rc;
|
2019-08-17 16:58:58 +02:00
|
|
|
} // end of restGetFile
|