mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Implement all curl methods
This commit is contained in:
parent
ac1112ae4d
commit
f47e1cc6ac
|
@ -19,6 +19,16 @@ project(curl_sandboxed)
|
|||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
option(CURL_SAPI_ENABLE_EXAMPLES "" ON)
|
||||
|
||||
# Add the callbacks used by the examples
|
||||
if (CURL_SAPI_ENABLE_EXAMPLES)
|
||||
list(APPEND CURL_SAPI_CALLBACKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/examples/callbacks.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/examples/callbacks.cc"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add folder containing the non-sandboxed custom curl library
|
||||
add_subdirectory(custom_curl)
|
||||
|
||||
|
@ -35,6 +45,9 @@ add_subdirectory(
|
|||
# Generate SAPI header
|
||||
add_sapi_library(curl_sapi
|
||||
|
||||
# List of all the methods in https://curl.haxx.se/libcurl/c/allfuncs.html
|
||||
# Some are added or modified because the original ones are not supported
|
||||
# by Sandboxed API (details can be found in custom_curl.h)
|
||||
FUNCTIONS curl_easy_cleanup
|
||||
curl_easy_duphandle
|
||||
curl_easy_escape
|
||||
|
@ -53,18 +66,66 @@ add_sapi_library(curl_sapi
|
|||
curl_easy_strerror
|
||||
curl_easy_unescape
|
||||
curl_easy_upkeep
|
||||
curl_free
|
||||
curl_getdate_sapi
|
||||
curl_global_cleanup
|
||||
curl_global_init
|
||||
curl_global_init_mem
|
||||
curl_global_sslset
|
||||
curl_mime_addpart
|
||||
curl_mime_data
|
||||
curl_mime_data_cb
|
||||
curl_mime_encoder
|
||||
curl_mime_filedata
|
||||
curl_mime_filename
|
||||
curl_mime_free
|
||||
curl_mime_headers
|
||||
curl_mime_init
|
||||
curl_mime_name
|
||||
curl_mime_subparts
|
||||
curl_mime_type
|
||||
curl_multi_add_handle
|
||||
curl_multi_assign
|
||||
curl_multi_cleanup
|
||||
curl_multi_fdset_sapi
|
||||
curl_multi_info_read
|
||||
curl_multi_init
|
||||
curl_multi_perform
|
||||
curl_multi_remove_handle
|
||||
curl_multi_setopt
|
||||
curl_multi_setopt_ptr
|
||||
curl_multi_setopt_long
|
||||
curl_multi_setopt_curl_off_t
|
||||
curl_multi_socket_action
|
||||
curl_multi_strerror
|
||||
curl_multi_timeout
|
||||
curl_multi_poll_sapi
|
||||
curl_multi_wait_sapi
|
||||
curl_multi_wakeup
|
||||
curl_share_init
|
||||
curl_share_setopt
|
||||
curl_share_setopt_ptr
|
||||
curl_share_setopt_long
|
||||
curl_share_strerror
|
||||
curl_slist_append
|
||||
curl_slist_free_all
|
||||
curl_url
|
||||
curl_url_cleanup
|
||||
curl_url_dup
|
||||
curl_url_get
|
||||
curl_url_set
|
||||
curl_version
|
||||
curl_version_info
|
||||
|
||||
INPUTS "custom_curl/curl/include/curl/curlver.h"
|
||||
"custom_curl/curl/include/curl/system.h"
|
||||
"custom_curl/curl/include/curl/curl.h"
|
||||
"custom_curl/curl/include/curl/easy.h"
|
||||
"custom_curl/custom_curl.h"
|
||||
INPUTS custom_curl/curl/include/curl/curl.h
|
||||
custom_curl/custom_curl.h
|
||||
|
||||
LIBRARY custom_curl
|
||||
LIBRARY custom_curl_and_callbacks
|
||||
|
||||
LIBRARY_NAME Curl
|
||||
|
||||
NAMESPACE ""
|
||||
|
||||
)
|
||||
|
||||
# Include generated SAPI header
|
||||
|
@ -73,4 +134,6 @@ target_include_directories(curl_sapi INTERFACE
|
|||
)
|
||||
|
||||
# Add examples
|
||||
if (CURL_SAPI_ENABLE_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
|
|
@ -1,22 +1,56 @@
|
|||
# Curl
|
||||
# Curl Sandboxed
|
||||
|
||||
This library is a sandboxed version of the original [curl](https://curl.haxx.se/libcurl/c/) C library, implemented using sandboxed-api.
|
||||
|
||||
## Supported methods
|
||||
|
||||
The library currently supports curl's [*Easy interface*](https://curl.haxx.se/libcurl/c/libcurl-easy.html). According to curl's website:
|
||||
|
||||
> The easy interface is a synchronous, efficient, quickly used and... yes, easy interface for file transfers.
|
||||
> Numerous applications have been built using this.
|
||||
|
||||
However, all of the methods using function pointers, are not yet supported.
|
||||
|
||||
## Examples
|
||||
|
||||
The `examples` directory contains the sandboxed versions of example source codes taken from [this](https://curl.haxx.se/libcurl/c/example.html) page on curl's website.
|
||||
This library is a sandboxed version of curl's C API, [libcurl](https://curl.haxx.se/libcurl/c/), implemented using Sandboxed API.
|
||||
|
||||
## Implementation details
|
||||
|
||||
Variadic methods are currently not supported by sandboxed-api. Because of this, the sandboxed header `custom_curl.h` wraps the curl library and explicitly defines the variadic methods.
|
||||
All of libcurl's methods are supported by the library. However, a few of these have different signatures defined in the sandboxed header `custom_curl.h`, which wraps and extends libcurl.
|
||||
|
||||
This is necessary because Sandboxed API sandboxes most of libcurl correctly, but encounters some issues when sandboxing a few methods. The simplest solution is wrapping these methods into wrapper methods that accomplish the same tasks but can also be sandboxed.
|
||||
|
||||
The next sections describe the issues encountered and contain some information on the signatures of the wrapper methods solving these issues.
|
||||
|
||||
#### Variadic methods
|
||||
|
||||
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
|
||||
|
||||
#### Methods with incomplete array arguments
|
||||
|
||||
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.
|
||||
|
||||
#### Methods with conflicts on the generated header
|
||||
|
||||
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 methods are:
|
||||
- `curl_getdate`. Use `curl_getdate_sapi` instead.
|
||||
- `curl_multi_fdset`. Use `curl_multi_fdset_sapi` instead.
|
||||
|
||||
#### Function pointers
|
||||
|
||||
The functions whose pointers will be passed to the library's methods (*callbacks*) can't be implemented in the files making use of the library, but must be in other files. These files must be compiled together with the library, and this is done by adding their absolute path to the cmake variable `CURL_SAPI_CALLBACKS`.
|
||||
|
||||
The pointers can then be obtained using an `RPCChannel` object, as shown in `example2.cc`.
|
||||
|
||||
## Examples
|
||||
|
||||
The `examples` directory contains the sandboxed versions of example source codes taken from [this page](https://curl.haxx.se/libcurl/c/example.html) on curl's website.
|
||||
|
||||
To build these examples when building the library, the cmake variable `CURL_SAPI_ENABLE_EXAMPLES` must be set to `ON`.
|
||||
|
||||
The `callbacks.h` and `callbacks.cc` files implement all the callbacks used by the examples.
|
||||
|
||||
For example, instead of using `curl_easy_setopt`, one of these methods can be used: `curl_easy_setopt_ptr`, `curl_easy_setopt_long` or `curl_easy_setopt_curl_off_t`.
|
|
@ -12,21 +12,25 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Wrapper library including curl,
|
||||
# adds the explicit versions of the variadic methods and the callbacks
|
||||
# The CURL_SAPI_CALLBACKS variable should contain the absolute paths of
|
||||
# all the files implementing the callbacks
|
||||
add_library(custom_curl_and_callbacks OBJECT
|
||||
custom_curl.h
|
||||
custom_curl.cc
|
||||
"${CURL_SAPI_CALLBACKS}"
|
||||
)
|
||||
set_target_properties(custom_curl_and_callbacks
|
||||
PROPERTIES LINKER_LANGUAGE C
|
||||
)
|
||||
|
||||
# Flags needed to build curl statically
|
||||
set(CURL_HIDDEN_SYMBOLS OFF)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
# Link the wrapper to the original curl library
|
||||
add_subdirectory(curl)
|
||||
|
||||
# Wrapper library including curl,
|
||||
# adds the explicit versions of the variadic methods
|
||||
add_library(custom_curl STATIC
|
||||
custom_curl.h
|
||||
custom_curl.cc
|
||||
)
|
||||
set_target_properties(custom_curl
|
||||
PROPERTIES LINKER_LANGUAGE C
|
||||
)
|
||||
target_link_libraries(custom_curl
|
||||
target_link_libraries(custom_curl_and_callbacks
|
||||
CURL::libcurl
|
||||
)
|
||||
|
|
|
@ -36,3 +36,59 @@ CURLcode curl_easy_getinfo_ptr(CURL* handle, CURLINFO option,
|
|||
void* parameter) {
|
||||
return curl_easy_getinfo(handle, option, parameter);
|
||||
}
|
||||
|
||||
time_t_sapi curl_getdate_sapi(char *datestring, time_t_sapi *now ) {
|
||||
return curl_getdate(datestring, now);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_fdset_sapi(CURLM *multi_handle,
|
||||
fd_set_sapi *read_fd_set,
|
||||
fd_set_sapi *write_fd_set,
|
||||
fd_set_sapi *exc_fd_set,
|
||||
int *max_fd) {
|
||||
return curl_multi_fdset(multi_handle, read_fd_set, write_fd_set, exc_fd_set,
|
||||
max_fd);
|
||||
}
|
||||
|
||||
CURLMcode curl_mutti_setopt_ptr(CURLM* handle, CURLMoption option,
|
||||
void* parameter) {
|
||||
return curl_multi_setopt(handle, option, parameter);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_setopt_long(CURLM* handle, CURLMoption option,
|
||||
long parameter) {
|
||||
return curl_multi_setopt(handle, option, parameter);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_setopt_curl_off_t(CURLM* handle, CURLMoption option,
|
||||
curl_off_t parameter) {
|
||||
return curl_multi_setopt(handle, option, parameter);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_poll_sapi(CURLM *multi_handle,
|
||||
struct curl_waitfd* extra_fds,
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *numfds) {
|
||||
return curl_multi_poll(multi_handle, extra_fds, extra_nfds, timeout_ms,
|
||||
numfds);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_wait_sapi(CURLM *multi_handle,
|
||||
struct curl_waitfd* extra_fds,
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *numfds) {
|
||||
return curl_multi_wait(multi_handle, extra_fds, extra_nfds, timeout_ms,
|
||||
numfds);
|
||||
}
|
||||
|
||||
CURLSHcode curl_share_setopt_ptr(CURLSH* handle, CURLSHoption option,
|
||||
void* parameter) {
|
||||
return curl_share_setopt(handle, option, parameter);
|
||||
}
|
||||
|
||||
CURLSHcode curl_share_setopt_long(CURLSH* handle, CURLSHoption option,
|
||||
long parameter) {
|
||||
return curl_share_setopt(handle, option, parameter);
|
||||
}
|
||||
|
|
|
@ -12,23 +12,76 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Wrapper for curl library used to implement variadic methods explicitly
|
||||
// Wrapper for curl library
|
||||
|
||||
#ifndef CUSTOM_CURL_H
|
||||
#define CUSTOM_CURL_H
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLcode curl_easy_setopt_ptr(CURL* handle, CURLoption option,
|
||||
void* parameter);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLcode curl_easy_setopt_long(CURL* handle, CURLoption option,
|
||||
long parameter);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLcode curl_easy_setopt_curl_off_t(CURL* handle, CURLoption option,
|
||||
curl_off_t parameter);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLcode curl_easy_getinfo_ptr(CURL* handle, CURLINFO option,
|
||||
void* parameter);
|
||||
|
||||
// The typedef and wrapper method are needed because the original method has
|
||||
// some conflicts in curl_sapi.sapi.h
|
||||
extern "C" typedef time_t time_t_sapi;
|
||||
extern "C" time_t_sapi curl_getdate_sapi(char *datestring, time_t_sapi *now );
|
||||
|
||||
// The typedef and wrapper method are needed because the original method has
|
||||
// some conflicts in curl_sapi.sapi.h
|
||||
extern "C" typedef fd_set fd_set_sapi;
|
||||
extern "C" CURLMcode curl_multi_fdset_sapi(CURLM *multi_handle,
|
||||
fd_set_sapi *read_fd_set,
|
||||
fd_set_sapi *write_fd_set,
|
||||
fd_set_sapi *exc_fd_set,
|
||||
int *max_fd);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLMcode curl_multi_setopt_ptr(CURLM* handle, CURLMoption option,
|
||||
void* parameter);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLMcode curl_multi_setopt_long(CURLM* handle, CURLMoption option,
|
||||
long parameter);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLMcode curl_multi_setopt_curl_off_t(CURLM* handle,
|
||||
CURLMoption option,
|
||||
curl_off_t parameter);
|
||||
|
||||
// The wrapper method is needed because incomplete array type is not supported
|
||||
extern "C" CURLMcode curl_multi_poll_sapi(CURLM *multi_handle,
|
||||
struct curl_waitfd* extra_fds,
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *numfds);
|
||||
|
||||
// The wrapper method is needed because incomplete array type is not supported
|
||||
extern "C" CURLMcode curl_multi_wait_sapi(CURLM *multi_handle,
|
||||
struct curl_waitfd* extra_fds,
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *numfds);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLSHcode curl_share_setopt_ptr(CURLSH* handle, CURLSHoption option,
|
||||
void* parameter);
|
||||
|
||||
// The wrapper method is needed to make the variadic argument explicit
|
||||
extern "C" CURLSHcode curl_share_setopt_long(CURLSH* handle, CURLSHoption option,
|
||||
long parameter);
|
||||
|
||||
#endif // CUSTOM_CURL_H
|
||||
|
|
|
@ -23,3 +23,39 @@ target_link_libraries(example1 PRIVATE
|
|||
curl_sapi
|
||||
sapi::sapi
|
||||
)
|
||||
|
||||
# Example 2: getinmemory.c
|
||||
add_executable(example2
|
||||
example2.cc
|
||||
)
|
||||
target_link_libraries(example2 PRIVATE
|
||||
curl_sapi
|
||||
sapi::sapi
|
||||
)
|
||||
|
||||
# Example 3: simplessl.c
|
||||
add_executable(example3
|
||||
example3.cc
|
||||
)
|
||||
target_link_libraries(example3 PRIVATE
|
||||
curl_sapi
|
||||
sapi::sapi
|
||||
)
|
||||
|
||||
# Example 4: multi-poll.c
|
||||
add_executable(example4
|
||||
example4.cc
|
||||
)
|
||||
target_link_libraries(example4 PRIVATE
|
||||
curl_sapi
|
||||
sapi::sapi
|
||||
)
|
||||
|
||||
# Example 5: multithread.c
|
||||
add_executable(example5
|
||||
example5.cc
|
||||
)
|
||||
target_link_libraries(example5 PRIVATE
|
||||
curl_sapi
|
||||
sapi::sapi
|
||||
)
|
41
oss-internship-2020/curl/examples/callbacks.cc
Normal file
41
oss-internship-2020/curl/examples/callbacks.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "callbacks.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// Function taken from curl's getinmemory.c
|
||||
size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb,
|
||||
void* userp) {
|
||||
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct* mem = (struct MemoryStruct*)userp;
|
||||
|
||||
char* ptr = (char*)realloc(mem->memory, mem->size + realsize + 1);
|
||||
if(ptr == NULL) { // Out of memory
|
||||
std::cout << "not enough memory (realloc returned NULL)\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
|
||||
}
|
28
oss-internship-2020/curl/examples/callbacks.h
Normal file
28
oss-internship-2020/curl/examples/callbacks.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CALLBACKS_H
|
||||
#define CALLBACKS_H
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
extern "C" struct MemoryStruct {
|
||||
char* memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
extern "C" size_t WriteMemoryCallback(void* contents, size_t size,
|
||||
size_t nmemb, void* userp);
|
||||
|
||||
#endif // CALLBACKS_H
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
// Sandboxed version of simple.c
|
||||
// Simple HTTP GET request
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
@ -35,31 +36,44 @@ class CurlApiSandboxEx1 : public CurlSandbox {
|
|||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
absl::Status status;
|
||||
sapi::StatusOr<CURL*> status_or_curl;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlApiSandboxEx1 sandbox;
|
||||
absl::Status status = sandbox.Init();
|
||||
status = sandbox.Init();
|
||||
assert(status.ok());
|
||||
CurlApi api(&sandbox);
|
||||
|
||||
sapi::StatusOr<CURL*> status_or_curl = api.curl_easy_init();
|
||||
// Initialize the curl session
|
||||
status_or_curl = api.curl_easy_init();
|
||||
assert(status_or_curl.ok());
|
||||
|
||||
sapi::v::RemotePtr curl(status_or_curl.value());
|
||||
assert(curl.GetValue()); // Checking curl != nullptr
|
||||
|
||||
// Specify URL to get
|
||||
sapi::v::ConstCStr url("http://example.com");
|
||||
sapi::StatusOr<int> 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());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set the library to follow a redirection
|
||||
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_FOLLOWLOCATION, 1l);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 0l);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Perform the request
|
||||
status_or_int = api.curl_easy_perform(&curl);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_easy_cleanup(&curl);
|
||||
assert(status.ok());
|
||||
|
||||
|
|
111
oss-internship-2020/curl/examples/example2.cc
Normal file
111
oss-internship-2020/curl/examples/example2.cc
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Sandboxed version of getinmemory.c
|
||||
// HTTP GET request using callbacks
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "curl_sapi.sapi.h"
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
|
||||
struct MemoryStruct {
|
||||
char* memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
class CurlApiSandboxEx2 : public CurlSandbox {
|
||||
private:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
// Return a new policy
|
||||
return sandbox2::PolicyBuilder()
|
||||
.DangerDefaultAllowAll()
|
||||
.AllowUnrestrictedNetworking()
|
||||
.AddDirectory("/lib")
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
||||
absl::Status status;
|
||||
sapi::StatusOr<CURL*> status_or_curl;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlApiSandboxEx2 sandbox;
|
||||
status = sandbox.Init();
|
||||
assert(status.ok());
|
||||
CurlApi api(&sandbox);
|
||||
|
||||
// Generate pointer to WriteMemoryCallback function
|
||||
sapi::RPCChannel rpcc(sandbox.comms());
|
||||
size_t (*_function_ptr)(void*, size_t, size_t, void*);
|
||||
status = rpcc.Symbol("WriteMemoryCallback", (void**)&_function_ptr);
|
||||
assert(status.ok());
|
||||
sapi::v::RemotePtr remote_function_ptr((void*)_function_ptr);
|
||||
|
||||
// Initialize the curl session
|
||||
status_or_curl = api.curl_easy_init();
|
||||
assert(status_or_curl.ok());
|
||||
sapi::v::RemotePtr curl(status_or_curl.value());
|
||||
assert(curl.GetValue()); // Checking curl != nullptr
|
||||
|
||||
// Specify URL to get
|
||||
sapi::v::ConstCStr url("http://example.com");
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set WriteMemoryCallback as the write function
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEFUNCTION,
|
||||
&remote_function_ptr);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Pass 'chunk' struct to the callback function
|
||||
sapi::v::Struct<MemoryStruct> chunk;
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_WRITEDATA,
|
||||
chunk.PtrBoth());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set a user agent
|
||||
sapi::v::ConstCStr user_agent("libcurl-agent/1.0");
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_USERAGENT,
|
||||
user_agent.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Perform the request
|
||||
status_or_int = api.curl_easy_perform(&curl);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Retrieve memory size
|
||||
sapi::v::Int size;
|
||||
size.SetRemote(&((MemoryStruct*)chunk.GetRemote())->size);
|
||||
status = sandbox.TransferFromSandboxee(&size);
|
||||
assert(status.ok());
|
||||
std::cout << "memory size: " << size.GetValue() << " bytes" << std::endl;
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_easy_cleanup(&curl);
|
||||
assert(status.ok());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
147
oss-internship-2020/curl/examples/example3.cc
Normal file
147
oss-internship-2020/curl/examples/example3.cc
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Sandboxed version of simplessl.c
|
||||
// HTTPS GET request
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "curl_sapi.sapi.h"
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
|
||||
class CurlApiSandboxEx3 : public CurlSandbox {
|
||||
|
||||
public:
|
||||
|
||||
CurlApiSandboxEx3(std::string ssl_certificate, std::string ssl_key,
|
||||
std::string ca_certificates)
|
||||
: ssl_certificate(ssl_certificate),
|
||||
ssl_key(ssl_key),
|
||||
ca_certificates(ca_certificates) {}
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
// Return a new policy
|
||||
return sandbox2::PolicyBuilder()
|
||||
.DangerDefaultAllowAll()
|
||||
.AllowUnrestrictedNetworking()
|
||||
.AddDirectory("/lib")
|
||||
.AddFile(ssl_certificate)
|
||||
.AddFile(ssl_key)
|
||||
.AddFile(ca_certificates)
|
||||
.BuildOrDie();
|
||||
}
|
||||
|
||||
std::string ssl_certificate;
|
||||
std::string ssl_key;
|
||||
std::string ca_certificates;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
absl::Status status;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<CURL*> status_or_curl;
|
||||
|
||||
// Get input parameters (should be absolute paths)
|
||||
assert(argc == 5);
|
||||
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
|
||||
CurlApiSandboxEx3 sandbox(ssl_certificate, ssl_key, ca_certificates);
|
||||
status = sandbox.Init();
|
||||
assert(status.ok());
|
||||
CurlApi api(&sandbox);
|
||||
|
||||
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
|
||||
status_or_int = api.curl_global_init(3l);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Initialize curl easy handle
|
||||
status_or_curl = api.curl_easy_init();
|
||||
assert(status_or_curl.ok());
|
||||
sapi::v::RemotePtr curl(status_or_curl.value());
|
||||
assert(curl.GetValue()); // Checking curl != nullptr
|
||||
|
||||
// Specify URL to get (using HTTPS)
|
||||
sapi::v::ConstCStr url("https://example.com");
|
||||
status_or_int =
|
||||
api.curl_easy_setopt_ptr(&curl, CURLOPT_URL, url.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set the SSL certificate type to "PEM"
|
||||
sapi::v::ConstCStr ssl_cert_type("PEM");
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERTTYPE,
|
||||
ssl_cert_type.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set the certificate for client authentication
|
||||
sapi::v::ConstCStr sapi_ssl_certificate(ssl_certificate.c_str());
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLCERT,
|
||||
sapi_ssl_certificate.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set the private key for client authentication
|
||||
sapi::v::ConstCStr sapi_ssl_key(ssl_key.c_str());
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_SSLKEY,
|
||||
sapi_ssl_key.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set the password used to protect the private key
|
||||
sapi::v::ConstCStr sapi_ssl_key_password(ssl_key_password.c_str());
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_KEYPASSWD,
|
||||
sapi_ssl_key_password.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Set the file with the certificates vaildating the server
|
||||
sapi::v::ConstCStr sapi_ca_certificates(ca_certificates.c_str());
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_CAINFO,
|
||||
sapi_ca_certificates.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Verify the authenticity of the server
|
||||
status_or_int = api.curl_easy_setopt_long(&curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Perform the request
|
||||
status_or_int = api.curl_easy_perform(&curl);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Cleanup curl easy handle
|
||||
status = api.curl_easy_cleanup(&curl);
|
||||
assert(status.ok());
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_global_cleanup();
|
||||
assert(status.ok());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
122
oss-internship-2020/curl/examples/example4.cc
Normal file
122
oss-internship-2020/curl/examples/example4.cc
Normal file
|
@ -0,0 +1,122 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Sandboxed version of multi-poll.c
|
||||
// HTTP GET request with polling
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "curl_sapi.sapi.h"
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
|
||||
class CurlApiSandboxEx4 : public CurlSandbox {
|
||||
private:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
// Return a new policy
|
||||
return sandbox2::PolicyBuilder()
|
||||
.DangerDefaultAllowAll()
|
||||
.AllowUnrestrictedNetworking()
|
||||
.AddDirectory("/lib")
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
||||
absl::Status status;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
sapi::StatusOr<CURL*> status_or_curl;
|
||||
sapi::StatusOr<CURLM*> status_or_curlm;
|
||||
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlApiSandboxEx4 sandbox;
|
||||
status = sandbox.Init();
|
||||
assert(status.ok());
|
||||
CurlApi api(&sandbox);
|
||||
|
||||
// Number of running handles
|
||||
sapi::v::Int still_running(1);
|
||||
|
||||
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
|
||||
status_or_int = api.curl_global_init(3l);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Initialize http_handle
|
||||
status_or_curl = api.curl_easy_init();
|
||||
assert(status_or_curl.ok());
|
||||
sapi::v::RemotePtr http_handle(status_or_curl.value());
|
||||
assert(http_handle.GetValue()); // Checking http_handle != nullptr
|
||||
|
||||
// Specify URL to get
|
||||
sapi::v::ConstCStr url("http://example.com");
|
||||
status_or_int =
|
||||
api.curl_easy_setopt_ptr(&http_handle, CURLOPT_URL, url.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Initialize multi_handle
|
||||
status_or_curlm = api.curl_multi_init();
|
||||
assert(status_or_curlm.ok());
|
||||
sapi::v::RemotePtr multi_handle(status_or_curlm.value());
|
||||
assert(multi_handle.GetValue()); // Checking multi_handle != nullptr
|
||||
|
||||
// Add http_handle to the multi stack
|
||||
status_or_int = api.curl_multi_add_handle(&multi_handle, &http_handle);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
while (still_running.GetValue()) {
|
||||
|
||||
sapi::v::Int numfds(0);
|
||||
|
||||
// Perform the request
|
||||
status_or_int = api.curl_multi_perform(&multi_handle,
|
||||
still_running.PtrBoth());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
if (still_running.GetValue()) {
|
||||
// Wait for an event or timeout
|
||||
sapi::v::NullPtr null_ptr;
|
||||
status_or_int = api.curl_multi_poll_sapi(&multi_handle, &null_ptr, 0,
|
||||
1000, numfds.PtrBoth());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLM_OK);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove http_handle from the multi stack
|
||||
status_or_int = api.curl_multi_remove_handle(&multi_handle, &http_handle);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Cleanup http_handle
|
||||
status = api.curl_easy_cleanup(&http_handle);
|
||||
assert(status.ok());
|
||||
|
||||
// Cleanup multi_handle
|
||||
status_or_int = api.curl_multi_cleanup(&multi_handle);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_global_cleanup();
|
||||
assert(status.ok());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
125
oss-internship-2020/curl/examples/example5.cc
Normal file
125
oss-internship-2020/curl/examples/example5.cc
Normal file
|
@ -0,0 +1,125 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Sandboxed version of multithread.c
|
||||
// Multithreaded HTTP GET requests
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "curl_sapi.sapi.h"
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
|
||||
class CurlApiSandboxEx5 : public CurlSandbox {
|
||||
private:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||
sandbox2::PolicyBuilder*) override {
|
||||
// Return a new policy
|
||||
return sandbox2::PolicyBuilder()
|
||||
.DangerDefaultAllowAll()
|
||||
.AllowUnrestrictedNetworking()
|
||||
.AddDirectory("/lib")
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
struct thread_args {
|
||||
const char* url;
|
||||
CurlApi* api;
|
||||
};
|
||||
|
||||
constexpr int kThreadsnumber = 4;
|
||||
|
||||
void *pull_one_url(void* args) {
|
||||
|
||||
absl::Status status;
|
||||
sapi::StatusOr<CURL*> status_or_curl;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
|
||||
CurlApi& api = *((thread_args*)args)->api;
|
||||
|
||||
// Initialize the curl session
|
||||
status_or_curl = api.curl_easy_init();
|
||||
assert(status_or_curl.ok());
|
||||
sapi::v::RemotePtr curl(status_or_curl.value());
|
||||
assert(curl.GetValue()); // Checking curl != nullptr
|
||||
|
||||
// Specify URL to get
|
||||
sapi::v::ConstCStr sapi_url(((thread_args*)args)->url);
|
||||
status_or_int = api.curl_easy_setopt_ptr(&curl, CURLOPT_URL,
|
||||
sapi_url.PtrBefore());
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Perform the request
|
||||
status_or_int = api.curl_easy_perform(&curl);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_easy_cleanup(&curl);
|
||||
assert(status.ok());
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
const char * const urls[kThreadsnumber] = {
|
||||
"http://example.com",
|
||||
"http://example.edu",
|
||||
"http://example.net",
|
||||
"http://example.org"
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
pthread_t tid[kThreadsnumber];
|
||||
|
||||
absl::Status status;
|
||||
sapi::StatusOr<int> status_or_int;
|
||||
|
||||
// Initialize sandbox2 and sapi
|
||||
CurlApiSandboxEx5 sandbox;
|
||||
status = sandbox.Init();
|
||||
assert(status.ok());
|
||||
CurlApi api(&sandbox);
|
||||
|
||||
// Initialize curl (CURL_GLOBAL_DEFAULT = 3)
|
||||
status_or_int = api.curl_global_init(3l);
|
||||
assert(status_or_int.ok());
|
||||
assert(status_or_int.value() == CURLE_OK);
|
||||
|
||||
// Create the threads
|
||||
for(int i = 0; i < kThreadsnumber; ++i) {
|
||||
thread_args args = {urls[i], &api};
|
||||
int error = pthread_create(&tid[i], NULL, pull_one_url, (void*)&args);
|
||||
assert(!error);
|
||||
std::cout << "Thread "<< i << " gets " << urls[i] << std::endl;
|
||||
}
|
||||
|
||||
// Join the threads
|
||||
for(int i = 0; i< kThreadsnumber; i++) {
|
||||
pthread_join(tid[i], NULL);
|
||||
std::cout << "Thread " << i << " terminated" << std::endl;
|
||||
}
|
||||
|
||||
// Cleanup curl
|
||||
status = api.curl_global_cleanup();
|
||||
assert(status.ok());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user