Add namespaces and improve error handling in examples

This commit is contained in:
Federico Stazi 2020-09-29 13:50:13 +00:00
parent 0b1951ea4c
commit fec2124ee1
15 changed files with 380 additions and 332 deletions

6
.gitmodules vendored
View File

@ -4,9 +4,9 @@
[submodule "oss-internship-2020/pffft/master"] [submodule "oss-internship-2020/pffft/master"]
path = oss-internship-2020/pffft/master path = oss-internship-2020/pffft/master
url = https://bitbucket.org/jpommier/pffft/src/master/ url = https://bitbucket.org/jpommier/pffft/src/master/
[submodule "oss-internship-2020/curl/curl_wrapper/curl"]
path = oss-internship-2020/curl/curl_wrapper/curl
url = https://github.com/curl/curl
[submodule "oss-internship-2020/gdal/gdal"] [submodule "oss-internship-2020/gdal/gdal"]
path = oss-internship-2020/gdal/gdal path = oss-internship-2020/gdal/gdal
url = https://github.com/OSGeo/gdal/tree/master/gdal url = https://github.com/OSGeo/gdal/tree/master/gdal
[submodule "oss-internship-2020/curl/curl_wrapper/curl"]
path = oss-internship-2020/curl/curl_wrapper/curl
url = git@github.com:curl/curl.git

View File

@ -12,15 +12,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.12)
project(libcurl_sandbox) project(libcurl_sandbox)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
option(CURL_SAPI_ENABLE_EXAMPLES "" ON) option(SAPI_CURL_ENABLE_EXAMPLES "" ON)
option(CURL_SAPI_ENABLE_TESTS "" ON) option(SAPI_CURL_ENABLE_TESTS "" ON)
# Add callbacks used by examples and tests # Add callbacks used by examples and tests
if (CURL_SAPI_ENABLE_EXAMPLES OR CURL_SAPI_ENABLE_TESTS) if (CURL_SAPI_ENABLE_EXAMPLES OR CURL_SAPI_ENABLE_TESTS)
@ -35,8 +35,8 @@ add_subdirectory(curl_wrapper)
# Setup Sandboxed API # Setup Sandboxed API
set(SAPI_ROOT "" CACHE PATH "Path to the Sandboxed API source tree") set(SAPI_ROOT "" CACHE PATH "Path to the Sandboxed API source tree")
set(SAPI_ENABLE_EXAMPLES ${CURL_SAPI_ENABLE_EXAMPLES} CACHE BOOL "" FORCE) set(SAPI_ENABLE_EXAMPLES ${SAPI_CURL_ENABLE_EXAMPLES} CACHE BOOL "" FORCE)
set(SAPI_ENABLE_TESTS ${CURL_SAPI_ENABLE_TESTS} CACHE BOOL "" FORCE) set(SAPI_ENABLE_TESTS ${SAPI_CURL_ENABLE_TESTS} CACHE BOOL "" FORCE)
add_subdirectory( add_subdirectory(
"${SAPI_ROOT}" "${SAPI_ROOT}"
"${CMAKE_BINARY_DIR}/sandboxed-api-build" "${CMAKE_BINARY_DIR}/sandboxed-api-build"
@ -125,7 +125,7 @@ add_sapi_library(curl_sapi
LIBRARY_NAME Curl LIBRARY_NAME Curl
NAMESPACE "" NAMESPACE curl
) )
# Include generated SAPI header # Include generated SAPI header
@ -134,11 +134,11 @@ target_include_directories(curl_sapi INTERFACE
) )
# Add examples # Add examples
if (CURL_SAPI_ENABLE_EXAMPLES) if (SAPI_CURL_ENABLE_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
endif() endif()
# Add tests # Add tests
if (CURL_SAPI_ENABLE_TESTS) if (SAPI_CURL_ENABLE_TESTS)
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef TESTS_CALLBACKS_H #ifndef CALLBACKS_H_
#define TESTS_CALLBACKS_H #define CALLBACKS_H_
#include <curl/curl.h> #include <curl/curl.h>
@ -21,4 +21,4 @@
extern "C" size_t WriteToMemory(char* contents, size_t size, size_t num_bytes, extern "C" size_t WriteToMemory(char* contents, size_t size, size_t num_bytes,
void* userp); void* userp);
#endif // TESTS_CALLBACKS_H #endif // CALLBACKS_H_

@ -1 +1 @@
Subproject commit cbe7fad20d969626a5c4eb0501a273dfe812bcd3 Subproject commit a87cca7b1cbec0b4206b2bb1cb074a8a4a5bd151

View File

@ -14,8 +14,8 @@
// Wrapper for curl library // Wrapper for curl library
#ifndef CURL_WRAPPER_H #ifndef CURL_WRAPPER_H_
#define CURL_WRAPPER_H #define CURL_WRAPPER_H_
#include <curl/curl.h> #include <curl/curl.h>
@ -77,6 +77,7 @@ CURLSHcode curl_share_setopt_ptr(CURLSH* handle, CURLSHoption option,
// The wrapper method is needed to make the variadic argument explicit // The wrapper method is needed to make the variadic argument explicit
CURLSHcode curl_share_setopt_long(CURLSH* handle, CURLSHoption option, CURLSHcode curl_share_setopt_long(CURLSH* handle, CURLSHoption option,
long parameter); long parameter);
}
#endif // CURL_WRAPPER_H } // extern "C"
#endif // CURL_WRAPPER_H_

View File

@ -19,59 +19,70 @@
#include "../sandbox.h" // NOLINT(build/include) #include "../sandbox.h" // NOLINT(build/include)
namespace {
absl::Status Example1() {
// Initialize sandbox2 and sapi
curl::CurlSapiSandbox sandbox;
SAPI_RETURN_IF_ERROR(sandbox.Init());
curl::CurlApi api(&sandbox);
// Initialize the curl session
curl::CURL* curl_handle;
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");
}
int curl_code;
// Specify URL to get
sapi::v::ConstCStr url("http://example.com");
SAPI_ASSIGN_OR_RETURN(
curl_code,
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
}
// Set the library to follow a redirection
SAPI_ASSIGN_OR_RETURN(
curl_code,
api.curl_easy_setopt_long(&curl, curl::CURLOPT_FOLLOWLOCATION, 1l));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_long failed: " + curl_code);
}
// Disable authentication of peer certificate
SAPI_ASSIGN_OR_RETURN(
curl_code,
api.curl_easy_setopt_long(&curl, curl::CURLOPT_SSL_VERIFYPEER, 0l));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_long failed: " + curl_code);
}
// Perform the request
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_perform failed: " + curl_code);
}
// Cleanup curl
SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
return absl::OkStatus();
}
} // namespace
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
absl::Status status; if (absl::Status status = Example1(); !status.ok()) {
LOG(ERROR) << "Example1 failed: " << status.ToString();
// Initialize sandbox2 and sapi return EXIT_FAILURE;
CurlSapiSandbox sandbox;
status = sandbox.Init();
if (!status.ok()) {
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
}
CurlApi api(&sandbox);
// Initialize the curl session
absl::StatusOr<CURL*> curl_handle = api.curl_easy_init();
if (!curl_handle.ok()) {
LOG(FATAL) << "curl_easy_init failed: " << curl_handle.status();
}
sapi::v::RemotePtr curl(curl_handle.value());
if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
absl::StatusOr<int> curl_code;
// Specify URL to get
sapi::v::ConstCStr url("http://example.com");
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
}
// Set the library to follow a redirection
curl_code = api.curl_easy_setopt_long(&curl, CURLOPT_FOLLOWLOCATION, 1l);
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
LOG(FATAL) << "curl_easy_setopt_long failed: " << curl_code.status();
}
// Disable authentication of peer certificate
curl_code = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 0l);
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
LOG(FATAL) << "curl_easy_setopt_long failed: " << curl_code.status();
}
// Perform the request
curl_code = api.curl_easy_perform(&curl);
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
LOG(FATAL) << "curl_easy_perform failed: " << curl_code.status();
}
// Cleanup curl
status = api.curl_easy_cleanup(&curl);
if (!status.ok()) {
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -20,87 +20,90 @@
#include "../sandbox.h" // NOLINT(build/include) #include "../sandbox.h" // NOLINT(build/include)
int main(int argc, char* argv[]) { namespace {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status;
absl::Status Example2() {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandbox sandbox; curl::CurlSapiSandbox sandbox;
status = sandbox.Init(); SAPI_RETURN_IF_ERROR(sandbox.Init());
if (!status.ok()) { curl::CurlApi api(&sandbox);
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
}
CurlApi api(&sandbox);
// Generate pointer to WriteMemoryCallback function // Generate pointer to WriteMemoryCallback function
void* function_ptr; void* function_ptr;
status = sandbox.rpc_channel()->Symbol("WriteToMemory", &function_ptr); SAPI_RETURN_IF_ERROR(
if (!status.ok()) { sandbox.rpc_channel()->Symbol("WriteToMemory", &function_ptr));
LOG(FATAL) << "sapi::Sandbox::rpc_channel().Symbol failed: " << status; sapi::v::RemotePtr write_to_memory(function_ptr);
}
sapi::v::RemotePtr remote_function_ptr(function_ptr);
// Initialize the curl session // Initialize the curl session
absl::StatusOr<CURL*> curl_handle = api.curl_easy_init(); curl::CURL* curl_handle;
if (!curl_handle.ok()) { SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
LOG(FATAL) << "curl_easy_init failed: " << curl_handle.status(); sapi::v::RemotePtr curl(curl_handle);
} if (!curl_handle) {
sapi::v::RemotePtr curl(curl_handle.value()); return absl::UnavailableError("curl_easy_init failed: curl is NULL");
if (!curl.GetValue()) {
LOG(FATAL) << "curl_easy_init failed: curl is NULL";
} }
absl::StatusOr<int> curl_code; int curl_code;
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr url("http://example.com"); sapi::v::ConstCStr url("http://example.com");
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()); SAPI_ASSIGN_OR_RETURN(
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { curl_code,
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set WriteMemoryCallback as the write function // Set WriteMemoryCallback as the write function
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEFUNCTION, SAPI_ASSIGN_OR_RETURN(
&remote_function_ptr); curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEFUNCTION,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { &write_to_memory));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Pass 'chunk' struct to the callback function // Pass 'chunk' struct to the callback function
sapi::v::LenVal chunk(0); sapi::v::LenVal chunk(0);
curl_code = SAPI_ASSIGN_OR_RETURN(curl_code,
api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEDATA, chunk.PtrBoth()); api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEDATA,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { chunk.PtrBoth()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set a user agent // Set a user agent
sapi::v::ConstCStr user_agent("libcurl-agent/1.0"); sapi::v::ConstCStr user_agent("libcurl-agent/1.0");
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_USERAGENT, SAPI_ASSIGN_OR_RETURN(curl_code,
user_agent.PtrBefore()); api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_USERAGENT,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { user_agent.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Perform the request // Perform the request
curl_code = api.curl_easy_perform(&curl); SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { if (curl_code != 0) {
LOG(FATAL) << "curl_easy_perform failed: " << curl_code.status(); return absl::UnavailableError("curl_easy_perform failed: " + curl_code);
} }
// Retrieve memory size // Retrieve memory size
status = sandbox.TransferFromSandboxee(&chunk); SAPI_RETURN_IF_ERROR(sandbox.TransferFromSandboxee(&chunk));
if (!status.ok()) {
LOG(FATAL) << "sandbox.TransferFromSandboxee failed: " << status;
}
std::cout << "memory size: " << chunk.GetDataSize() << " bytes" << std::endl; std::cout << "memory size: " << chunk.GetDataSize() << " bytes" << std::endl;
// Cleanup curl // Cleanup curl
status = api.curl_easy_cleanup(&curl); SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
if (!status.ok()) {
LOG(FATAL) << "curl_easy_cleanup failed: " << status; return absl::OkStatus();
}
} // namespace
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
if (absl::Status status = Example2(); !status.ok()) {
LOG(ERROR) << "Example2 failed: " << status.ToString();
return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -19,7 +19,9 @@
#include "../sandbox.h" // NOLINT(build/include) #include "../sandbox.h" // NOLINT(build/include)
class CurlSapiSandboxEx3 : public CurlSapiSandbox { namespace {
class CurlSapiSandboxEx3 : public curl::CurlSapiSandbox {
public: public:
CurlSapiSandboxEx3(std::string ssl_certificate, std::string ssl_key, CurlSapiSandboxEx3(std::string ssl_certificate, std::string ssl_key,
std::string ca_certificates) std::string ca_certificates)
@ -42,7 +44,7 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
.AddFile(ssl_key) .AddFile(ssl_key)
.AddFile(ca_certificates); .AddFile(ca_certificates);
// Provide the new PolicyBuilder to ModifyPolicy in CurlSandbox // Provide the new PolicyBuilder to ModifyPolicy in CurlSandbox
return CurlSapiSandbox::ModifyPolicy(policy_builder.get()); return curl::CurlSapiSandbox::ModifyPolicy(policy_builder.get());
} }
std::string ssl_certificate; std::string ssl_certificate;
@ -50,116 +52,123 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
std::string ca_certificates; std::string ca_certificates;
}; };
int main(int argc, char* argv[]) { absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
gflags::ParseCommandLineFlags(&argc, &argv, true); std::string ssl_key_password,
google::InitGoogleLogging(argv[0]); std::string ca_certificates) {
absl::Status status;
// Get input parameters (should be absolute paths)
if (argc != 5) {
LOG(FATAL) << "wrong number of arguments (4 expected)";
}
std::string ssl_certificate = argv[1];
std::string ssl_key = argv[2];
std::string ssl_key_password = argv[3];
std::string ca_certificates = argv[4];
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandboxEx3 sandbox(ssl_certificate, ssl_key, ca_certificates); CurlSapiSandboxEx3 sandbox(ssl_certificate, ssl_key, ca_certificates);
status = sandbox.Init(); SAPI_RETURN_IF_ERROR(sandbox.Init());
if (!status.ok()) { curl::CurlApi api(&sandbox);
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
}
CurlApi api(&sandbox);
absl::StatusOr<int> curl_code; int curl_code;
// Initialize curl (CURL_GLOBAL_DEFAULT = 3) // Initialize curl (CURL_GLOBAL_DEFAULT = 3)
curl_code = api.curl_global_init(3l); SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { if (curl_code != 0) {
LOG(FATAL) << "curl_global_init failed: " << curl_code.status(); return absl::UnavailableError("curl_global_init failed: " + curl_code);
} }
// Initialize curl easy handle // Initialize curl easy handle
absl::StatusOr<CURL*> curl_handle = api.curl_easy_init(); curl::CURL* curl_handle;
if (!curl_handle.ok()) { SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
LOG(FATAL) << "curl_easy_init failed: " << curl_handle.status(); sapi::v::RemotePtr curl(curl_handle);
} if (!curl_handle) {
sapi::v::RemotePtr curl(curl_handle.value()); return absl::UnavailableError("curl_easy_init failed: curl is NULL");
if (!curl.GetValue()) {
LOG(FATAL) << "curl_easy_init failed: curl is NULL";
} }
// Specify URL to get (using HTTPS) // Specify URL to get (using HTTPS)
sapi::v::ConstCStr url("https://example.com"); sapi::v::ConstCStr url("https://example.com");
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()); SAPI_ASSIGN_OR_RETURN(
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { curl_code,
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set the SSL certificate type to "PEM" // Set the SSL certificate type to "PEM"
sapi::v::ConstCStr ssl_cert_type("PEM"); sapi::v::ConstCStr ssl_cert_type("PEM");
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERTTYPE, SAPI_ASSIGN_OR_RETURN(
ssl_cert_type.PtrBefore()); curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLCERTTYPE,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { ssl_cert_type.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set the certificate for client authentication // Set the certificate for client authentication
sapi::v::ConstCStr sapi_ssl_certificate(ssl_certificate.c_str()); sapi::v::ConstCStr sapi_ssl_certificate(ssl_certificate.c_str());
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERT, SAPI_ASSIGN_OR_RETURN(
sapi_ssl_certificate.PtrBefore()); curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLCERT,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { sapi_ssl_certificate.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set the private key for client authentication // Set the private key for client authentication
sapi::v::ConstCStr sapi_ssl_key(ssl_key.c_str()); sapi::v::ConstCStr sapi_ssl_key(ssl_key.c_str());
curl_code = SAPI_ASSIGN_OR_RETURN(curl_code,
api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLKEY, sapi_ssl_key.PtrBefore()); api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLKEY,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { sapi_ssl_key.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set the password used to protect the private key // Set the password used to protect the private key
sapi::v::ConstCStr sapi_ssl_key_password(ssl_key_password.c_str()); sapi::v::ConstCStr sapi_ssl_key_password(ssl_key_password.c_str());
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_KEYPASSWD, SAPI_ASSIGN_OR_RETURN(
sapi_ssl_key_password.PtrBefore()); curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_KEYPASSWD,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { sapi_ssl_key_password.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Set the file with the certificates vaildating the server // Set the file with the certificates vaildating the server
sapi::v::ConstCStr sapi_ca_certificates(ca_certificates.c_str()); sapi::v::ConstCStr sapi_ca_certificates(ca_certificates.c_str());
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_CAINFO, SAPI_ASSIGN_OR_RETURN(
sapi_ca_certificates.PtrBefore()); curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_CAINFO,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { sapi_ca_certificates.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Verify the authenticity of the server // Verify the authenticity of the server
curl_code = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 1L); SAPI_ASSIGN_OR_RETURN(
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { curl_code,
LOG(FATAL) << "curl_easy_setopt_long failed: " << curl_code.status(); api.curl_easy_setopt_long(&curl, curl::CURLOPT_SSL_VERIFYPEER, 1L));
if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_long failed: " + curl_code);
} }
// Perform the request // Perform the request
curl_code = api.curl_easy_perform(&curl); SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { if (curl_code != 0) {
LOG(FATAL) << "curl_easy_perform failed: " << curl_code.status(); return absl::UnavailableError("curl_easy_perform failed: " + curl_code);
} }
// Cleanup curl easy handle // Cleanup curl easy handle
status = api.curl_easy_cleanup(&curl); SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
if (!status.ok()) {
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
}
// Cleanup curl // Cleanup curl
status = api.curl_global_cleanup(); SAPI_RETURN_IF_ERROR(api.curl_global_cleanup());
if (!status.ok()) {
LOG(FATAL) << "curl_global_cleanup failed: " << status; return absl::OkStatus();
}
} // namespace
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
// Get input parameters (should be absolute paths)
if (argc != 5) {
LOG(ERROR) << "wrong number of arguments (4 expected)";
return EXIT_FAILURE;
}
if (absl::Status status = Example3(argv[1], argv[2], argv[3], argv[4]);
!status.ok()) {
LOG(ERROR) << "Example3 failed: " << status.ToString();
return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -21,107 +21,114 @@
#include "curl_sapi.sapi.h" // NOLINT(build/include) #include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/util/flag.h" #include "sandboxed_api/util/flag.h"
int main(int argc, char* argv[]) { namespace {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status;
absl::Status Example4() {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandbox sandbox; curl::CurlSapiSandbox sandbox;
status = sandbox.Init(); SAPI_RETURN_IF_ERROR(sandbox.Init());
if (!status.ok()) { curl::CurlApi api(&sandbox);
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
}
CurlApi api(&sandbox);
// Number of running handles // Number of running handles
sapi::v::Int still_running(1); sapi::v::Int still_running(1);
absl::StatusOr<int> curl_code; int curl_code;
// Initialize curl (CURL_GLOBAL_DEFAULT = 3) // Initialize curl (CURL_GLOBAL_DEFAULT = 3)
curl_code = api.curl_global_init(3l); SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { if (curl_code != 0) {
LOG(FATAL) << "curl_global_init failed: " << curl_code.status(); return absl::UnavailableError("curl_global_init failed: " + curl_code);
} }
// Initialize http_handle // Initialize http_handle
absl::StatusOr<CURL*> curl_handle = api.curl_easy_init(); curl::CURL* curl_handle;
if (!curl_handle.ok()) { SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
LOG(FATAL) << "curl_easy_init failed: " << curl_handle.status(); sapi::v::RemotePtr http_handle(curl_handle);
} if (!curl_handle) {
sapi::v::RemotePtr http_handle(curl_handle.value()); return absl::UnavailableError("curl_easy_init failed: curl is NULL");
if (!http_handle.GetValue()) {
LOG(FATAL) << "curl_easy_init failed: http_handle is NULL";
} }
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr url("http://example.com"); sapi::v::ConstCStr url("http://example.com");
curl_code = SAPI_ASSIGN_OR_RETURN(
api.curl_easy_setopt_ptr(&http_handle, CURLOPT_URL, url.PtrBefore()); curl_code, api.curl_easy_setopt_ptr(&http_handle, curl::CURLOPT_URL,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { url.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Initialize multi_handle // Initialize multi_handle
absl::StatusOr<CURLM*> curlm_handle = api.curl_multi_init(); curl::CURLM* curlm_handle;
if (!curlm_handle.ok()) { SAPI_ASSIGN_OR_RETURN(curlm_handle, api.curl_multi_init());
LOG(FATAL) << "curl_multi_init failed: " << curlm_handle.status(); sapi::v::RemotePtr multi_handle(curlm_handle);
} if (!curlm_handle) {
sapi::v::RemotePtr multi_handle(curlm_handle.value()); return absl::UnavailableError(
if (!multi_handle.GetValue()) { "curl_multi_init failed: multi_handle is NULL");
LOG(FATAL) << "curl_multi_init failed: multi_handle is NULL";
} }
// Add http_handle to the multi stack // Add http_handle to the multi stack
curl_code = api.curl_multi_add_handle(&multi_handle, &http_handle); SAPI_ASSIGN_OR_RETURN(curl_code,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { api.curl_multi_add_handle(&multi_handle, &http_handle));
LOG(FATAL) << "curl_multi_add_handle failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_multi_add_handle failed: " + curl_code);
} }
while (still_running.GetValue()) { while (still_running.GetValue()) {
sapi::v::Int numfds(0); sapi::v::Int numfds(0);
// Perform the request // Perform the request
curl_code = api.curl_multi_perform(&multi_handle, still_running.PtrBoth()); SAPI_ASSIGN_OR_RETURN(
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { curl_code,
LOG(FATAL) << "curl_mutli_perform failed: " << curl_code.status(); api.curl_multi_perform(&multi_handle, still_running.PtrBoth()));
if (curl_code != 0) {
return absl::UnavailableError("curl_mutli_perform failed: " + curl_code);
} }
if (still_running.GetValue()) { if (still_running.GetValue()) {
// Wait for an event or timeout // Wait for an event or timeout
sapi::v::NullPtr null_ptr; sapi::v::NullPtr null_ptr;
curl_code = api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0, 1000, SAPI_ASSIGN_OR_RETURN(
numfds.PtrBoth()); curl_code, api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0, 1000,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { numfds.PtrBoth()));
LOG(FATAL) << "curl_multi_poll_sapi failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_multi_poll_sapi failed: " +
curl_code);
} }
} }
} }
// Remove http_handle from the multi stack // Remove http_handle from the multi stack
curl_code = api.curl_multi_remove_handle(&multi_handle, &http_handle); SAPI_ASSIGN_OR_RETURN(
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { curl_code, api.curl_multi_remove_handle(&multi_handle, &http_handle));
LOG(FATAL) << "curl_multi_remove_handle failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_multi_remove_handle failed: " +
curl_code);
} }
// Cleanup http_handle // Cleanup http_handle
status = api.curl_easy_cleanup(&http_handle); SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&http_handle));
if (!status.ok()) {
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
}
// Cleanup multi_handle // Cleanup multi_handle
curl_code = api.curl_multi_cleanup(&multi_handle); SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_multi_cleanup(&multi_handle));
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { if (curl_code != 0) {
LOG(FATAL) << "curl_multi_cleanup failed: " << curl_code.status(); return absl::UnavailableError("curl_multi_cleanup failed: " + curl_code);
} }
// Cleanup curl // Cleanup curl
status = api.curl_global_cleanup(); SAPI_RETURN_IF_ERROR(api.curl_global_cleanup());
if (!status.ok()) {
LOG(FATAL) << "curl_global_cleanup failed: " << status; return absl::OkStatus();
}
} // namespace
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
if (absl::Status status = Example4(); !status.ok()) {
LOG(ERROR) << "Example4 failed: " << status.ToString();
return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -15,87 +15,91 @@
// Sandboxed version of multithread.c // Sandboxed version of multithread.c
// Multithreaded HTTP GET requests // Multithreaded HTTP GET requests
#include <pthread.h>
#include <cstdlib> #include <cstdlib>
#include <future>
#include <thread>
#include "../sandbox.h" // NOLINT(build/include) #include "../sandbox.h" // NOLINT(build/include)
void pull_one_url(const std::string& url, CurlApi& api) { namespace {
absl::Status pull_one_url(const std::string& url, curl::CurlApi& api) {
// Initialize the curl session // Initialize the curl session
absl::StatusOr<CURL*> curl_handle = api.curl_easy_init(); curl::CURL* curl_handle;
if (!curl_handle.ok()) { SAPI_ASSIGN_OR_RETURN(curl_handle, api.curl_easy_init());
LOG(FATAL) << "curl_easy_init failed: " << curl_handle.status(); sapi::v::RemotePtr curl(curl_handle);
} if (!curl_handle) {
sapi::v::RemotePtr curl(curl_handle.value()); return absl::UnavailableError("curl_easy_init failed: curl is NULL");
if (!curl.GetValue()) {
LOG(FATAL) << "curl_easy_init failed: curl is NULL";
} }
absl::StatusOr<int> curl_code; int curl_code;
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr sapi_url(url.c_str()); sapi::v::ConstCStr sapi_url(url.c_str());
curl_code = SAPI_ASSIGN_OR_RETURN(
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, sapi_url.PtrBefore()); curl_code,
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, sapi_url.PtrBefore()));
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status(); if (curl_code != 0) {
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
} }
// Perform the request // Perform the request
curl_code = api.curl_easy_perform(&curl); SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
if (!curl_code.ok() || curl_code.value() != CURLE_OK) { if (curl_code != 0) {
LOG(FATAL) << "curl_easy_perform failed: " << curl_code.status(); return absl::UnavailableError("curl_easy_perform failed: " + curl_code);
} }
// Cleanup curl // Cleanup curl easy handle
absl::Status status = api.curl_easy_cleanup(&curl); SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
if (!status.ok()) {
LOG(FATAL) << "curl_easy_cleanup failed: " << status; return absl::OkStatus();
}
} }
const std::vector<std::string> urls = { const std::vector<std::string> urls = {
"http://example.com", "http://example.edu", "http://example.net", "http://example.com", "http://example.edu", "http://example.net",
"http://example.org"}; "http://example.org"};
absl::Status Example5() {
// Initialize sandbox2 and sapi
curl::CurlSapiSandbox sandbox;
SAPI_RETURN_IF_ERROR(sandbox.Init());
curl::CurlApi api(&sandbox);
int curl_code;
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
if (curl_code != 0) {
return absl::UnavailableError("curl_global_init failed: " + curl_code);
}
// Create the threads (by using futures)
std::vector<std::future<absl::Status>> futures;
for (auto& url : urls) {
futures.emplace_back(
std::async(pull_one_url, std::ref(url), std::ref(api)));
}
// Join the threads and check for errors
for (auto& future : futures) {
SAPI_RETURN_IF_ERROR(future.get());
}
// Cleanup curl
SAPI_RETURN_IF_ERROR(api.curl_global_cleanup());
return absl::OkStatus();
}
} // namespace
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
absl::Status status; if (absl::Status status = Example5(); !status.ok()) {
LOG(ERROR) << "Example5 failed: " << status.ToString();
// Initialize sandbox2 and sapi return EXIT_FAILURE;
CurlSapiSandbox sandbox;
status = sandbox.Init();
if (!status.ok()) {
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
}
CurlApi api(&sandbox);
absl::StatusOr<int> curl_code;
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
curl_code = api.curl_global_init(3l);
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
LOG(FATAL) << "curl_global_init failed: " << curl_code.status();
}
// Create the threads
std::vector<std::thread> threads;
for (auto& url : urls) {
threads.emplace_back(pull_one_url, std::ref(url), std::ref(api));
}
// Join the threads
for (auto& thread : threads) {
thread.join();
}
// Cleanup curl
status = api.curl_global_cleanup();
if (!status.ok()) {
LOG(FATAL) << "curl_global_cleanup failed: " << status;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -20,6 +20,8 @@
#include "../sandbox.h" // NOLINT(build/include) #include "../sandbox.h" // NOLINT(build/include)
#include "sandboxed_api/transaction.h" #include "sandboxed_api/transaction.h"
namespace {
class CurlTransaction : public sapi::Transaction { class CurlTransaction : public sapi::Transaction {
public: public:
explicit CurlTransaction(std::unique_ptr<sapi::Sandbox> sandbox) explicit CurlTransaction(std::unique_ptr<sapi::Sandbox> sandbox)
@ -36,7 +38,7 @@ class CurlTransaction : public sapi::Transaction {
}; };
absl::Status CurlTransaction::Main() { absl::Status CurlTransaction::Main() {
CurlApi api(sandbox()); curl::CurlApi api(sandbox());
// Initialize the curl session // Initialize the curl session
SAPI_ASSIGN_OR_RETURN(void* curl_remote, api.curl_easy_init()); SAPI_ASSIGN_OR_RETURN(void* curl_remote, api.curl_easy_init());
@ -47,13 +49,13 @@ absl::Status CurlTransaction::Main() {
sapi::v::ConstCStr url("http://example.com"); sapi::v::ConstCStr url("http://example.com");
SAPI_ASSIGN_OR_RETURN( SAPI_ASSIGN_OR_RETURN(
int setopt_url_code, int setopt_url_code,
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore())); api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK, TRANSACTION_FAIL_IF_NOT(setopt_url_code == curl::CURLE_OK,
"curl_easy_setopt_ptr failed"); "curl_easy_setopt_ptr failed");
// Perform the request // Perform the request
SAPI_ASSIGN_OR_RETURN(int perform_code, api.curl_easy_perform(&curl)); SAPI_ASSIGN_OR_RETURN(int perform_code, api.curl_easy_perform(&curl));
TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK, TRANSACTION_FAIL_IF_NOT(setopt_url_code == curl::CURLE_OK,
"curl_easy_perform failed"); "curl_easy_perform failed");
// Cleanup curl // Cleanup curl
@ -63,8 +65,10 @@ absl::Status CurlTransaction::Main() {
return absl::OkStatus(); return absl::OkStatus();
} }
} // namespace
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
CurlTransaction curl{std::make_unique<CurlSapiSandbox>()}; CurlTransaction curl{std::make_unique<curl::CurlSapiSandbox>()};
absl::Status status = curl.Run(); absl::Status status = curl.Run();
CHECK(status.ok()) << "CurlTransaction failed"; CHECK(status.ok()) << "CurlTransaction failed";

View File

@ -24,7 +24,9 @@
#include "curl_sapi.sapi.h" // NOLINT(build/include) #include "curl_sapi.sapi.h" // NOLINT(build/include)
#include "sandboxed_api/sandbox2/util/bpf_helper.h" #include "sandboxed_api/sandbox2/util/bpf_helper.h"
class CurlSapiSandbox : public CurlSandbox { namespace curl {
class CurlSapiSandbox : public curl::CurlSandbox {
protected: protected:
std::unique_ptr<sandbox2::Policy> ModifyPolicy( std::unique_ptr<sandbox2::Policy> ModifyPolicy(
sandbox2::PolicyBuilder* policy_builder) override { sandbox2::PolicyBuilder* policy_builder) override {

View File

@ -28,17 +28,17 @@
int CurlTestUtils::port_; int CurlTestUtils::port_;
std::thread CurlTestUtils::server_thread_; std::thread CurlTestUtils::server_thread_;
absl::Status CurlTestUtils::CurlTestSetUp() { absl::Status curl::tests::CurlTestUtils::CurlTestSetUp() {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
sandbox_ = std::make_unique<CurlSapiSandbox>(); sandbox_ = std::make_unique<curl::CurlSapiSandbox>();
absl::Status init = sandbox_->Init(); absl::Status init = sandbox_->Init();
if (!init.ok()) { if (!init.ok()) {
return init; return init;
} }
api_ = std::make_unique<CurlApi>(sandbox_.get()); api_ = std::make_unique<curl::CurlApi>(sandbox_.get());
// Initialize curl // Initialize curl
absl::StatusOr<CURL*> curl_handle = api_->curl_easy_init(); absl::StatusOr<curl::CURL*> curl_handle = api_->curl_easy_init();
if (!curl_handle.ok()) { if (!curl_handle.ok()) {
return curl_handle.status(); return curl_handle.status();
} }
@ -51,23 +51,24 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
// Specify request URL // Specify request URL
sapi::v::ConstCStr sapi_url(kUrl.data()); sapi::v::ConstCStr sapi_url(kUrl.data());
curl_code = api_->curl_easy_setopt_ptr(curl_.get(), CURLOPT_URL, curl_code = api_->curl_easy_setopt_ptr(curl_.get(), curl::CURLOPT_URL,
sapi_url.PtrBefore()); sapi_url.PtrBefore());
if (!curl_code.ok()) { if (!curl_code.ok()) {
return curl_code.status(); return curl_code.status();
} }
if (curl_code.value() != CURLE_OK) { if (curl_code.value() != curl::CURLE_OK) {
return absl::UnavailableError( return absl::UnavailableError(
"curl_easy_setopt_ptr returned with the error code " + "curl_easy_setopt_ptr returned with the error code " +
curl_code.value()); curl_code.value());
} }
// Set port // Set port
curl_code = api_->curl_easy_setopt_long(curl_.get(), CURLOPT_PORT, port_); curl_code =
api_->curl_easy_setopt_long(curl_.get(), curl::CURLOPT_PORT, port_);
if (!curl_code.ok()) { if (!curl_code.ok()) {
return curl_code.status(); return curl_code.status();
} }
if (curl_code.value() != CURLE_OK) { if (curl_code.value() != curl::CURLE_OK) {
return absl::UnavailableError( return absl::UnavailableError(
"curl_easy_setopt_long returned with the error code " + "curl_easy_setopt_long returned with the error code " +
curl_code.value()); curl_code.value());
@ -83,12 +84,12 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
sapi::v::RemotePtr remote_function_ptr(function_ptr); sapi::v::RemotePtr remote_function_ptr(function_ptr);
// Set WriteToMemory as the write function // Set WriteToMemory as the write function
curl_code = api_->curl_easy_setopt_ptr(curl_.get(), CURLOPT_WRITEFUNCTION, curl_code = api_->curl_easy_setopt_ptr(
&remote_function_ptr); curl_.get(), curl::CURLOPT_WRITEFUNCTION, &remote_function_ptr);
if (!curl_code.ok()) { if (!curl_code.ok()) {
return curl_code.status(); return curl_code.status();
} }
if (curl_code.value() != CURLE_OK) { if (curl_code.value() != curl::CURLE_OK) {
return absl::UnavailableError( return absl::UnavailableError(
"curl_easy_setopt_ptr returned with the error code " + "curl_easy_setopt_ptr returned with the error code " +
curl_code.value()); curl_code.value());
@ -96,12 +97,12 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
// Pass memory chunk object to the callback // Pass memory chunk object to the callback
chunk_ = std::make_unique<sapi::v::LenVal>(0); chunk_ = std::make_unique<sapi::v::LenVal>(0);
curl_code = api_->curl_easy_setopt_ptr(curl_.get(), CURLOPT_WRITEDATA, curl_code = api_->curl_easy_setopt_ptr(curl_.get(), curl::CURLOPT_WRITEDATA,
chunk_->PtrBoth()); chunk_->PtrBoth());
if (!curl_code.ok()) { if (!curl_code.ok()) {
return curl_code.status(); return curl_code.status();
} }
if (curl_code.value() != CURLE_OK) { if (curl_code.value() != curl::CURLE_OK) {
return absl::UnavailableError( return absl::UnavailableError(
"curl_easy_setopt_ptr returned with the error code " + "curl_easy_setopt_ptr returned with the error code " +
curl_code.value()); curl_code.value());
@ -110,18 +111,18 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
return absl::OkStatus(); return absl::OkStatus();
} }
absl::Status CurlTestUtils::CurlTestTearDown() { absl::Status curl::tests::CurlTestUtils::CurlTestTearDown() {
// Cleanup curl // Cleanup curl
return api_->curl_easy_cleanup(curl_.get()); return api_->curl_easy_cleanup(curl_.get());
} }
absl::StatusOr<std::string> CurlTestUtils::PerformRequest() { absl::StatusOr<std::string> curl::tests::CurlTestUtils::PerformRequest() {
// Perform the request // Perform the request
absl::StatusOr<int> curl_code = api_->curl_easy_perform(curl_.get()); absl::StatusOr<int> curl_code = api_->curl_easy_perform(curl_.get());
if (!curl_code.ok()) { if (!curl_code.ok()) {
return curl_code.status(); return curl_code.status();
} }
if (curl_code.value() != CURLE_OK) { if (curl_code.value() != curl::CURLE_OK) {
return absl::UnavailableError( return absl::UnavailableError(
"curl_easy_perform returned with the error code " + curl_code.value()); "curl_easy_perform returned with the error code " + curl_code.value());
} }
@ -267,7 +268,7 @@ void ServerLoop(int listening_socket, sockaddr_in socket_address) {
} // namespace } // namespace
void CurlTestUtils::StartMockServer() { void curl::tests::CurlTestUtils::StartMockServer() {
// Get the socket file descriptor // Get the socket file descriptor
int listening_socket = socket(AF_INET, SOCK_STREAM, 0); int listening_socket = socket(AF_INET, SOCK_STREAM, 0);

View File

@ -21,6 +21,8 @@
#include "sandboxed_api/util/flag.h" #include "sandboxed_api/util/flag.h"
#include "sandboxed_api/util/status_matchers.h" #include "sandboxed_api/util/status_matchers.h"
namespace curl::tests {
// Helper class that can be used to test Curl Sandboxed // Helper class that can be used to test Curl Sandboxed
class CurlTestUtils { class CurlTestUtils {
protected: protected:
@ -39,8 +41,8 @@ class CurlTestUtils {
// Responds with the POST request fields to a POST request // Responds with the POST request fields to a POST request
static void StartMockServer(); static void StartMockServer();
std::unique_ptr<CurlSapiSandbox> sandbox_; std::unique_ptr<curl::CurlSapiSandbox> sandbox_;
std::unique_ptr<CurlApi> api_; std::unique_ptr<curl::CurlApi> api_;
std::unique_ptr<sapi::v::RemotePtr> curl_; std::unique_ptr<sapi::v::RemotePtr> curl_;
static std::thread server_thread_; static std::thread server_thread_;

View File

@ -14,7 +14,9 @@
#include "test_utils.h" // NOLINT(build/include) #include "test_utils.h" // NOLINT(build/include)
class CurlTest : public CurlTestUtils, public ::testing::Test { namespace {
class CurlTest : public curl::tests::CurlTestUtils, public ::testing::Test {
protected: protected:
void SetUp() override { void SetUp() override {
// Start mock server, get port number and check for any error // Start mock server, get port number and check for any error
@ -38,9 +40,9 @@ TEST_F(CurlTest, EffectiveUrl) {
// Get effective URL // Get effective URL
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int getinfo_code, int getinfo_code,
api_->curl_easy_getinfo_ptr(curl_.get(), CURLINFO_EFFECTIVE_URL, api_->curl_easy_getinfo_ptr(curl_.get(), curl::CURLINFO_EFFECTIVE_URL,
effective_url_ptr.PtrBoth())); effective_url_ptr.PtrBoth()));
ASSERT_EQ(getinfo_code, CURLE_OK); ASSERT_EQ(getinfo_code, curl::CURLE_OK);
// Store effective URL in a string // Store effective URL in a string
SAPI_ASSERT_OK_AND_ASSIGN(std::string effective_url, SAPI_ASSERT_OK_AND_ASSIGN(std::string effective_url,
@ -74,9 +76,9 @@ TEST_F(CurlTest, ResponseCode) {
// Get response code // Get response code
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int getinfo_code, int getinfo_code,
api_->curl_easy_getinfo_ptr(curl_.get(), CURLINFO_RESPONSE_CODE, api_->curl_easy_getinfo_ptr(curl_.get(), curl::CURLINFO_RESPONSE_CODE,
response_code.PtrBoth())); response_code.PtrBoth()));
ASSERT_EQ(getinfo_code, CURLE_OK); ASSERT_EQ(getinfo_code, curl::CURLE_OK);
// Check response code // Check response code
ASSERT_EQ(response_code.GetValue(), 200); ASSERT_EQ(response_code.GetValue(), 200);
@ -120,19 +122,21 @@ TEST_F(CurlTest, POSTResponse) {
// Set the size of the POST fields // Set the size of the POST fields
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_post_fields_size, int setopt_post_fields_size,
api_->curl_easy_setopt_long(curl_.get(), CURLOPT_POSTFIELDSIZE, api_->curl_easy_setopt_long(curl_.get(), curl::CURLOPT_POSTFIELDSIZE,
post_fields.GetSize())); post_fields.GetSize()));
ASSERT_EQ(setopt_post_fields_size, CURLE_OK); ASSERT_EQ(setopt_post_fields_size, curl::CURLE_OK);
// Set the POST fields // Set the POST fields
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_post_fields, int setopt_post_fields,
api_->curl_easy_setopt_ptr(curl_.get(), CURLOPT_POSTFIELDS, api_->curl_easy_setopt_ptr(curl_.get(), curl::CURLOPT_POSTFIELDS,
post_fields.PtrBefore())); post_fields.PtrBefore()));
ASSERT_EQ(setopt_post_fields, CURLE_OK); ASSERT_EQ(setopt_post_fields, curl::CURLE_OK);
SAPI_ASSERT_OK_AND_ASSIGN(std::string response, PerformRequest()); SAPI_ASSERT_OK_AND_ASSIGN(std::string response, PerformRequest());
// Compare response with expected response // Compare response with expected response
ASSERT_EQ(std::string(post_fields.GetData()), response); ASSERT_EQ(std::string(post_fields.GetData()), response);
} }
} // namespace