mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Merge pull request #61 from FedericoStazi:curl
PiperOrigin-RevId: 334994112 Change-Id: Iedd065f33cdb5ebda796722d0a4d158ba719ff2c
This commit is contained in:
commit
47ba5c8e39
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -7,9 +7,9 @@
|
|||
[submodule "oss-internship-2020/pffft/master"]
|
||||
path = oss-internship-2020/pffft/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"]
|
||||
path = oss-internship-2020/gdal/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
|
||||
|
|
|
@ -12,15 +12,15 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
project(libcurl_sandbox)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
option(CURL_SAPI_ENABLE_EXAMPLES "" ON)
|
||||
option(CURL_SAPI_ENABLE_TESTS "" ON)
|
||||
option(SAPI_CURL_ENABLE_EXAMPLES "" ON)
|
||||
option(SAPI_CURL_ENABLE_TESTS "" ON)
|
||||
|
||||
# Add callbacks used by examples and tests
|
||||
if (CURL_SAPI_ENABLE_EXAMPLES OR CURL_SAPI_ENABLE_TESTS)
|
||||
|
@ -35,8 +35,8 @@ add_subdirectory(curl_wrapper)
|
|||
|
||||
# Setup Sandboxed API
|
||||
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_TESTS ${CURL_SAPI_ENABLE_TESTS} CACHE BOOL "" FORCE)
|
||||
set(SAPI_ENABLE_EXAMPLES ${SAPI_CURL_ENABLE_EXAMPLES} CACHE BOOL "" FORCE)
|
||||
set(SAPI_ENABLE_TESTS ${SAPI_CURL_ENABLE_TESTS} CACHE BOOL "" FORCE)
|
||||
add_subdirectory(
|
||||
"${SAPI_ROOT}"
|
||||
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
|
||||
|
@ -125,7 +125,7 @@ add_sapi_library(curl_sapi
|
|||
|
||||
LIBRARY_NAME Curl
|
||||
|
||||
NAMESPACE ""
|
||||
NAMESPACE curl
|
||||
)
|
||||
|
||||
# Include generated SAPI header
|
||||
|
@ -134,11 +134,11 @@ target_include_directories(curl_sapi INTERFACE
|
|||
)
|
||||
|
||||
# Add examples
|
||||
if (CURL_SAPI_ENABLE_EXAMPLES)
|
||||
if (SAPI_CURL_ENABLE_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
# Add tests
|
||||
if (CURL_SAPI_ENABLE_TESTS)
|
||||
if (SAPI_CURL_ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
|
|
@ -38,12 +38,15 @@ Variadic methods are currently not supported by Sandboxed API. To solve this,
|
|||
these methods are defined with an additional explicit parameter in
|
||||
`custom_curl.h`.
|
||||
|
||||
The methods are: - `curl_easy_setopt`. Use `curl_easy_setopt_ptr`,
|
||||
`curl_easy_setopt_long` or `curl_easy_setopt_curl_off_t` instead. -
|
||||
`curl_easy_getinfo`. Use `curl_easy_getinfo_ptr` instead. - `curl_multi_setopt`.
|
||||
Use `curl_multi_setopt_ptr`, `curl_multi_setopt_long` or
|
||||
`curl_multi_setopt_curl_off_t` instead. - `curl_share_setopt`. Use
|
||||
`curl_share_setopt_ptr` or `curl_share_setopt_long` instead
|
||||
The methods are:
|
||||
|
||||
- `curl_easy_setopt`. Use `curl_easy_setopt_ptr`, `curl_easy_setopt_long` or
|
||||
`curl_easy_setopt_curl_off_t` instead.
|
||||
- `curl_easy_getinfo`. Use `curl_easy_getinfo_ptr` instead.
|
||||
- `curl_multi_setopt`. Use `curl_multi_setopt_ptr`, `curl_multi_setopt_long`
|
||||
or `curl_multi_setopt_curl_off_t` instead.
|
||||
- `curl_share_setopt`. Use `curl_share_setopt_ptr` or `curl_share_setopt_long`
|
||||
instead
|
||||
|
||||
#### Methods with incomplete array arguments
|
||||
|
||||
|
@ -51,8 +54,10 @@ Incomplete array arguments are currently not supported by Sandboxed API. To
|
|||
solve this, methods taking an incomplete array argument have a wrapper in
|
||||
`custom_curl.h`, and take a pointer as the argument.
|
||||
|
||||
The methods are: - `curl_multi_poll`. Use `curl_multi_poll_sapi` instead. -
|
||||
`curl_multi_wait`. Use `curl_multi_wait_sapi` instead.
|
||||
The methods are:
|
||||
|
||||
- `curl_multi_poll`. Use `curl_multi_poll_sapi` instead.
|
||||
- `curl_multi_wait`. Use `curl_multi_wait_sapi` instead.
|
||||
|
||||
#### Methods with conflicts on the generated header
|
||||
|
||||
|
@ -60,11 +65,15 @@ Some methods create conflicts on the generated header because of redefined
|
|||
`#define` directives from files included by the header. To solve this, the
|
||||
conflicting types and methods are redefined in `custom_curl.h`.
|
||||
|
||||
The types are: - `time_t`. Use `time_t_sapi` instead. - `fd_set`. Use
|
||||
`fd_set_sapi` instead.
|
||||
The types are:
|
||||
|
||||
The methods are: - `curl_getdate`. Use `curl_getdate_sapi` instead. -
|
||||
`curl_multi_fdset`. Use `curl_multi_fdset_sapi` instead.
|
||||
- `time_t`. Use `time_t_sapi` instead.
|
||||
- `fd_set`. Use `fd_set_sapi` instead.
|
||||
|
||||
The methods are:
|
||||
|
||||
- `curl_getdate`. Use `curl_getdate_sapi` instead.
|
||||
- `curl_multi_fdset`. Use `curl_multi_fdset_sapi` instead.
|
||||
|
||||
#### Function pointers
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef TESTS_CALLBACKS_H
|
||||
#define TESTS_CALLBACKS_H
|
||||
#ifndef CALLBACKS_H_
|
||||
#define CALLBACKS_H_
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@ -21,4 +21,4 @@
|
|||
extern "C" size_t WriteToMemory(char* contents, size_t size, size_t num_bytes,
|
||||
void* userp);
|
||||
|
||||
#endif // TESTS_CALLBACKS_H
|
||||
#endif // CALLBACKS_H_
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
// Wrapper for curl library
|
||||
|
||||
#ifndef CURL_WRAPPER_H
|
||||
#define CURL_WRAPPER_H
|
||||
#ifndef CURL_WRAPPER_H_
|
||||
#define CURL_WRAPPER_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
|
||||
CURLSHcode curl_share_setopt_long(CURLSH* handle, CURLSHoption option,
|
||||
long parameter);
|
||||
}
|
||||
|
||||
#endif // CURL_WRAPPER_H
|
||||
} // extern "C"
|
||||
|
||||
#endif // CURL_WRAPPER_H_
|
||||
|
|
|
@ -19,59 +19,67 @@
|
|||
|
||||
#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[]) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
absl::Status status;
|
||||
|
||||
// Initialize sandbox2 and sapi
|
||||
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;
|
||||
if (absl::Status status = Example1(); !status.ok()) {
|
||||
LOG(ERROR) << "Example1 failed: " << status.ToString();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -20,87 +20,89 @@
|
|||
|
||||
#include "../sandbox.h" // NOLINT(build/include)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
absl::Status status;
|
||||
namespace {
|
||||
|
||||
absl::Status Example2() {
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlSapiSandbox sandbox;
|
||||
status = sandbox.Init();
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
|
||||
}
|
||||
CurlApi api(&sandbox);
|
||||
curl::CurlSapiSandbox sandbox;
|
||||
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||
curl::CurlApi api(&sandbox);
|
||||
|
||||
// Generate pointer to WriteMemoryCallback function
|
||||
void* function_ptr;
|
||||
status = sandbox.rpc_channel()->Symbol("WriteToMemory", &function_ptr);
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "sapi::Sandbox::rpc_channel().Symbol failed: " << status;
|
||||
}
|
||||
sapi::v::RemotePtr remote_function_ptr(function_ptr);
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
sandbox.rpc_channel()->Symbol("WriteToMemory", &function_ptr));
|
||||
sapi::v::RemotePtr write_to_memory(function_ptr);
|
||||
|
||||
// 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";
|
||||
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");
|
||||
}
|
||||
|
||||
absl::StatusOr<int> curl_code;
|
||||
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();
|
||||
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 WriteMemoryCallback as the write function
|
||||
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEFUNCTION,
|
||||
&remote_function_ptr);
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEFUNCTION,
|
||||
&write_to_memory));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Pass 'chunk' struct to the callback function
|
||||
sapi::v::LenVal chunk(0);
|
||||
curl_code =
|
||||
api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEDATA, chunk.PtrBoth());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_WRITEDATA,
|
||||
chunk.PtrBoth()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Set a user agent
|
||||
sapi::v::ConstCStr user_agent("libcurl-agent/1.0");
|
||||
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_USERAGENT,
|
||||
user_agent.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_USERAGENT,
|
||||
user_agent.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// 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();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_perform(&curl));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_perform failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Retrieve memory size
|
||||
status = sandbox.TransferFromSandboxee(&chunk);
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "sandbox.TransferFromSandboxee failed: " << status;
|
||||
}
|
||||
SAPI_RETURN_IF_ERROR(sandbox.TransferFromSandboxee(&chunk));
|
||||
std::cout << "memory size: " << chunk.GetDataSize() << " bytes" << std::endl;
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_easy_cleanup(&curl);
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
|
||||
SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
|
||||
|
||||
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;
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
|
||||
#include "../sandbox.h" // NOLINT(build/include)
|
||||
|
||||
class CurlSapiSandboxEx3 : public CurlSapiSandbox {
|
||||
namespace {
|
||||
|
||||
class CurlSapiSandboxEx3 : public curl::CurlSapiSandbox {
|
||||
public:
|
||||
CurlSapiSandboxEx3(std::string ssl_certificate, std::string ssl_key,
|
||||
std::string ca_certificates)
|
||||
|
@ -42,7 +44,7 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
|
|||
.AddFile(ssl_key)
|
||||
.AddFile(ca_certificates);
|
||||
// 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;
|
||||
|
@ -50,116 +52,121 @@ class CurlSapiSandboxEx3 : public CurlSapiSandbox {
|
|||
std::string ca_certificates;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
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];
|
||||
|
||||
absl::Status Example3(std::string ssl_certificate, std::string ssl_key,
|
||||
std::string ssl_key_password,
|
||||
std::string ca_certificates) {
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlSapiSandboxEx3 sandbox(ssl_certificate, ssl_key, ca_certificates);
|
||||
status = sandbox.Init();
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
|
||||
}
|
||||
CurlApi api(&sandbox);
|
||||
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||
curl::CurlApi api(&sandbox);
|
||||
|
||||
absl::StatusOr<int> curl_code;
|
||||
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();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_global_init failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Initialize curl easy handle
|
||||
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";
|
||||
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");
|
||||
}
|
||||
|
||||
// Specify URL to get (using HTTPS)
|
||||
sapi::v::ConstCStr url("https://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();
|
||||
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 SSL certificate type to "PEM"
|
||||
sapi::v::ConstCStr ssl_cert_type("PEM");
|
||||
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERTTYPE,
|
||||
ssl_cert_type.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLCERTTYPE,
|
||||
ssl_cert_type.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Set the certificate for client authentication
|
||||
sapi::v::ConstCStr sapi_ssl_certificate(ssl_certificate.c_str());
|
||||
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERT,
|
||||
sapi_ssl_certificate.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLCERT,
|
||||
sapi_ssl_certificate.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Set the private key for client authentication
|
||||
sapi::v::ConstCStr sapi_ssl_key(ssl_key.c_str());
|
||||
curl_code =
|
||||
api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLKEY, sapi_ssl_key.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_SSLKEY,
|
||||
sapi_ssl_key.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Set the password used to protect the private key
|
||||
sapi::v::ConstCStr sapi_ssl_key_password(ssl_key_password.c_str());
|
||||
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_KEYPASSWD,
|
||||
sapi_ssl_key_password.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_KEYPASSWD,
|
||||
sapi_ssl_key_password.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Set the file with the certificates vaildating the server
|
||||
sapi::v::ConstCStr sapi_ca_certificates(ca_certificates.c_str());
|
||||
curl_code = api.curl_easy_setopt_ptr(&curl, CURLOPT_CAINFO,
|
||||
sapi_ca_certificates.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_CAINFO,
|
||||
sapi_ca_certificates.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Verify the authenticity of the server
|
||||
curl_code = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_long failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, 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
|
||||
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();
|
||||
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 easy handle
|
||||
status = api.curl_easy_cleanup(&curl);
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
|
||||
}
|
||||
SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_global_cleanup();
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "curl_global_cleanup failed: " << status;
|
||||
SAPI_RETURN_IF_ERROR(api.curl_global_cleanup());
|
||||
|
||||
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;
|
||||
|
|
|
@ -21,107 +21,113 @@
|
|||
#include "curl_sapi.sapi.h" // NOLINT(build/include)
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
absl::Status status;
|
||||
namespace {
|
||||
|
||||
absl::Status Example4() {
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlSapiSandbox sandbox;
|
||||
status = sandbox.Init();
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "Couldn't initialize Sandboxed API: " << status;
|
||||
}
|
||||
CurlApi api(&sandbox);
|
||||
curl::CurlSapiSandbox sandbox;
|
||||
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||
curl::CurlApi api(&sandbox);
|
||||
|
||||
// Number of running handles
|
||||
sapi::v::Int still_running(1);
|
||||
|
||||
absl::StatusOr<int> curl_code;
|
||||
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();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_global_init(3l));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_global_init failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Initialize http_handle
|
||||
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 http_handle(curl_handle.value());
|
||||
if (!http_handle.GetValue()) {
|
||||
LOG(FATAL) << "curl_easy_init failed: http_handle is NULL";
|
||||
curl::CURL* curl_handle;
|
||||
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");
|
||||
}
|
||||
|
||||
// Specify URL to get
|
||||
sapi::v::ConstCStr url("http://example.com");
|
||||
curl_code =
|
||||
api.curl_easy_setopt_ptr(&http_handle, CURLOPT_URL, url.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_easy_setopt_ptr(&http_handle, curl::CURLOPT_URL,
|
||||
url.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Initialize multi_handle
|
||||
absl::StatusOr<CURLM*> curlm_handle = api.curl_multi_init();
|
||||
if (!curlm_handle.ok()) {
|
||||
LOG(FATAL) << "curl_multi_init failed: " << curlm_handle.status();
|
||||
}
|
||||
sapi::v::RemotePtr multi_handle(curlm_handle.value());
|
||||
if (!multi_handle.GetValue()) {
|
||||
LOG(FATAL) << "curl_multi_init failed: multi_handle is NULL";
|
||||
curl::CURLM* curlm_handle;
|
||||
SAPI_ASSIGN_OR_RETURN(curlm_handle, api.curl_multi_init());
|
||||
sapi::v::RemotePtr multi_handle(curlm_handle);
|
||||
if (!curlm_handle) {
|
||||
return absl::UnavailableError(
|
||||
"curl_multi_init failed: multi_handle is NULL");
|
||||
}
|
||||
|
||||
// Add http_handle to the multi stack
|
||||
curl_code = api.curl_multi_add_handle(&multi_handle, &http_handle);
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_multi_add_handle failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_multi_add_handle(&multi_handle, &http_handle));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_multi_add_handle failed: " + curl_code);
|
||||
}
|
||||
|
||||
while (still_running.GetValue()) {
|
||||
sapi::v::Int numfds(0);
|
||||
|
||||
// Perform the request
|
||||
curl_code = api.curl_multi_perform(&multi_handle, still_running.PtrBoth());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_mutli_perform failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, 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()) {
|
||||
// Wait for an event or timeout
|
||||
sapi::v::NullPtr null_ptr;
|
||||
curl_code = api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0, 1000,
|
||||
numfds.PtrBoth());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_multi_poll_sapi failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
curl_code, api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0, 1000,
|
||||
numfds.PtrBoth()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_multi_poll_sapi failed: " +
|
||||
curl_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove http_handle from the multi stack
|
||||
curl_code = api.curl_multi_remove_handle(&multi_handle, &http_handle);
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_multi_remove_handle failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code,
|
||||
api.curl_multi_remove_handle(&multi_handle, &http_handle));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_multi_remove_handle failed: " +
|
||||
curl_code);
|
||||
}
|
||||
|
||||
// Cleanup http_handle
|
||||
status = api.curl_easy_cleanup(&http_handle);
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
|
||||
}
|
||||
SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&http_handle));
|
||||
|
||||
// Cleanup multi_handle
|
||||
curl_code = api.curl_multi_cleanup(&multi_handle);
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_multi_cleanup failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_multi_cleanup(&multi_handle));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_multi_cleanup failed: " + curl_code);
|
||||
}
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_global_cleanup();
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "curl_global_cleanup failed: " << status;
|
||||
SAPI_RETURN_IF_ERROR(api.curl_global_cleanup());
|
||||
|
||||
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;
|
||||
|
|
|
@ -15,87 +15,90 @@
|
|||
// Sandboxed version of multithread.c
|
||||
// Multithreaded HTTP GET requests
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <future> // NOLINT(build/c++11)
|
||||
#include <thread> // NOLINT(build/c++11)
|
||||
|
||||
#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
|
||||
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";
|
||||
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");
|
||||
}
|
||||
|
||||
absl::StatusOr<int> curl_code;
|
||||
int curl_code;
|
||||
|
||||
// Specify URL to get
|
||||
sapi::v::ConstCStr sapi_url(url.c_str());
|
||||
curl_code =
|
||||
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, sapi_url.PtrBefore());
|
||||
if (!curl_code.ok() || curl_code.value() != CURLE_OK) {
|
||||
LOG(FATAL) << "curl_easy_setopt_ptr failed: " << curl_code.status();
|
||||
SAPI_ASSIGN_OR_RETURN(curl_code, api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL,
|
||||
sapi_url.PtrBefore()));
|
||||
if (curl_code != 0) {
|
||||
return absl::UnavailableError("curl_easy_setopt_ptr failed: " + curl_code);
|
||||
}
|
||||
|
||||
// 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();
|
||||
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
|
||||
absl::Status status = api.curl_easy_cleanup(&curl);
|
||||
if (!status.ok()) {
|
||||
LOG(FATAL) << "curl_easy_cleanup failed: " << status;
|
||||
}
|
||||
// Cleanup curl easy handle
|
||||
SAPI_RETURN_IF_ERROR(api.curl_easy_cleanup(&curl));
|
||||
|
||||
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;
|
||||
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[]) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
absl::Status status;
|
||||
|
||||
// Initialize sandbox2 and sapi
|
||||
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;
|
||||
if (absl::Status status = Example5(); !status.ok()) {
|
||||
LOG(ERROR) << "Example5 failed: " << status.ToString();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "../sandbox.h" // NOLINT(build/include)
|
||||
#include "sandboxed_api/transaction.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class CurlTransaction : public sapi::Transaction {
|
||||
public:
|
||||
explicit CurlTransaction(std::unique_ptr<sapi::Sandbox> sandbox)
|
||||
|
@ -36,7 +38,7 @@ class CurlTransaction : public sapi::Transaction {
|
|||
};
|
||||
|
||||
absl::Status CurlTransaction::Main() {
|
||||
CurlApi api(sandbox());
|
||||
curl::CurlApi api(sandbox());
|
||||
|
||||
// Initialize the curl session
|
||||
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_ASSIGN_OR_RETURN(
|
||||
int setopt_url_code,
|
||||
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore()));
|
||||
TRANSACTION_FAIL_IF_NOT(setopt_url_code == CURLE_OK,
|
||||
api.curl_easy_setopt_ptr(&curl, curl::CURLOPT_URL, url.PtrBefore()));
|
||||
TRANSACTION_FAIL_IF_NOT(setopt_url_code == curl::CURLE_OK,
|
||||
"curl_easy_setopt_ptr failed");
|
||||
|
||||
// Perform the request
|
||||
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");
|
||||
|
||||
// Cleanup curl
|
||||
|
@ -63,8 +65,10 @@ absl::Status CurlTransaction::Main() {
|
|||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
CurlTransaction curl{std::make_unique<CurlSapiSandbox>()};
|
||||
CurlTransaction curl{std::make_unique<curl::CurlSapiSandbox>()};
|
||||
absl::Status status = curl.Run();
|
||||
CHECK(status.ok()) << "CurlTransaction failed";
|
||||
|
||||
|
|
|
@ -24,7 +24,9 @@
|
|||
#include "curl_sapi.sapi.h" // NOLINT(build/include)
|
||||
#include "sandboxed_api/sandbox2/util/bpf_helper.h"
|
||||
|
||||
class CurlSapiSandbox : public CurlSandbox {
|
||||
namespace curl {
|
||||
|
||||
class CurlSapiSandbox : public curl::CurlSandbox {
|
||||
protected:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder* policy_builder) override {
|
||||
|
@ -64,4 +66,6 @@ class CurlSapiSandbox : public CurlSandbox {
|
|||
}
|
||||
};
|
||||
|
||||
} // namespace curl
|
||||
|
||||
#endif // SANDBOX_H_
|
||||
|
|
|
@ -28,17 +28,17 @@
|
|||
int CurlTestUtils::port_;
|
||||
std::thread CurlTestUtils::server_thread_;
|
||||
|
||||
absl::Status CurlTestUtils::CurlTestSetUp() {
|
||||
absl::Status curl::tests::CurlTestUtils::CurlTestSetUp() {
|
||||
// Initialize sandbox2 and sapi
|
||||
sandbox_ = std::make_unique<CurlSapiSandbox>();
|
||||
sandbox_ = std::make_unique<curl::CurlSapiSandbox>();
|
||||
absl::Status init = sandbox_->Init();
|
||||
if (!init.ok()) {
|
||||
return init;
|
||||
}
|
||||
api_ = std::make_unique<CurlApi>(sandbox_.get());
|
||||
api_ = std::make_unique<curl::CurlApi>(sandbox_.get());
|
||||
|
||||
// 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()) {
|
||||
return curl_handle.status();
|
||||
}
|
||||
|
@ -51,23 +51,24 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
|
|||
|
||||
// Specify request URL
|
||||
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());
|
||||
if (!curl_code.ok()) {
|
||||
return curl_code.status();
|
||||
}
|
||||
if (curl_code.value() != CURLE_OK) {
|
||||
if (curl_code.value() != curl::CURLE_OK) {
|
||||
return absl::UnavailableError(
|
||||
"curl_easy_setopt_ptr returned with the error code " +
|
||||
curl_code.value());
|
||||
}
|
||||
|
||||
// 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()) {
|
||||
return curl_code.status();
|
||||
}
|
||||
if (curl_code.value() != CURLE_OK) {
|
||||
if (curl_code.value() != curl::CURLE_OK) {
|
||||
return absl::UnavailableError(
|
||||
"curl_easy_setopt_long returned with the error code " +
|
||||
curl_code.value());
|
||||
|
@ -83,12 +84,12 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
|
|||
sapi::v::RemotePtr remote_function_ptr(function_ptr);
|
||||
|
||||
// Set WriteToMemory as the write function
|
||||
curl_code = api_->curl_easy_setopt_ptr(curl_.get(), CURLOPT_WRITEFUNCTION,
|
||||
&remote_function_ptr);
|
||||
curl_code = api_->curl_easy_setopt_ptr(
|
||||
curl_.get(), curl::CURLOPT_WRITEFUNCTION, &remote_function_ptr);
|
||||
if (!curl_code.ok()) {
|
||||
return curl_code.status();
|
||||
}
|
||||
if (curl_code.value() != CURLE_OK) {
|
||||
if (curl_code.value() != curl::CURLE_OK) {
|
||||
return absl::UnavailableError(
|
||||
"curl_easy_setopt_ptr returned with the error code " +
|
||||
curl_code.value());
|
||||
|
@ -96,12 +97,12 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
|
|||
|
||||
// Pass memory chunk object to the callback
|
||||
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());
|
||||
if (!curl_code.ok()) {
|
||||
return curl_code.status();
|
||||
}
|
||||
if (curl_code.value() != CURLE_OK) {
|
||||
if (curl_code.value() != curl::CURLE_OK) {
|
||||
return absl::UnavailableError(
|
||||
"curl_easy_setopt_ptr returned with the error code " +
|
||||
curl_code.value());
|
||||
|
@ -110,18 +111,18 @@ absl::Status CurlTestUtils::CurlTestSetUp() {
|
|||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status CurlTestUtils::CurlTestTearDown() {
|
||||
absl::Status curl::tests::CurlTestUtils::CurlTestTearDown() {
|
||||
// Cleanup curl
|
||||
return api_->curl_easy_cleanup(curl_.get());
|
||||
}
|
||||
|
||||
absl::StatusOr<std::string> CurlTestUtils::PerformRequest() {
|
||||
absl::StatusOr<std::string> curl::tests::CurlTestUtils::PerformRequest() {
|
||||
// Perform the request
|
||||
absl::StatusOr<int> curl_code = api_->curl_easy_perform(curl_.get());
|
||||
if (!curl_code.ok()) {
|
||||
return curl_code.status();
|
||||
}
|
||||
if (curl_code.value() != CURLE_OK) {
|
||||
if (curl_code.value() != curl::CURLE_OK) {
|
||||
return absl::UnavailableError(
|
||||
"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
|
||||
|
||||
void CurlTestUtils::StartMockServer() {
|
||||
void curl::tests::CurlTestUtils::StartMockServer() {
|
||||
// Get the socket file descriptor
|
||||
int listening_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "sandboxed_api/util/flag.h"
|
||||
#include "sandboxed_api/util/status_matchers.h"
|
||||
|
||||
namespace curl::tests {
|
||||
|
||||
// Helper class that can be used to test Curl Sandboxed
|
||||
class CurlTestUtils {
|
||||
protected:
|
||||
|
@ -39,8 +41,8 @@ class CurlTestUtils {
|
|||
// Responds with the POST request fields to a POST request
|
||||
static void StartMockServer();
|
||||
|
||||
std::unique_ptr<CurlSapiSandbox> sandbox_;
|
||||
std::unique_ptr<CurlApi> api_;
|
||||
std::unique_ptr<curl::CurlSapiSandbox> sandbox_;
|
||||
std::unique_ptr<curl::CurlApi> api_;
|
||||
std::unique_ptr<sapi::v::RemotePtr> curl_;
|
||||
|
||||
static std::thread server_thread_;
|
||||
|
@ -52,4 +54,6 @@ class CurlTestUtils {
|
|||
std::unique_ptr<sapi::v::LenVal> chunk_;
|
||||
};
|
||||
|
||||
} // namespace curl::tests
|
||||
|
||||
#endif // TESTS_H_
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
|
||||
#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:
|
||||
void SetUp() override {
|
||||
// Start mock server, get port number and check for any error
|
||||
|
@ -38,9 +40,9 @@ TEST_F(CurlTest, EffectiveUrl) {
|
|||
// Get effective URL
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
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()));
|
||||
ASSERT_EQ(getinfo_code, CURLE_OK);
|
||||
ASSERT_EQ(getinfo_code, curl::CURLE_OK);
|
||||
|
||||
// Store effective URL in a string
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string effective_url,
|
||||
|
@ -74,9 +76,9 @@ TEST_F(CurlTest, ResponseCode) {
|
|||
// Get response code
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
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()));
|
||||
ASSERT_EQ(getinfo_code, CURLE_OK);
|
||||
ASSERT_EQ(getinfo_code, curl::CURLE_OK);
|
||||
|
||||
// Check response code
|
||||
ASSERT_EQ(response_code.GetValue(), 200);
|
||||
|
@ -120,19 +122,21 @@ TEST_F(CurlTest, POSTResponse) {
|
|||
// Set the size of the POST fields
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
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()));
|
||||
ASSERT_EQ(setopt_post_fields_size, CURLE_OK);
|
||||
ASSERT_EQ(setopt_post_fields_size, curl::CURLE_OK);
|
||||
|
||||
// Set the POST fields
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(
|
||||
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()));
|
||||
ASSERT_EQ(setopt_post_fields, CURLE_OK);
|
||||
ASSERT_EQ(setopt_post_fields, curl::CURLE_OK);
|
||||
|
||||
SAPI_ASSERT_OK_AND_ASSIGN(std::string response, PerformRequest());
|
||||
|
||||
// Compare response with expected response
|
||||
ASSERT_EQ(std::string(post_fields.GetData()), response);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue
Block a user