xref: /aosp_15_r20/external/sandboxed-api/oss-internship-2020/curl/examples/example2.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Sandboxed version of getinmemory.c
16 // HTTP GET request using callbacks
17 
18 #include <cstdlib>
19 
20 #include "../curl_util.h"  // NOLINT(build/include)
21 #include "../sandbox.h"    // NOLINT(build/include)
22 #include "absl/strings/str_cat.h"
23 #include "sandboxed_api/util/status_macros.h"
24 
25 namespace {
26 
Example2()27 absl::Status Example2() {
28   // Initialize sandbox2 and sapi
29   curl::CurlSapiSandbox sandbox;
30   SAPI_RETURN_IF_ERROR(sandbox.Init());
31   curl::CurlApi api(&sandbox);
32 
33   // Generate pointer to WriteMemoryCallback function
34   void* function_ptr;
35   SAPI_RETURN_IF_ERROR(
36       sandbox.rpc_channel()->Symbol("WriteToMemory", &function_ptr));
37   sapi::v::RemotePtr write_to_memory(function_ptr);
38 
39   // Initialize the curl session
40   curl::CURL* curl_handle;
41   SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
42   sapi::v::RemotePtr curl(curl_handle);
43   if (!curl_handle) {
44     return absl::UnavailableError("curl_easy_init failed: Invalid curl handle");
45   }
46 
47   int curl_code;
48 
49   // Specify URL to get
50   sapi::v::ConstCStr url("http://example.com");
51   SAPI_ASSIGN_OR_RETURN(
52       curl_code,
53       api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
54   if (curl_code != 0) {
55     return absl::UnavailableError(absl::StrCat(
56         "curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
57   }
58 
59   // Set WriteMemoryCallback as the write function
60   SAPI_ASSIGN_OR_RETURN(
61       curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEFUNCTION,
62                                           &write_to_memory));
63   if (curl_code != 0) {
64     return absl::UnavailableError(absl::StrCat(
65         "curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
66   }
67 
68   // Pass 'chunk' struct to the callback function
69   sapi::v::LenVal chunk(0);
70   SAPI_ASSIGN_OR_RETURN(curl_code,
71                         api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEDATA,
72                                                  chunk.PtrBoth()));
73   if (curl_code != 0) {
74     return absl::UnavailableError(absl::StrCat(
75         "curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
76   }
77 
78   // Set a user agent
79   sapi::v::ConstCStr user_agent("libcurl-agent/1.0");
80   SAPI_ASSIGN_OR_RETURN(curl_code,
81                         api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_USERAGENT,
82                                                  user_agent.PtrBefore()));
83   if (curl_code != 0) {
84     return absl::UnavailableError(absl::StrCat(
85         "curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
86   }
87 
88   // Perform the request
89   SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
90   if (curl_code != 0) {
91     return absl::UnavailableError(absl::StrCat(
92         "curl_easy_perform failed: ", curl::StrError(&api, curl_code)));
93   }
94 
95   // Retrieve memory size
96   SAPI_RETURN_IF_ERROR(sandbox.TransferFromSandboxee(&chunk));
97   std::cout << "memory size: " << chunk.GetDataSize() << " bytes" << std::endl;
98 
99   // Cleanup curl
100   SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
101 
102   return absl::OkStatus();
103 }
104 
105 }  // namespace
106 
main(int argc,char * argv[])107 int main(int argc, char* argv[]) {
108   gflags::ParseCommandLineFlags(&argc, &argv, true);
109   sapi::InitLogging(argv[0]);
110 
111   if (absl::Status status = Example2(); !status.ok()) {
112     LOG(ERROR) << "Example2 failed: " << status.ToString();
113     return EXIT_FAILURE;
114   }
115 
116   return EXIT_SUCCESS;
117 }
118