1 /************* Restget C++ Program Source Code File (.CPP) *************/
2 /* Adapted from the sample program of the Casablanca tutorial. */
3 /* Copyright Olivier Bertrand 2019. */
4 /***********************************************************************/
5 #include <cpprest/filestream.h>
6 #include <cpprest/http_client.h>
7
8 using namespace utility::conversions; // String conversions utilities
9 using namespace web; // Common features like URIs.
10 using namespace web::http; // Common HTTP functionality
11 using namespace web::http::client; // HTTP client features
12 using namespace concurrency::streams; // Asynchronous streams
13
14 typedef const char* PCSZ;
15
16 extern "C" int restGetFile(char* m, bool xt, PCSZ http, PCSZ uri, PCSZ fn);
17
18 /***********************************************************************/
19 /* Make a local copy of the requested file. */
20 /***********************************************************************/
restGetFile(char * m,bool xt,PCSZ http,PCSZ uri,PCSZ fn)21 int restGetFile(char *m, bool xt, PCSZ http, PCSZ uri, PCSZ fn)
22 {
23 int rc = 0;
24 auto fileStream = std::make_shared<ostream>();
25
26 if (!http || !fn) {
27 //strcpy(g->Message, "Missing http or filename");
28 strcpy(m, "Missing http or filename");
29 return 2;
30 } // endif
31
32 if (xt)
33 fprintf(stderr, "restGetFile: fn=%s\n", fn);
34
35 // Open stream to output file.
36 pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
37 .then([=](ostream outFile) {
38 *fileStream= outFile;
39
40 if (xt)
41 fprintf(stderr, "Outfile isopen=%d\n", outFile.is_open());
42
43 // Create http_client to send the request.
44 http_client client(to_string_t(http));
45
46 if (uri) {
47 // Build request URI and start the request.
48 uri_builder builder(to_string_t(uri));
49 return client.request(methods::GET, builder.to_string());
50 } else
51 return client.request(methods::GET);
52 })
53
54 // Handle response headers arriving.
55 .then([=](http_response response) {
56 if (xt)
57 fprintf(stderr, "Received response status code:%u\n",
58 response.status_code());
59
60 // Write response body into the file.
61 return response.body().read_to_end(fileStream->streambuf());
62 })
63
64 // Close the file stream.
65 .then([=](size_t n) {
66 if (xt)
67 fprintf(stderr, "Return size=%zu\n", n);
68
69 return fileStream->close();
70 });
71
72 // Wait for all the outstanding I/O to complete and handle any exceptions
73 try {
74 if (xt)
75 fprintf(stderr, "Waiting\n");
76
77 requestTask.wait();
78 } catch (const std::exception &e) {
79 if (xt)
80 fprintf(stderr, "Error exception: %s\n", e.what());
81
82 sprintf(m, "Error exception: %s", e.what());
83 rc= 1;
84 } // end try/catch
85
86 if (xt)
87 fprintf(stderr, "restget done: rc=%d\n", rc);
88
89 return rc;
90 } // end of restGetFile
91