Improve curl example

- Update sandbox policy (bring back inclusion of `/lib` to enable glibc
  resolver
- Better error handling using new `curl_util` library

Signed-off-by: Christian Blichmann <cblichmann@google.com>
pull/82/head
Christian Blichmann 2021-01-26 15:58:06 +01:00
parent 6f33cef716
commit d1e8ad94a8
No known key found for this signature in database
GPG Key ID: 19DC5E747974E966
11 changed files with 184 additions and 88 deletions

View File

@ -45,6 +45,7 @@ add_subdirectory(
# Generate SAPI header
add_sapi_library(curl_sapi
SOURCES sandbox.h
# List of all the methods in https://curl.haxx.se/libcurl/c/allfuncs.html
# Some are added or modified because the original ones are not supported
@ -127,10 +128,16 @@ add_sapi_library(curl_sapi
NAMESPACE curl
)
# Include generated SAPI header
target_include_directories(curl_sapi INTERFACE
"${PROJECT_BINARY_DIR}"
"${PROJECT_BINARY_DIR}" # Include generated SAPI header
)
add_library(curl_util STATIC
curl_util.cc
curl_util.h
)
target_link_libraries(curl_util PUBLIC
curl_sapi
)
# Add examples

View File

@ -0,0 +1,37 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "curl_util.h" // NOLINT(build/include)
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
namespace curl {
std::string StrError(curl::CurlApi* api, int curl_error) {
absl::StatusOr<void*> remote_error_message =
api->curl_easy_strerror(static_cast<CURLcode>(curl_error));
if (!remote_error_message.ok()) {
return absl::StrCat("Code ", curl_error, " (curl_easy_strerror failed)");
}
absl::StatusOr<std::string> error_message =
api->sandbox()->GetCString(sapi::v::RemotePtr(*remote_error_message));
if (!error_message.ok()) {
return absl::StrCat("Code ", curl_error, " (error getting error message)");
}
return *error_message;
}
} // namespace curl

View File

@ -0,0 +1,30 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CURL_UTIL_H_
#define CURL_UTIL_H_
#include <string>
#include "curl_sapi.sapi.h" // NOLINT(build/include)
namespace curl {
// Calls into the sandbox to retrieve the error message for the curl error code
// in curl_error.
std::string StrError(curl::CurlApi* api, int curl_error);
} // namespace curl
#endif // CURL_UTIL_H_

View File

@ -22,6 +22,7 @@ add_executable(example1
)
target_link_libraries(example1 PRIVATE
curl_sapi
curl_util
sapi::sapi
)
@ -32,6 +33,7 @@ add_executable(example2
)
target_link_libraries(example2 PRIVATE
curl_sapi
curl_util
sapi::sapi
)
@ -42,6 +44,7 @@ add_executable(example3
)
target_link_libraries(example3 PRIVATE
curl_sapi
curl_util
sapi::sapi
)
@ -52,6 +55,7 @@ add_executable(example4
)
target_link_libraries(example4 PRIVATE
curl_sapi
curl_util
sapi::sapi
)
@ -62,6 +66,7 @@ add_executable(example5
)
target_link_libraries(example5 PRIVATE
curl_sapi
curl_util
sapi::sapi
)
@ -72,5 +77,6 @@ add_executable(example6
)
target_link_libraries(example6 PRIVATE
curl_sapi
curl_util
sapi::sapi
)

View File

@ -17,8 +17,11 @@
#include <cstdlib>
#include "../sandbox.h" // NOLINT(build/include)
#include "../curl_util.h" // NOLINT(build/include)
#include "../sandbox.h" // NOLINT(build/include)
#include "absl/strings/str_cat.h"
#include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/util/status_macros.h"
namespace {
@ -33,7 +36,7 @@ absl::Status Example1() {
SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
sapi::v::RemotePtr curl(curl_handle);
if (!curl_handle) {
return absl::UnavailableError("curl_easy_init failed: curl is NULL");
return absl::UnknownError("curl_easy_init failed: Invalid curl handle");
}
int curl_code;
@ -44,8 +47,8 @@ absl::Status Example1() {
curl_code,
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnknownError(absl::StrCat("curl_easy_setopt_ptr failed: ",
curl::StrError(&api, curl_code)));
}
// Set the library to follow a redirection
@ -53,8 +56,8 @@ absl::Status Example1() {
curl_code,
api.curl_easy_setopt_long(&curl, curl::CURLOPT_FOLLOWLOCATION, 1l));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_long failed: ", curl_code));
return absl::UnknownError(absl::StrCat("curl_easy_setopt_long failed: ",
curl::StrError(&api, curl_code)));
}
// Disable authentication of peer certificate
@ -62,15 +65,15 @@ absl::Status Example1() {
curl_code,
api.curl_easy_setopt_long(&curl, curl::CURLOPT_SSL_VERIFYPEER, 0l));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_long failed: ", curl_code));
return absl::UnknownError(absl::StrCat("curl_easy_setopt_long failed: ",
curl::StrError(&api, curl_code)));
}
// Perform the request
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_perform failed: ", curl_code));
return absl::UnknownError(absl::StrCat("curl_easy_perform failed: ",
curl::StrError(&api, curl_code)));
}
// Cleanup curl

View File

@ -16,10 +16,11 @@
// HTTP GET request using callbacks
#include <cstdlib>
#include <iostream>
#include "../sandbox.h" // NOLINT(build/include)
#include "../curl_util.h" // NOLINT(build/include)
#include "../sandbox.h" // NOLINT(build/include)
#include "absl/strings/str_cat.h"
#include "sandboxed_api/util/status_macros.h"
namespace {
@ -40,7 +41,7 @@ absl::Status Example2() {
SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
sapi::v::RemotePtr curl(curl_handle);
if (!curl_handle) {
return absl::UnavailableError("curl_easy_init failed: curl is NULL");
return absl::UnavailableError("curl_easy_init failed: Invalid curl handle");
}
int curl_code;
@ -51,8 +52,8 @@ absl::Status Example2() {
curl_code,
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set WriteMemoryCallback as the write function
@ -60,8 +61,8 @@ absl::Status Example2() {
curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEFUNCTION,
&write_to_memory));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Pass 'chunk' struct to the callback function
@ -70,8 +71,8 @@ absl::Status Example2() {
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEDATA,
chunk.PtrBoth()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set a user agent
@ -80,15 +81,15 @@ absl::Status Example2() {
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_USERAGENT,
user_agent.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Perform the request
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_perform failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_perform failed: ", curl::StrError(&api, curl_code)));
}
// Retrieve memory size

View File

@ -17,7 +17,11 @@
#include <cstdlib>
#include "../sandbox.h" // NOLINT(build/include)
#include "../curl_util.h" // NOLINT(build/include)
#include "../sandbox.h" // NOLINT(build/include)
#include "absl/strings/str_cat.h"
#include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/util/status_macros.h"
namespace {
@ -25,9 +29,9 @@ class CurlSapiSandboxEx3 : public curl::CurlSapiSandbox {
public:
CurlSapiSandboxEx3(std::string ssl_certificate, std::string ssl_key,
std::string ca_certificates)
: ssl_certificate(ssl_certificate),
ssl_key(ssl_key),
ca_certificates(ca_certificates) {}
: ssl_certificate(std::move(ssl_certificate)),
ssl_key(std::move(ssl_key)),
ca_certificates(std::move(ca_certificates)) {}
private:
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
@ -35,11 +39,9 @@ class CurlSapiSandboxEx3 : public curl::CurlSapiSandbox {
// Add the syscalls and files missing in CurlSandbox to a new PolicyBuilder
auto policy_builder = std::make_unique<sandbox2::PolicyBuilder>();
(*policy_builder)
.AllowFutexOp(FUTEX_WAIT_PRIVATE)
.AllowGetPIDs()
.AllowGetRandom()
.AllowHandleSignals()
.AllowSyscall(__NR_sysinfo)
.AddFile(ssl_certificate)
.AddFile(ssl_key)
.AddFile(ca_certificates);
@ -52,9 +54,10 @@ class CurlSapiSandboxEx3 : public curl::CurlSapiSandbox {
std::string ca_certificates;
};
absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
std::string ssl_key_password,
std::string ca_certificates) {
absl::Status Example3(const std::string& ssl_certificate,
const std::string& ssl_key,
const std::string& ssl_key_password,
const std::string& ca_certificates) {
// Initialize sandbox2 and sapi
CurlSapiSandboxEx3 sandbox(ssl_certificate, ssl_key, ca_certificates);
SAPI_RETURN_IF_ERROR(sandbox.Init());
@ -65,8 +68,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_global_init failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_global_init failed: ", curl::StrError(&api, curl_code)));
}
// Initialize curl easy handle
@ -74,7 +77,7 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
sapi::v::RemotePtr curl(curl_handle);
if (!curl_handle) {
return absl::UnavailableError("curl_easy_init failed: curl is NULL");
return absl::UnavailableError("curl_easy_init failed: Invalid curl handle");
}
// Specify URL to get (using HTTPS)
@ -83,8 +86,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
curl_code,
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set the SSL certificate type to "PEM"
@ -93,8 +96,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLCERTTYPE,
ssl_cert_type.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set the certificate for client authentication
@ -103,8 +106,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLCERT,
sapi_ssl_certificate.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set the private key for client authentication
@ -113,8 +116,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLKEY,
sapi_ssl_key.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set the password used to protect the private key
@ -123,8 +126,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_KEYPASSWD,
sapi_ssl_key_password.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Set the file with the certificates vaildating the server
@ -133,8 +136,8 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_CAINFO,
sapi_ca_certificates.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Verify the authenticity of the server
@ -142,15 +145,15 @@ absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
curl_code,
api.curl_easy_setopt_long(&curl, curl::CURLOPT_SSL_VERIFYPEER, 1L));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_long failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_long failed: ", curl::StrError(&api, curl_code)));
}
// Perform the request
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_perform failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_perform failed: ", curl::StrError(&api, curl_code)));
}
// Cleanup curl easy handle

View File

@ -17,10 +17,11 @@
#include <cstdlib>
#include "../sandbox.h" // NOLINT(build/include)
#include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/util/flag.h"
#include "../curl_util.h" // NOLINT(build/include)
#include "../sandbox.h" // NOLINT(build/include)
#include "absl/strings/str_cat.h"
#include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/util/status_macros.h"
namespace {
@ -38,8 +39,8 @@ absl::Status Example4() {
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_global_init failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_global_init failed: ", curl::StrError(&api, curl_code)));
}
// Initialize http_handle
@ -47,7 +48,7 @@ absl::Status Example4() {
SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
sapi::v::RemotePtr http_handle(curl_handle);
if (!curl_handle) {
return absl::UnavailableError("curl_easy_init failed: curl is NULL");
return absl::UnavailableError("curl_easy_init failed: Invalid curl handle");
}
// Specify URL to get
@ -56,8 +57,8 @@ absl::Status Example4() {
curl_code, api.curl_easy_setopt_ptr(&http_handle, curl::CURLOPT_URL,
url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Initialize multi_handle
@ -66,15 +67,15 @@ absl::Status Example4() {
sapi::v::RemotePtr multi_handle(curlm_handle);
if (!curlm_handle) {
return absl::UnavailableError(
"curl_multi_init failed: multi_handle is NULL");
"curl_multi_init failed: multi_handle is invalid");
}
// Add http_handle to the multi stack
SAPI_ASSIGN_OR_RETURN(curl_code,
api.curl_multi_add_handle(&multi_handle, &http_handle));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_multi_add_handle failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_multi_add_handle failed: ", curl::StrError(&api, curl_code)));
}
while (still_running.GetValue()) {
@ -85,8 +86,8 @@ absl::Status Example4() {
curl_code,
api.curl_multi_perform(&multi_handle, still_running.PtrBoth()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_mutli_perform failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_mutli_perform failed: ", curl::StrError(&api, curl_code)));
}
if (still_running.GetValue()) {
@ -96,8 +97,8 @@ absl::Status Example4() {
curl_code, api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0, 1000,
numfds.PtrBoth()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_multi_poll_sapi failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_multi_poll_sapi failed: ", curl::StrError(&api, curl_code)));
}
}
}
@ -106,8 +107,8 @@ absl::Status Example4() {
SAPI_ASSIGN_OR_RETURN(
curl_code, api.curl_multi_remove_handle(&multi_handle, &http_handle));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_multi_remove_handle failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_multi_remove_handle failed: ", curl::StrError(&api, curl_code)));
}
// Cleanup http_handle
@ -116,8 +117,8 @@ absl::Status Example4() {
// Cleanup multi_handle
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_multi_cleanup(&multi_handle));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_multi_cleanup failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_multi_cleanup failed: ", curl::StrError(&api, curl_code)));
}
// Cleanup curl

View File

@ -19,8 +19,11 @@
#include <future> // NOLINT(build/c++11)
#include <thread> // NOLINT(build/c++11)
#include "../sandbox.h" // NOLINT(build/include)
#include "../curl_util.h" // NOLINT(build/include)
#include "../sandbox.h" // NOLINT(build/include)
#include "absl/strings/str_cat.h"
#include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/util/status_macros.h"
namespace {
@ -30,7 +33,7 @@ absl::Status pull_one_url(const std::string& url, curl::CurlApi& api) {
SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
sapi::v::RemotePtr curl(curl_handle);
if (!curl_handle) {
return absl::UnavailableError("curl_easy_init failed: curl is NULL");
return absl::UnavailableError("curl_easy_init failed: Invalid curl handle");
}
int curl_code;
@ -41,15 +44,15 @@ absl::Status pull_one_url(const std::string& url, curl::CurlApi& api) {
curl_code,
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, sapi_url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_setopt_ptr failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_setopt_ptr failed: ", curl::StrError(&api, curl_code)));
}
// Perform the request
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_easy_perform failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_easy_perform failed: ", curl::StrError(&api, curl_code)));
}
// Cleanup curl easy handle
@ -58,10 +61,6 @@ absl::Status pull_one_url(const std::string& url, curl::CurlApi& api) {
return absl::OkStatus();
}
const std::vector<std::string> urls = {
"http://example.com", "http://example.edu", "http://example.net",
"http://example.org"};
absl::Status Example5() {
// Initialize sandbox2 and sapi
curl::CurlSapiSandbox sandbox;
@ -73,11 +72,14 @@ absl::Status Example5() {
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
if (curl_code != 0) {
return absl::UnavailableError(
absl::StrCat("curl_global_init failed: ", curl_code));
return absl::UnavailableError(absl::StrCat(
"curl_global_init failed: ", curl::StrError(&api, curl_code)));
}
// Create the threads (by using futures)
const std::vector<std::string> urls = {
"http://example.com", "http://example.edu", "http://example.net",
"http://example.org"};
std::vector<std::future<absl::Status>> futures;
for (auto& url : urls) {
futures.emplace_back(

View File

@ -17,8 +17,12 @@
#include <cstdlib>
#include "../sandbox.h" // NOLINT(build/include)
#include "../curl_util.h" // NOLINT(build/include)
#include "../sandbox.h" // NOLINT(build/include)
#include "absl/strings/str_cat.h"
#include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/transaction.h"
#include "sandboxed_api/util/status_macros.h"
namespace {

View File

@ -29,16 +29,17 @@ namespace curl {
class CurlSapiSandbox : public curl::CurlSandbox {
protected:
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
sandbox2::PolicyBuilder* policy_builder) override {
sandbox2::PolicyBuilder*) override {
// Return a new policy
return sandbox2::PolicyBuilder()
.AllowDynamicStartup()
.AllowExit()
.AllowFork()
.AllowFutexOp(FUTEX_WAIT_PRIVATE)
.AllowFutexOp(FUTEX_WAKE_PRIVATE)
.AllowFutexOp(FUTEX_REQUEUE_PRIVATE)
.AllowMmap()
.AllowOpen()
.AllowRead()
.AllowSafeFcntl()
.AllowWrite()
.AllowAccess()
@ -62,6 +63,7 @@ class CurlSapiSandbox : public curl::CurlSandbox {
__NR_socket,
__NR_sysinfo,
})
.AddDirectory("/lib")
.AllowUnrestrictedNetworking()
.BuildOrDie();
}