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