Improved error handling

This commit is contained in:
Federico Stazi 2020-08-21 16:08:10 +00:00
parent 6167cafbde
commit 9fed2ec097
9 changed files with 162 additions and 271 deletions

View File

@ -20,6 +20,9 @@
#include "../sandbox.h" #include "../sandbox.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status; absl::Status status;
sapi::StatusOr<CURL*> status_or_curl; sapi::StatusOr<CURL*> status_or_curl;
sapi::StatusOr<int> status_or_int; sapi::StatusOr<int> status_or_int;
@ -27,59 +30,41 @@ int main(int argc, char* argv[]) {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandbox sandbox; CurlSapiSandbox sandbox;
status = sandbox.Init(); status = sandbox.Init();
if (!status.ok()) { if (!status.ok())
std::cerr << "error in sandbox Init" << std::endl; LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
return EXIT_FAILURE;
}
CurlApi api(&sandbox); CurlApi api(&sandbox);
// Initialize the curl session // Initialize the curl session
status_or_curl = api.curl_easy_init(); status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) { if (!status_or_curl.ok())
std::cerr << "error in curl_easy_init" << std::endl; LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
return EXIT_FAILURE;
}
sapi::v::RemotePtr curl(status_or_curl.value()); sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) { if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr url("http://example.com"); sapi::v::ConstCStr url("http://example.com");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()); status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Set the library to follow a redirection // Set the library to follow a redirection
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_FOLLOWLOCATION, 1l); status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_FOLLOWLOCATION, 1l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_long" << std::endl; LOG(FATAL) << "curl_easy_setopt_long failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); // Disable authentication of peer certificate
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 0l); status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 0l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_long" << std::endl; LOG(FATAL) << "curl_easy_setopt_long failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Perform the request // Perform the request
status_or_int = api.curl_easy_perform(&curl); status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_perform" << std::endl; LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Cleanup curl // Cleanup curl
status = api.curl_easy_cleanup(&curl); status = api.curl_easy_cleanup(&curl);
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -25,7 +25,10 @@ struct MemoryStruct {
size_t size; size_t size;
}; };
int main() { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status; absl::Status status;
sapi::StatusOr<CURL*> status_or_curl; sapi::StatusOr<CURL*> status_or_curl;
sapi::StatusOr<int> status_or_int; sapi::StatusOr<int> status_or_int;
@ -33,91 +36,66 @@ int main() {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandbox sandbox; CurlSapiSandbox sandbox;
status = sandbox.Init(); status = sandbox.Init();
if (!status.ok()) { if (!status.ok())
std::cerr << "error in sandbox Init" << std::endl; LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
return EXIT_FAILURE;
}
CurlApi api(&sandbox); CurlApi api(&sandbox);
// Generate pointer to WriteMemoryCallback function // Generate pointer to WriteMemoryCallback function
sapi::RPCChannel rpcc(sandbox.comms()); sapi::RPCChannel rpcc(sandbox.comms());
size_t (*_function_ptr)(void*, size_t, size_t, void*); size_t (*_function_ptr)(void*, size_t, size_t, void*);
status = rpcc.Symbol("WriteMemoryCallback", (void**)&_function_ptr); status = rpcc.Symbol("WriteMemoryCallback", (void**)&_function_ptr);
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "rpcc.Symbol failed: " << status;
std::cerr << "error in RPCChannel Symbol" << std::endl;
return EXIT_FAILURE;
}
sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr); sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr);
// Initialize the curl session // Initialize the curl session
status_or_curl = api.curl_easy_init(); status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) { if (!status_or_curl.ok())
std::cerr << "error in curl_easy_init" << std::endl; LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
return EXIT_FAILURE;
}
sapi::v::RemotePtr curl(status_or_curl.value()); sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) { if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr url("http://example.com"); sapi::v::ConstCStr url("http://example.com");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()); status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Set WriteMemoryCallback as the write function // Set WriteMemoryCallback as the write function
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEFUNCTION, status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEFUNCTION,
&remote_function_ptr); &remote_function_ptr);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Pass 'chunk' struct to the callback function // Pass 'chunk' struct to the callback function
sapi::v::Struct<MemoryStruct> chunk; sapi::v::Struct<MemoryStruct> chunk;
status_or_int = status_or_int =
api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEDATA, chunk.PtrBoth()); api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEDATA, chunk.PtrBoth());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// 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");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_USERAGENT, status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_USERAGENT,
user_agent.PtrBefore()); user_agent.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Perform the request // Perform the request
status_or_int = api.curl_easy_perform(&curl); status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_perform" << std::endl; LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Retrieve memory size // Retrieve memory size
sapi::v::Int size; sapi::v::Int size;
size.SetRemote(&((MemoryStruct*)chunk.GetRemote())->size); size.SetRemote(&((MemoryStruct*)chunk.GetRemote())->size);
status = sandbox.TransferFromSandboxee(&size); status = sandbox.TransferFromSandboxee(&size);
if (!status.ok()) { if (!status.ok())
std::cerr << "error in sandbox TransferFromSandboxee" << std::endl; LOG(FATAL) << "sandbox.TransferFromSandboxee failed: " << status;
return EXIT_FAILURE;
}
std::cout << "memory size: " << size.GetValue() << " bytes" << std::endl; std::cout << "memory size: " << size.GetValue() << " bytes" << std::endl;
// Cleanup curl // Cleanup curl
status = api.curl_easy_cleanup(&curl); status = api.curl_easy_cleanup(&curl);
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -33,8 +33,10 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
// Add the syscalls and files missing in CurlSandbox to a new PolicyBuilder // Add the syscalls and files missing in CurlSandbox to a new PolicyBuilder
auto policy_builder = std::make_unique<sandbox2::PolicyBuilder>(); auto policy_builder = std::make_unique<sandbox2::PolicyBuilder>();
(*policy_builder) (*policy_builder)
.AllowFutexOp(FUTEX_WAIT_PRIVATE)
.AllowGetPIDs() .AllowGetPIDs()
.AllowGetRandom() .AllowGetRandom()
.AllowHandleSignals()
.AllowSyscall(__NR_sysinfo) .AllowSyscall(__NR_sysinfo)
.AddFile(ssl_certificate) .AddFile(ssl_certificate)
.AddFile(ssl_key) .AddFile(ssl_key)
@ -49,15 +51,15 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
}; };
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status; absl::Status status;
sapi::StatusOr<int> status_or_int; sapi::StatusOr<int> status_or_int;
sapi::StatusOr<CURL*> status_or_curl; sapi::StatusOr<CURL*> status_or_curl;
// Get input parameters (should be absolute paths) // Get input parameters (should be absolute paths)
if (argc != 5) { if (argc != 5) LOG(FATAL) << "wrong number of arguments (4 expected)";
std::cerr << "wrong number of arguments (4 expected)" << std::endl;
return EXIT_FAILURE;
}
std::string ssl_certificate = argv[1]; std::string ssl_certificate = argv[1];
std::string ssl_key = argv[2]; std::string ssl_key = argv[2];
std::string ssl_key_password = argv[3]; std::string ssl_key_password = argv[3];
@ -66,111 +68,80 @@ int main(int argc, char* argv[]) {
// 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(); status = sandbox.Init();
if (!status.ok()) { if (!status.ok())
std::cerr << "error in sandbox Init" << std::endl; LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
return EXIT_FAILURE;
}
CurlApi api(&sandbox); CurlApi api(&sandbox);
// Initialize curl (CURL_GLOBAL_DEFAULT = 3) // Initialize curl (CURL_GLOBAL_DEFAULT = 3)
status_or_int = api.curl_global_init(3l); status_or_int = api.curl_global_init(3l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_global_init" << std::endl; LOG(FATAL) << "curl_global_init failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Initialize curl easy handle // Initialize curl easy handle
status_or_curl = api.curl_easy_init(); status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) { if (!status_or_curl.ok())
std::cerr << "error in curl_easy_init" << std::endl; LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
return EXIT_FAILURE;
}
sapi::v::RemotePtr curl(status_or_curl.value()); sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) { if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
std::cerr << "error in curl_easy_init" << std::endl;
return EXIT_FAILURE;
}
// 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");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()); status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// 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");
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERTTYPE, status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERTTYPE,
ssl_cert_type.PtrBefore()); ssl_cert_type.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// 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());
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERT, status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERT,
sapi_ssl_certificate.PtrBefore()); sapi_ssl_certificate.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// 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());
status_or_int = status_or_int =
api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLKEY, sapi_ssl_key.PtrBefore()); api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLKEY, sapi_ssl_key.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// 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());
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_KEYPASSWD, status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_KEYPASSWD,
sapi_ssl_key_password.PtrBefore()); sapi_ssl_key_password.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// 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());
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_CAINFO, status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_CAINFO,
sapi_ca_certificates.PtrBefore()); sapi_ca_certificates.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Verify the authenticity of the server // Verify the authenticity of the server
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 1L); status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 1L);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_long" << std::endl; LOG(FATAL) << "curl_easy_setopt_long failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Perform the request // Perform the request
status_or_int = api.curl_easy_perform(&curl); status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_perform" << std::endl; LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Cleanup curl easy handle // Cleanup curl easy handle
status = api.curl_easy_cleanup(&curl); status = api.curl_easy_cleanup(&curl);
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
// Cleanup curl // Cleanup curl
status = api.curl_global_cleanup(); status = api.curl_global_cleanup();
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_global_cleanup failed: " << status;
std::cerr << "error in curl_global_cleanup" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -21,7 +21,10 @@
#include "curl_sapi.sapi.h" #include "curl_sapi.sapi.h"
#include "sandboxed_api/util/flag.h" #include "sandboxed_api/util/flag.h"
int main() { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
absl::Status status; absl::Status status;
sapi::StatusOr<int> status_or_int; sapi::StatusOr<int> status_or_int;
sapi::StatusOr<CURL*> status_or_curl; sapi::StatusOr<CURL*> status_or_curl;
@ -30,10 +33,8 @@ int main() {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandbox sandbox; CurlSapiSandbox sandbox;
status = sandbox.Init(); status = sandbox.Init();
if (!status.ok()) { if (!status.ok())
std::cerr << "error in sandbox Init" << std::endl; LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
return EXIT_FAILURE;
}
CurlApi api(&sandbox); CurlApi api(&sandbox);
// Number of running handles // Number of running handles
@ -41,50 +42,36 @@ int main() {
// Initialize curl (CURL_GLOBAL_DEFAULT = 3) // Initialize curl (CURL_GLOBAL_DEFAULT = 3)
status_or_int = api.curl_global_init(3l); status_or_int = api.curl_global_init(3l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_global_init" << std::endl; LOG(FATAL) << "curl_global_init failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Initialize http_handle // Initialize http_handle
status_or_curl = api.curl_easy_init(); status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) { if (!status_or_curl.ok())
std::cerr << "error in curl_easy_init" << std::endl; LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
return EXIT_FAILURE;
}
sapi::v::RemotePtr http_handle(status_or_curl.value()); sapi::v::RemotePtr http_handle(status_or_curl.value());
if (!http_handle.GetValue()) { if (!http_handle.GetValue())
std::cerr << "error in curl_easy_init" << std::endl; LOG(FATAL) << "curl_easy_init failed: http_handle is NULL";
return EXIT_FAILURE;
}
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr url("http://example.com"); sapi::v::ConstCStr url("http://example.com");
status_or_int = status_or_int =
api.curl_easy_setopt_ptr(&http_handle, CURLOPT_URL, url.PtrBefore()); api.curl_easy_setopt_ptr(&http_handle, CURLOPT_URL, url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Initialize multi_handle // Initialize multi_handle
status_or_curlm = api.curl_multi_init(); status_or_curlm = api.curl_multi_init();
if (!status_or_curl.ok()) { if (!status_or_curlm.ok())
std::cerr << "error in curl_multi_init" << std::endl; LOG(FATAL) << "curl_multi_init failed: " << status_or_curlm.status();
return EXIT_FAILURE;
}
sapi::v::RemotePtr multi_handle(status_or_curlm.value()); sapi::v::RemotePtr multi_handle(status_or_curlm.value());
if (!multi_handle.GetValue()) { if (!multi_handle.GetValue())
std::cerr << "error in curl_multi_init" << std::endl; LOG(FATAL) << "curl_multi_init failed: multi_handle is NULL";
return EXIT_FAILURE;
}
// Add http_handle to the multi stack // Add http_handle to the multi stack
status_or_int = api.curl_multi_add_handle(&multi_handle, &http_handle); status_or_int = api.curl_multi_add_handle(&multi_handle, &http_handle);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_multi_add_handle" << std::endl; LOG(FATAL) << "curl_multi_add_handle failed: " << status_or_int.status();
return EXIT_FAILURE;
}
while (still_running.GetValue()) { while (still_running.GetValue()) {
sapi::v::Int numfds(0); sapi::v::Int numfds(0);
@ -92,50 +79,36 @@ int main() {
// Perform the request // Perform the request
status_or_int = status_or_int =
api.curl_multi_perform(&multi_handle, still_running.PtrBoth()); api.curl_multi_perform(&multi_handle, still_running.PtrBoth());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_multi_perform" << std::endl; LOG(FATAL) << "curl_mutli_perform failed: " << status_or_int.status();
return EXIT_FAILURE;
}
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;
status_or_int = api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0, status_or_int = api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0,
1000, numfds.PtrBoth()); 1000, numfds.PtrBoth());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_multi_poll_sapi" << std::endl; LOG(FATAL) << "curl_multi_poll_sapi failed: " << status_or_int.status();
return EXIT_FAILURE;
}
} }
} }
// Remove http_handle from the multi stack // Remove http_handle from the multi stack
status_or_int = api.curl_multi_remove_handle(&multi_handle, &http_handle); status_or_int = api.curl_multi_remove_handle(&multi_handle, &http_handle);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_multi_remove_handle" << std::endl; LOG(FATAL) << "curl_multi_remove_handle failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Cleanup http_handle // Cleanup http_handle
status = api.curl_easy_cleanup(&http_handle); status = api.curl_easy_cleanup(&http_handle);
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
std::cerr << "error in curl_easy_cleanup" << std::endl;
return EXIT_FAILURE;
}
// Cleanup multi_handle // Cleanup multi_handle
status_or_int = api.curl_multi_cleanup(&multi_handle); status_or_int = api.curl_multi_cleanup(&multi_handle);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_multi_cleanup" << std::endl; LOG(FATAL) << "curl_multi_cleanup failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Cleanup curl // Cleanup curl
status = api.curl_global_cleanup(); status = api.curl_global_cleanup();
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_global_cleanup failed: " << status;
std::cerr << "error in curl_global_cleanup" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -37,38 +37,26 @@ void* pull_one_url(void* args) {
// Initialize the curl session // Initialize the curl session
status_or_curl = api.curl_easy_init(); status_or_curl = api.curl_easy_init();
if (!status_or_curl.ok()) { if (!status_or_curl.ok())
std::cerr << "error in curl_easy_init" << std::endl; LOG(FATAL) << "curl_easy_init failed: " << status_or_curl.status();
return NULL;
}
sapi::v::RemotePtr curl(status_or_curl.value()); sapi::v::RemotePtr curl(status_or_curl.value());
if (!curl.GetValue()) { if (!curl.GetValue()) LOG(FATAL) << "curl_easy_init failed: curl is NULL";
std::cerr << "error in curl_easy_init" << std::endl;
return NULL;
}
// Specify URL to get // Specify URL to get
sapi::v::ConstCStr sapi_url(((thread_args*)args)->url); sapi::v::ConstCStr sapi_url(((thread_args*)args)->url);
status_or_int = status_or_int =
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, sapi_url.PtrBefore()); api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, sapi_url.PtrBefore());
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_setopt_ptr" << std::endl; LOG(FATAL) << "curl_easy_setopt_ptr failed: " << status_or_int.status();
return NULL;
}
// Perform the request // Perform the request
status_or_int = api.curl_easy_perform(&curl); status_or_int = api.curl_easy_perform(&curl);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_easy_perform" << std::endl; LOG(FATAL) << "curl_easy_perform failed: " << status_or_int.status();
return NULL;
}
// Cleanup curl // Cleanup curl
status = api.curl_easy_cleanup(&curl); status = api.curl_easy_cleanup(&curl);
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_easy_cleanup failed: " << status;
std::cerr << "error in curl_easy_cleanup" << std::endl;
return NULL;
}
return NULL; return NULL;
} }
@ -77,7 +65,10 @@ const char* const urls[kThreadsnumber] = {
"http://example.com", "http://example.edu", "http://example.net", "http://example.com", "http://example.edu", "http://example.net",
"http://example.org"}; "http://example.org"};
int main(int argc, char** argv) { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
pthread_t tid[kThreadsnumber]; pthread_t tid[kThreadsnumber];
absl::Status status; absl::Status status;
@ -86,42 +77,33 @@ int main(int argc, char** argv) {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
CurlSapiSandbox sandbox; CurlSapiSandbox sandbox;
status = sandbox.Init(); status = sandbox.Init();
if (!status.ok()) { if (!status.ok())
std::cerr << "error in sandbox Init" << std::endl; LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
return EXIT_FAILURE;
}
CurlApi api(&sandbox); CurlApi api(&sandbox);
// Initialize curl (CURL_GLOBAL_DEFAULT = 3) // Initialize curl (CURL_GLOBAL_DEFAULT = 3)
status_or_int = api.curl_global_init(3l); status_or_int = api.curl_global_init(3l);
if (!status_or_int.ok() or status_or_int.value() != CURLE_OK) { if (!status_or_int.ok() or status_or_int.value() != CURLE_OK)
std::cerr << "error in curl_global_init" << std::endl; LOG(FATAL) << "curl_global_init failed: " << status_or_int.status();
return EXIT_FAILURE;
}
// Create the threads // Create the threads
for (int i = 0; i < kThreadsnumber; ++i) { for (int i = 0; i < kThreadsnumber; ++i) {
thread_args args = {urls[i], &api}; thread_args args = {urls[i], &api};
int error = pthread_create(&tid[i], NULL, pull_one_url, (void*)&args); int error = pthread_create(&tid[i], NULL, pull_one_url, (void*)&args);
if (error) { if (error) LOG(FATAL) << "pthread_create failed";
std::cerr << "error in pthread_create" << std::endl;
return EXIT_FAILURE;
}
std::cout << "Thread " << i << " gets " << urls[i] << std::endl; std::cout << "Thread " << i << " gets " << urls[i] << std::endl;
} }
// Join the threads // Join the threads
for (int i = 0; i < kThreadsnumber; i++) { for (int i = 0; i < kThreadsnumber; ++i) {
pthread_join(tid[i], NULL); int error = pthread_join(tid[i], NULL);
if (error) LOG(FATAL) << "pthread_join failed";
std::cout << "Thread " << i << " terminated" << std::endl; std::cout << "Thread " << i << " terminated" << std::endl;
} }
// Cleanup curl // Cleanup curl
status = api.curl_global_cleanup(); status = api.curl_global_cleanup();
if (!status.ok()) { if (!status.ok()) LOG(FATAL) << "curl_global_cleanup failed: " << status;
std::cerr << "error in curl_global_cleanup" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -39,26 +39,26 @@ absl::Status CurlTransaction::Main() {
CurlApi api(sandbox()); 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());
sapi::v::RemotePtr curl(curl_remote); sapi::v::RemotePtr curl(curl_remote);
TRANSACTION_FAIL_IF_NOT(curl.GetValue(), "error in curl_easy_init"); TRANSACTION_FAIL_IF_NOT(curl.GetValue(), "curl_easy_init failed");
// Specify URL to get // Specify URL to get
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, CURLOPT_URL, url.PtrBefore()));
TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK, TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK,
"error in curl_easy_setopt_ptr"); "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 == CURLE_OK,
"error in curl_easy_perform"); "curl_easy_perform failed");
// Cleanup curl // Cleanup curl
TRANSACTION_FAIL_IF_NOT(api.curl_easy_cleanup(&curl).ok(), TRANSACTION_FAIL_IF_NOT(api.curl_easy_cleanup(&curl).ok(),
"error in curl_easy_cleanup"); "curl_easy_cleanup failed");
return absl::OkStatus(); return absl::OkStatus();
} }
@ -66,7 +66,7 @@ absl::Status CurlTransaction::Main() {
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
CurlTransaction curl{std::make_unique<CurlSapiSandbox>()}; CurlTransaction curl{std::make_unique<CurlSapiSandbox>()};
absl::Status status = curl.Run(); absl::Status status = curl.Run();
CHECK(status.ok()); CHECK(status.ok()) << "CurlTransaction failed";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -12,11 +12,14 @@
// 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.
#include <linux/futex.h>
#include <sys/mman.h> // For mmap arguments
#include <syscall.h> #include <syscall.h>
#include <cstdlib> #include <cstdlib>
#include "curl_sapi.sapi.h" #include "curl_sapi.sapi.h"
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
#include "sandboxed_api/util/flag.h" #include "sandboxed_api/util/flag.h"
class CurlSapiSandbox : public CurlSandbox { class CurlSapiSandbox : public CurlSandbox {
@ -28,7 +31,8 @@ class CurlSapiSandbox : public CurlSandbox {
.AllowDynamicStartup() .AllowDynamicStartup()
.AllowExit() .AllowExit()
.AllowFork() .AllowFork()
.AllowHandleSignals() .AllowFutexOp(FUTEX_WAKE_PRIVATE)
.AllowMmap()
.AllowOpen() .AllowOpen()
.AllowRead() .AllowRead()
.AllowSafeFcntl() .AllowSafeFcntl()
@ -38,14 +42,12 @@ class CurlSapiSandbox : public CurlSandbox {
__NR_access, __NR_access,
__NR_bind, __NR_bind,
__NR_connect, __NR_connect,
__NR_futex,
__NR_getpeername, __NR_getpeername,
__NR_getsockname, __NR_getsockname,
__NR_getsockopt, __NR_getsockopt,
__NR_ioctl, __NR_ioctl,
__NR_listen, __NR_listen,
__NR_madvise, __NR_madvise,
__NR_mmap,
__NR_poll, __NR_poll,
__NR_recvfrom, __NR_recvfrom,
__NR_recvmsg, __NR_recvmsg,

View File

@ -24,7 +24,7 @@
void CurlTestUtils::curl_test_set_up() { void CurlTestUtils::curl_test_set_up() {
// Initialize sandbox2 and sapi // Initialize sandbox2 and sapi
sandbox = std::make_unique<CurlSapiSandbox>(); sandbox = std::make_unique<CurlSapiSandbox>();
sandbox->Init().IgnoreError(); ASSERT_THAT(sandbox->Init(), sapi::IsOk());
api = std::make_unique<CurlApi>(sandbox.get()); api = std::make_unique<CurlApi>(sandbox.get());
// Initialize curl // Initialize curl
@ -36,18 +36,18 @@ void CurlTestUtils::curl_test_set_up() {
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_url_code, int setopt_url_code,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_URL, sapi_url.PtrBefore())); api->curl_easy_setopt_ptr(curl.get(), CURLOPT_URL, sapi_url.PtrBefore()));
EXPECT_EQ(setopt_url_code, CURLE_OK); ASSERT_EQ(setopt_url_code, CURLE_OK);
// Set port // Set port
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_port_code, int setopt_port_code,
api->curl_easy_setopt_long(curl.get(), CURLOPT_PORT, port)); api->curl_easy_setopt_long(curl.get(), CURLOPT_PORT, port));
EXPECT_EQ(setopt_port_code, CURLE_OK); ASSERT_EQ(setopt_port_code, CURLE_OK);
// Generate pointer to the write_to_memory callback // Generate pointer to the write_to_memory callback
sapi::RPCChannel rpcc(sandbox->comms()); sapi::RPCChannel rpcc(sandbox->comms());
size_t (*_function_ptr)(char*, size_t, size_t, void*); size_t (*_function_ptr)(char*, size_t, size_t, void*);
EXPECT_THAT(rpcc.Symbol("write_to_memory", (void**)&_function_ptr), ASSERT_THAT(rpcc.Symbol("write_to_memory", (void**)&_function_ptr),
sapi::IsOk()); sapi::IsOk());
sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr); sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr);
@ -56,36 +56,36 @@ void CurlTestUtils::curl_test_set_up() {
int setopt_write_function, int setopt_write_function,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_WRITEFUNCTION, api->curl_easy_setopt_ptr(curl.get(), CURLOPT_WRITEFUNCTION,
&remote_function_ptr)); &remote_function_ptr));
EXPECT_EQ(setopt_write_function, CURLE_OK); ASSERT_EQ(setopt_write_function, CURLE_OK);
// Pass memory chunk object to the callback // Pass memory chunk object to the callback
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(
int setopt_write_data, int setopt_write_data,
api->curl_easy_setopt_ptr(curl.get(), CURLOPT_WRITEDATA, api->curl_easy_setopt_ptr(curl.get(), CURLOPT_WRITEDATA,
chunk.PtrBoth())); chunk.PtrBoth()));
EXPECT_EQ(setopt_write_data, CURLE_OK); ASSERT_EQ(setopt_write_data, CURLE_OK);
} }
void CurlTestUtils::curl_test_tear_down() { void CurlTestUtils::curl_test_tear_down() {
// Cleanup curl // Cleanup curl
api->curl_easy_cleanup(curl.get()).IgnoreError(); ASSERT_THAT(api->curl_easy_cleanup(curl.get()), sapi::IsOk());
} }
void CurlTestUtils::perform_request(std::string& response) { void CurlTestUtils::perform_request(std::string& response) {
// Perform the request // Perform the request
SAPI_ASSERT_OK_AND_ASSIGN(int perform_code, SAPI_ASSERT_OK_AND_ASSIGN(int perform_code,
api->curl_easy_perform(curl.get())); api->curl_easy_perform(curl.get()));
EXPECT_EQ(perform_code, CURLE_OK); ASSERT_EQ(perform_code, CURLE_OK);
// Get pointer to the memory chunk // Get pointer to the memory chunk
sapi::v::GenericPtr remote_ptr; sapi::v::GenericPtr remote_ptr;
remote_ptr.SetRemote(&((MemoryStruct*)chunk.GetRemote())->memory); remote_ptr.SetRemote(&((MemoryStruct*)chunk.GetRemote())->memory);
sandbox->TransferFromSandboxee(&remote_ptr).IgnoreError(); ASSERT_THAT(sandbox->TransferFromSandboxee(&remote_ptr), sapi::IsOk());
void* chunk_ptr = (void*)remote_ptr.GetValue(); void* chunk_ptr = (void*)remote_ptr.GetValue();
// Get the string and store it in response // Get the string and store it in response
SAPI_ASSERT_OK_AND_ASSIGN( SAPI_ASSERT_OK_AND_ASSIGN(response,
response, sandbox->GetCString(sapi::v::RemotePtr(chunk_ptr))); sandbox->GetCString(sapi::v::RemotePtr(chunk_ptr)));
} }
void CurlTestUtils::perform_request() { void CurlTestUtils::perform_request() {

View File

@ -19,7 +19,7 @@ class Curl_Test : public CurlTestUtils, public ::testing::Test {
void SetUp() override { void SetUp() override {
// Start mock server, also sets port number // Start mock server, also sets port number
start_mock_server(); start_mock_server();
EXPECT_TRUE(server_future.valid()); ASSERT_TRUE(server_future.valid());
curl_test_set_up(); curl_test_set_up();
} }
@ -28,7 +28,7 @@ class Curl_Test : public CurlTestUtils, public ::testing::Test {
curl_test_tear_down(); curl_test_tear_down();
// Wait for the mock server to return and check for any error // Wait for the mock server to return and check for any error
EXPECT_TRUE(server_future.get()); ASSERT_TRUE(server_future.get());
} }
}; };
@ -42,7 +42,7 @@ TEST_F(Curl_Test, EffectiveUrl) {
int getinfo_code, int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_EFFECTIVE_URL, api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_EFFECTIVE_URL,
effective_url_ptr.PtrBoth())); effective_url_ptr.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK); ASSERT_EQ(getinfo_code, 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,
@ -50,7 +50,7 @@ TEST_F(Curl_Test, EffectiveUrl) {
effective_url_ptr.GetPointedVar()))); effective_url_ptr.GetPointedVar())));
// Compare effective URL with original URL // Compare effective URL with original URL
EXPECT_EQ(effective_url, kUrl); ASSERT_EQ(effective_url, kUrl);
} }
TEST_F(Curl_Test, EffectivePort) { TEST_F(Curl_Test, EffectivePort) {
@ -63,10 +63,10 @@ TEST_F(Curl_Test, EffectivePort) {
int getinfo_code, int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_PRIMARY_PORT, api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_PRIMARY_PORT,
effective_port.PtrBoth())); effective_port.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK); ASSERT_EQ(getinfo_code, CURLE_OK);
// Compare effective port with port set by the mock server // Compare effective port with port set by the mock server
EXPECT_EQ(effective_port.GetValue(), port); ASSERT_EQ(effective_port.GetValue(), port);
} }
TEST_F(Curl_Test, ResponseCode) { TEST_F(Curl_Test, ResponseCode) {
@ -79,10 +79,10 @@ TEST_F(Curl_Test, ResponseCode) {
int getinfo_code, int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_RESPONSE_CODE, api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_RESPONSE_CODE,
response_code.PtrBoth())); response_code.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK); ASSERT_EQ(getinfo_code, CURLE_OK);
// Check response code // Check response code
EXPECT_EQ(response_code.GetValue(), 200); ASSERT_EQ(response_code.GetValue(), 200);
} }
TEST_F(Curl_Test, ContentType) { TEST_F(Curl_Test, ContentType) {
@ -95,7 +95,7 @@ TEST_F(Curl_Test, ContentType) {
int getinfo_code, int getinfo_code,
api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_CONTENT_TYPE, api->curl_easy_getinfo_ptr(curl.get(), CURLINFO_CONTENT_TYPE,
content_type_ptr.PtrBoth())); content_type_ptr.PtrBoth()));
EXPECT_EQ(getinfo_code, CURLE_OK); ASSERT_EQ(getinfo_code, CURLE_OK);
// Store content type in a string // Store content type in a string
SAPI_ASSERT_OK_AND_ASSIGN(std::string content_type, SAPI_ASSERT_OK_AND_ASSIGN(std::string content_type,
@ -103,7 +103,7 @@ TEST_F(Curl_Test, ContentType) {
content_type_ptr.GetPointedVar()))); content_type_ptr.GetPointedVar())));
// Compare content type with "text/plain" // Compare content type with "text/plain"
EXPECT_EQ(content_type, "text/plain"); ASSERT_EQ(content_type, "text/plain");
} }
TEST_F(Curl_Test, GETResponse) { TEST_F(Curl_Test, GETResponse) {
@ -111,7 +111,7 @@ TEST_F(Curl_Test, GETResponse) {
perform_request(response); perform_request(response);
// Compare response with expected response // Compare response with expected response
EXPECT_EQ(response, kSimpleResponse); ASSERT_EQ(response, kSimpleResponse);
} }
TEST_F(Curl_Test, POSTResponse) { TEST_F(Curl_Test, POSTResponse) {
@ -120,25 +120,25 @@ TEST_F(Curl_Test, POSTResponse) {
// Set request method to POST // Set request method to POST
SAPI_ASSERT_OK_AND_ASSIGN(int setopt_post, api->curl_easy_setopt_long( SAPI_ASSERT_OK_AND_ASSIGN(int setopt_post, api->curl_easy_setopt_long(
curl.get(), CURLOPT_POST, 1l)); curl.get(), CURLOPT_POST, 1l));
EXPECT_EQ(setopt_post, CURLE_OK); ASSERT_EQ(setopt_post, CURLE_OK);
// 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(), CURLOPT_POSTFIELDSIZE,
post_fields.GetSize())); post_fields.GetSize()));
EXPECT_EQ(setopt_post_fields_size, CURLE_OK); ASSERT_EQ(setopt_post_fields_size, 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(), CURLOPT_POSTFIELDS,
post_fields.PtrBefore())); post_fields.PtrBefore()));
EXPECT_EQ(setopt_post_fields, CURLE_OK); ASSERT_EQ(setopt_post_fields, CURLE_OK);
std::string response; std::string response;
perform_request(response); perform_request(response);
// Compare response with expected response // Compare response with expected response
EXPECT_EQ(std::string(post_fields.GetData()), response); ASSERT_EQ(std::string(post_fields.GetData()), response);
} }