Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make HTTP support optional #225

Merged
merged 2 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 30 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ include(cmake/variables.cmake)
include(CMakeDependentOption)
include(GNUInstallDirs)

option(TLSUV_HTTP "enable HTTP/websocket support" ON)

set(TLSUV_TLSLIB "openssl" CACHE STRING "TLS implementation library (openssl|mbedtls)")

if(NOT (TLSUV_TLSLIB STREQUAL "openssl" OR TLSUV_TLSLIB STREQUAL "mbedtls"))
Expand All @@ -27,25 +29,29 @@ cmake_dependent_option(USE_MBEDTLS "Use mbedTLS" ON "TLSUV_TLSLIB STREQUAL mbedt

set(tlsuv_sources
src/tlsuv.c
# src/bio.c
src/http.c
src/tcp_src.c
src/um_debug.c
src/um_debug.h
src/websocket.c
src/http_req.c
src/tls_link.c
src/base64.c
src/tls_engine.c
src/compression.c
src/compression.h
src/p11.c
src/p11.h
src/util.h
src/connector.c
src/alloc.c
)

if (TLSUV_HTTP)
list(APPEND tlsuv_sources
src/http.c
src/tcp_src.c
src/websocket.c
src/http_req.c
src/tls_link.c
src/compression.c
src/compression.h
)
endif (TLSUV_HTTP)

if(USE_OPENSSL)
set(tlsImpl openssl)
FILE(GLOB ssl_files src/openssl/*)
Expand Down Expand Up @@ -80,9 +86,6 @@ else()
find_library(TLSUV_LIBUV_LIB uv_a NAMES uv)
endif()

find_package(llhttp CONFIG REQUIRED)

add_subdirectory(deps)

add_library(tlsuv STATIC
${tlsuv_sources}
Expand All @@ -101,14 +104,24 @@ target_include_directories(tlsuv
${CMAKE_CURRENT_SOURCE_DIR}/src
)

find_package(ZLIB REQUIRED)

target_link_libraries(tlsuv
PUBLIC llhttp::llhttp_static
PRIVATE ${TLSUV_LIBUV_LIB}
PUBLIC uv_link
PRIVATE ZLIB::ZLIB
)
)


if (TLSUV_HTTP)
find_package(llhttp CONFIG REQUIRED)

add_subdirectory(deps)

find_package(ZLIB REQUIRED)

target_link_libraries(tlsuv
PUBLIC llhttp::llhttp_static
PUBLIC uv_link
PRIVATE ZLIB::ZLIB
)
endif (TLSUV_HTTP)

if (APPLE)
target_link_libraries(tlsuv PRIVATE
Expand Down
2 changes: 1 addition & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"hidden": true,
"cacheVariables": {
"tlsuv_DEVELOPER_MODE": "ON",
"VCPKG_MANIFEST_FEATURES": "test;samples"
"VCPKG_MANIFEST_FEATURES": "http;test;samples"
}
},
{
Expand Down
101 changes: 49 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ or [OpenSSL](https://www.openssl.org/)
## Features
* async TLS over TCP
* flexible TLS engine support
* [pkcs#11](https://en.wikipedia.org/wiki/PKCS_11) support with default(mbedTLS) engine
* HTTP and websocket clients
* [pkcs#11](https://en.wikipedia.org/wiki/PKCS_11) support with default(OpenSSL) engine

## API
API is attempted to be consistent with [libuv API](http://docs.libuv.org/en/v1.x/api.html)
Expand All @@ -20,65 +21,61 @@ API is attempted to be consistent with [libuv API](http://docs.libuv.org/en/v1.x
* Darwin/MacOS
* Windows

## Using in your project
The simplest way to integrate `tlsuv` in your project is to include it in your CMake build
with [`FetchContent`](https://cmake.org/cmake/help/latest/module/FetchContent.html)

```cmake
FetchContent_Declare(tlsuv
GIT_REPOSITORY https://github.com/openziti/tlsuv.git
GIT_TAG v0.29.5 # use latest release version
)
FetchContent_MakeAvailable(tlsuv)

target_link_libraries(your_app PRIVATE tlsuv)
```

## Selectable Features
HTTP support is a selectable feature (ON by default) and can be disabled by adding `-DTLSUV_HTTP=OFF` during CMake
configuration step. This will also reduce dependencies list.

## Dependencies
TLSUV depends on the following libraries:

| Library | Notes |
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [libuv](https://github.com/libuv/libuv) | |
| TLS | [OpenSSL](https://github.com/openssl/openssl)(default) or<br/> [mbedTLS](https://github.com/mbedtls/mbedtls)(`TLSUV_TLSLIB=mbedtls`). <br/>Some features are only available with OpenSSL |
| [llhttp](https://github.com/nodejs/llhttp) | only with HTTP enabled |
| [zlib](https://github.com/madler/zlib) | only with HTTP enabled |


CMake configuration process will attempt to resolve the above dependencies via `find_package()` it is up to consuming project
to provide them.

## TLS engine support (BYFE - Bring Your Favorite Engine)
If using mbedTLS does not work for you,
for example you're already using another TLS library for your project, there is a way to use it inside _uv-mbed_.
If either of two TLS library options are not working for, there is a mechanism to dynamically provide TLS implementation.

For example, you're already using another TLS library for your project, there is a way to use it inside _tlsuv_.
Two API [interfaces are defined](include/tlsuv/tls_engine.h) for that purpose:

- `tls_context` is roughly equivalent to `mbedtls_ssl_config` or `SSL_CTX`in OpenSSL and is used to create instances
of `tls_engine` for individual connections
- `tls_engine` is an object for handling handshake and encryption for a single connection.
Similar in purpose to `mbedtls_ssl_ctx` or `SSL` in OpenSSL

### OpenSSL use
*UPDATE* OpenSSL is now supported _out-of-the-box_. You can enable it by adding `-DUSE_OPENSSL=on` option
to your CMake generation step. It requires to have OpenSSL installed on your build system as well as available at
runtime as a shared library.

## Build
* Dependencies (libuv, and mbedTLS) are specified as [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules).
Make sure to get them with `$ git submodule update --init --recursive`
* We use [Cmake](https://cmake.org) as our build system.
Any of the standard generators(`makefile`, [`ninja`](https://ninja-build.org/))
should be working fine, let us know if you see any issues.

#### Windows
Building on windows:
* ensure cmake is on your path
* cd to root of checkout
* mkdir build
* cd build
* after checking out the project - open a visual studio command prompt
* if vs 2017 issue: `cmake -G "Visual Studio 15 2017" .. -DCMAKE_INSTALL_INCLUDEDIR=include`
* if vs 2019 issue: `cmake -G "Visual Studio 16 2019" .. -DCMAKE_INSTALL_INCLUDEDIR=include`
* test building with cmake/msbuild:
* `cmake --build . --config Debug`
* execute the sample application and verify the output looks like the following (note: exe is at sample\Debug\sample.exe)

c:\git\uv-mbed\2017>sample\Debug\sample.exe
request sent 0
HTTP/1.1 301 Moved Permanently
Location: https://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Fri, 24 May 2019 05:30:28 GMT
Expires: Sun, 23 Jun 2019 05:30:28 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Alt-Svc: quic=":443"; ma=2592000; v="46,44,43,39"
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
=====================
connection closed
mbed is closed
## Building standalone
See [development](HACKING.md) instruction for building this project standalone
for checking out samples, or contributing.


## Getting Help

------------
Please use these community resources for getting help. We use GitHub [issues](https://github.com/openziti/tlsuv/issues)
for tracking bugs and feature requests and have limited bandwidth to address them.

- Read [the docs](https://docs.openziti.io/)
- Ask a question on [Discourse](https://openziti.discourse.group/)

Copyright&copy; 2018-2024. NetFoundry, Inc.
2 changes: 0 additions & 2 deletions include/tlsuv/tlsuv.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
#include <uv.h>

#include "connector.h"
#include "tcp_src.h"
#include "tls_engine.h"
#include "tls_link.h"
#include "queue.h"

#ifdef __cplusplus
Expand Down
42 changes: 25 additions & 17 deletions sample/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,34 @@ if (WIN32)
find_package(unofficial-getopt-win32 REQUIRED)
endif()

add_executable(sample sample.c common.c)
target_link_libraries(sample PUBLIC tlsuv)
add_library(common OBJECT common.c)
target_link_libraries(common PUBLIC tlsuv)
target_compile_definitions(common PUBLIC $<$<BOOL:${TLSUV_HTTP}>:TLSUV_HTTP>)

add_executable(engine_test engine_test.c common.c)
target_link_libraries(engine_test PUBLIC tlsuv)
message(NOTICE "TLSUV_HTTP = ${TLSUV_HTTP}")

add_executable(sample-cf sample-cf.c common.c)
target_link_libraries(sample-cf PUBLIC tlsuv)
add_executable(sample sample.c)
target_link_libraries(sample PUBLIC tlsuv common)

add_executable(um-curl um-curl.c common.c)
if (WIN32)
target_link_libraries(um-curl PRIVATE unofficial::getopt-win32::getopt)
endif()
target_link_libraries(um-curl PUBLIC tlsuv)
add_executable(engine_test engine_test.c)
target_link_libraries(engine_test PUBLIC tlsuv common)

add_executable(sample-cf sample-cf.c)
target_link_libraries(sample-cf PUBLIC tlsuv common)

if (TLSUV_HTTP)
add_executable(um-curl um-curl.c)
if (WIN32)
target_link_libraries(um-curl PRIVATE unofficial::getopt-win32::getopt)
endif()
target_link_libraries(um-curl PUBLIC tlsuv common)

add_executable(repeat-fetch repeat-fetch.c common.c)
target_link_libraries(repeat-fetch PUBLIC tlsuv)
add_executable(repeat-fetch repeat-fetch.c)
target_link_libraries(repeat-fetch PUBLIC tlsuv common)

add_executable(ws-client ws-client.c common.c)
target_link_libraries(ws-client PUBLIC tlsuv)
add_executable(ws-client ws-client.c)
target_link_libraries(ws-client PUBLIC tlsuv common)

add_executable(http-ping http-ping.c common.c)
target_link_libraries(http-ping PUBLIC tlsuv)
add_executable(http-ping http-ping.c)
target_link_libraries(http-ping PUBLIC tlsuv common)
endif (TLSUV_HTTP)
5 changes: 5 additions & 0 deletions sample/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// limitations under the License.


#include <time.h>
#include <stdio.h>
#include "common.h"

void logger(int level, const char *file, unsigned int line, const char *msg) {
Expand All @@ -26,6 +28,7 @@ void logger(int level, const char *file, unsigned int line, const char *msg) {
#endif
}

#if defined(TLSUV_HTTP)
void resp_cb(tlsuv_http_resp_t *resp, void *data) {
if (resp->req->client->tls) {
printf("Using %s\n", resp->req->client->tls->version());
Expand Down Expand Up @@ -54,3 +57,5 @@ void body_cb(tlsuv_http_req_t *req, char *body, ssize_t len) {
printf("%*.*s", (int) len, (int) len, body);
}
}

#endif
4 changes: 4 additions & 0 deletions sample/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
#ifndef UV_MBED_COMMON_H
#define UV_MBED_COMMON_H

#if defined(TLSUV_HTTP)
#include <tlsuv/http.h>

void resp_cb(tlsuv_http_resp_t *resp, void *data);
void body_cb(tlsuv_http_req_t *req, char *body, ssize_t len);
#endif

void logger(int level, const char *file, unsigned int line, const char *msg);

#endif //UV_MBED_COMMON_H
21 changes: 15 additions & 6 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,20 @@ if (USE_OPENSSL)
endif()

set(test_srcs
http_tests.cpp
ws_tests.cpp
engine_tests.cpp
stream_tests.cpp
compression_tests.cpp
key_tests.cpp
connector_tests.cpp
)

if (TLSUV_HTTP)
list(APPEND test_srcs
http_tests.cpp
ws_tests.cpp
compression_tests.cpp
)
endif()


add_executable(all_tests
all_tests.cpp ${test_srcs})
Expand Down Expand Up @@ -94,6 +99,10 @@ add_custom_target(run-tests
include(CTest)
add_test(key_tests all_tests [key])
add_test(engine_tests all_tests [engine])
add_test(http_tests all_tests [http])
add_test(ws_tests all_tests [websocket])
add_test(uv_mbed all_tests [stream])
add_test(stream_tests all_tests [stream])

if (TLSUV_HTTP)
add_test(http_tests all_tests [http])
add_test(ws_tests all_tests [websocket])
endif (TLSUV_HTTP)

4 changes: 4 additions & 0 deletions tests/fixtures.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
#define UV_MBED_FIXTURES_H

#include "catch.hpp"
#include "tlsuv/tls_engine.h"
#include <uv.h>


extern tls_context *testServerTLS();

template<typename T> T* t_alloc() {
return (T*)calloc(1, sizeof(T));
}
Expand Down
19 changes: 0 additions & 19 deletions tests/http_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,7 @@ std::string testServerURL(const string& type) {
return "";
}

class testServer {
public:
tls_context* TLS() {
return tls;
}
testServer() {
tls = default_tls_context(test_server_CA, strlen(test_server_CA));
}

~testServer() {
tls->free_ctx(tls);
}
private:
tls_context* tls;
};

tls_context* testServerTLS() {
static testServer srv;
return srv.TLS();
}

static const tlsuv_connector_t *proxy = tlsuv_new_proxy_connector(tlsuv_PROXY_HTTP, "127.0.0.1", "13128");

Expand Down
Loading
Loading