Skip to content

Commit

Permalink
core: add native-platform callback implementation (#316)
Browse files Browse the repository at this point in the history
Co-authored-by: Jose Ulises Nino Rivera <junr03@users.noreply.github.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
  • Loading branch information
goaway and junr03 authored Aug 9, 2019
1 parent aeaaf36 commit da4d4d6
Show file tree
Hide file tree
Showing 16 changed files with 442 additions and 248 deletions.
2 changes: 1 addition & 1 deletion library/common/buffer/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Utility {
Buffer::InstancePtr transformData(envoy_data) { return nullptr; }

// TODO: implement this https://github.com/lyft/envoy-mobile/issues/284.
envoy_data transformData(Buffer::Instance&) { return {0, nullptr}; }
envoy_data transformData(Buffer::Instance&) { return envoy_nodata; }

} // namespace Utility
} // namespace Buffer
Expand Down
8 changes: 4 additions & 4 deletions library/common/http/dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@ void Dispatcher::DirectStreamCallbacks::onHeaders(HeaderMapPtr&& headers, bool e
if (end_stream) {
http_dispatcher_.removeStream(stream_);
}
observer_.on_headers_f(Utility::transformHeaders(*headers), end_stream, observer_.context);
observer_.on_headers(Utility::transformHeaders(*headers), end_stream, observer_.context);
}

void Dispatcher::DirectStreamCallbacks::onData(Buffer::Instance& data, bool end_stream) {
ENVOY_LOG(debug, "response data for stream (length={} end_stream={})", data.length(), end_stream);
if (end_stream) {
http_dispatcher_.removeStream(stream_);
}
observer_.on_data_f(Envoy::Buffer::Utility::transformData(data), end_stream, observer_.context);
observer_.on_data(Envoy::Buffer::Utility::transformData(data), end_stream, observer_.context);
}

void Dispatcher::DirectStreamCallbacks::onTrailers(HeaderMapPtr&& trailers) {
ENVOY_LOG(debug, "response trailers for stream:\n{}", *trailers);
http_dispatcher_.removeStream(stream_);
observer_.on_trailers_f(Utility::transformHeaders(*trailers), observer_.context);
observer_.on_trailers(Utility::transformHeaders(*trailers), observer_.context);
}

void Dispatcher::DirectStreamCallbacks::onReset() {
http_dispatcher_.removeStream(stream_);
observer_.on_error_f({ENVOY_STREAM_RESET, {0, nullptr}}, observer_.context);
observer_.on_error({ENVOY_STREAM_RESET, envoy_nodata}, observer_.context);
}

Dispatcher::DirectStream::DirectStream(AsyncClient::Stream& underlying_stream,
Expand Down
4 changes: 2 additions & 2 deletions library/common/http/header_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Utility {
static inline envoy_data copyEnvoyData(size_t length, const uint8_t* source) {
uint8_t* destination = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * length));
memcpy(destination, source, length);
return {length, destination};
return {length, destination, nullptr, nullptr};
}

std::string convertToString(envoy_data s) {
Expand All @@ -18,7 +18,7 @@ std::string convertToString(envoy_data s) {

HeaderMapPtr transformHeaders(envoy_headers headers) {
Http::HeaderMapPtr transformed_headers = std::make_unique<HeaderMapImpl>();
for (uint64_t i = 0; i < headers.length; i++) {
for (envoy_header_size_t i = 0; i < headers.length; i++) {
transformed_headers->addCopy(LowerCaseString(convertToString(headers.headers[i].key)),
convertToString(headers.headers[i].value));
}
Expand Down
1 change: 1 addition & 0 deletions library/common/include/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ envoy_package()

envoy_cc_library(
name = "c_types_interface",
srcs = ["c_types.cc"],
hdrs = ["c_types.h"],
repository = "@envoy",
)
16 changes: 16 additions & 0 deletions library/common/include/c_types.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "library/common/include/c_types.h"

// NOLINT(namespace-envoy)

void envoy_noop_release(void* context) { (void)context; }

void release_envoy_headers(envoy_headers headers) {
for (envoy_header_size_t i = 0; i < headers.length; i++) {
envoy_header header = headers.headers[i];
header.key.release(header.key.context);
header.value.release(header.value.context);
}
free(headers.headers);
}

const envoy_data envoy_nodata = {0, NULL, envoy_noop_release, NULL};
64 changes: 49 additions & 15 deletions library/common/include/c_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

// NOLINT(namespace-envoy)

Expand All @@ -28,12 +29,31 @@ typedef enum { ENVOY_SUCCESS, ENVOY_FAILURE } envoy_status_t;
*/
typedef enum { ENVOY_STREAM_RESET } envoy_error_code_t;

#ifdef __cplusplus
extern "C" { // release function
#endif
/**
* Callback indicating Envoy has drained the associated buffer.
*/
typedef void (*envoy_release_f)(void* context);

/**
* No-op callback.
*/
void envoy_noop_release(void* context);

#ifdef __cplusplus
} // release function
#endif

/**
* Holds raw binary data as an array of bytes.
*/
typedef struct {
uint64_t length;
size_t length;
const uint8_t* bytes;
envoy_release_f release;
void* context;
} envoy_data;

/**
Expand All @@ -56,19 +76,29 @@ typedef struct {
envoy_data value;
} envoy_header;

/**
* Consistent type for dealing with encodable/processable header counts.
*/
typedef int envoy_header_size_t;

/**
* Holds an HTTP header map as an array of envoy_header structs.
*/
typedef struct {
// Number of header elements in the array.
uint64_t length;
envoy_header_size_t length;
// Array of headers.
envoy_header* headers;
} envoy_headers;

/**
* Helper function to free/release memory associated with underlying headers.
*/
void release_envoy_headers(envoy_headers headers);

// Convenience constant to pass to function calls with no data.
// For example when sending a headers-only request.
const envoy_data envoy_nodata = {0, NULL};
extern const envoy_data envoy_nodata;

/**
* Error struct.
Expand All @@ -88,7 +118,7 @@ extern "C" { // function pointers
* @param context, contains the necessary state to carry out platform-specific dispatch and
* execution.
*/
typedef void (*on_headers)(envoy_headers headers, bool end_stream, void* context);
typedef void (*envoy_on_headers_f)(envoy_headers headers, bool end_stream, void* context);
/**
* Called when a data frame gets received on the async HTTP stream.
* This callback can be invoked multiple times if the data gets streamed.
Expand All @@ -97,30 +127,33 @@ typedef void (*on_headers)(envoy_headers headers, bool end_stream, void* context
* @param context, contains the necessary state to carry out platform-specific dispatch and
* execution.
*/
typedef void (*on_data)(envoy_data data, bool end_stream, void* context);
typedef void (*envoy_on_data_f)(envoy_data data, bool end_stream, void* context);
/**
* Called when all metadata get received on the async HTTP stream.
* Note that end stream is implied when on_metadata is called.
* Called when a metadata frame gets received on the async HTTP stream.
* Note that metadata frames are prohibited from ending a stream.
* @param metadata, the metadata received.
* @param context, contains the necessary state to carry out platform-specific dispatch and
* execution.
*/
typedef void (*on_metadata)(envoy_headers metadata, void* context);
typedef void (*envoy_on_metadata_f)(envoy_headers metadata, void* context);
/**
* Called when all trailers get received on the async HTTP stream.
* Note that end stream is implied when on_trailers is called.
* @param trailers, the trailers received.
* @param context, contains the necessary state to carry out platform-specific dispatch and
* execution.
*/
typedef void (*on_trailers)(envoy_headers trailers, void* context);
typedef void (*envoy_on_trailers_f)(envoy_headers trailers, void* context);
/**
* Called when the async HTTP stream has an error.
* @param envoy_error, the error received/caused by the async HTTP stream.
* @param context, contains the necessary state to carry out platform-specific dispatch and
* execution.
*/
typedef void (*on_error)(envoy_error error, void* context);
typedef void (*envoy_on_error_f)(envoy_error error, void* context);

// FIXME comments
typedef void (*envoy_on_complete_f)(void* context);

#ifdef __cplusplus
} // function pointers
Expand All @@ -130,10 +163,11 @@ typedef void (*on_error)(envoy_error error, void* context);
* Interface that can handle HTTP callbacks.
*/
typedef struct {
on_headers on_headers_f;
on_data on_data_f;
on_metadata on_metadata_f;
on_trailers on_trailers_f;
on_error on_error_f;
envoy_on_headers_f on_headers;
envoy_on_data_f on_data;
envoy_on_metadata_f on_metadata;
envoy_on_trailers_f on_trailers;
envoy_on_complete_f on_complete;
envoy_on_error_f on_error;
void* context; // Will be passed through to callbacks to provide dispatch and execution state.
} envoy_observer;
2 changes: 1 addition & 1 deletion library/common/main_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ envoy_status_t send_headers(envoy_stream_t stream_id, envoy_headers headers, boo

// TODO: implement.
envoy_status_t send_data(envoy_stream_t, envoy_data, bool) { return ENVOY_FAILURE; }
envoy_status_t send_metadata(envoy_stream_t, envoy_headers, bool) { return ENVOY_FAILURE; }
envoy_status_t send_metadata(envoy_stream_t, envoy_headers) { return ENVOY_FAILURE; }
envoy_status_t send_trailers(envoy_stream_t, envoy_headers) { return ENVOY_FAILURE; }
envoy_status_t locally_close_stream(envoy_stream_t) { return ENVOY_FAILURE; }
envoy_status_t reset_stream(envoy_stream_t) { return ENVOY_FAILURE; }
Expand Down
3 changes: 1 addition & 2 deletions library/common/main_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ envoy_status_t send_data(envoy_stream_t stream, envoy_data data, bool end_stream
* Send metadata over an HTTP stream. This method can be invoked multiple times.
* @param stream, the stream to send metadata over.
* @param metadata, the metadata to send.
* @param end_stream, supplies whether this is the last data in the stream.
* @return envoy_status_t, the resulting status of the operation.
*/
envoy_status_t send_metadata(envoy_stream_t stream, envoy_headers metadata, bool end_stream);
envoy_status_t send_metadata(envoy_stream_t stream, envoy_headers metadata);

/**
* Send trailers over an open HTTP stream. This method can only be invoked once per stream.
Expand Down
7 changes: 4 additions & 3 deletions library/objective-c/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ licenses(["notice"]) # Apache 2

exports_files([
"EnvoyEngine.h",
"EnvoyTypes.h",
])

objc_library(
name = "envoy_engine_objc_lib",
# TODO(@goaway): The headers here should really be in hdrs, but this causes them to be imported
# twice due to the way they're pulled into our swift framework rule. We should fix this to
# maintain a valid objc target.
srcs = [
"EnvoyEngine.mm",
"EnvoyEngine.m",
],
hdrs = [
"EnvoyEngine.h",
],
copts = ["-std=c++14"],
visibility = ["//visibility:public"],
deps = ["//library/common:envoy_main_interface_lib"],
)
Loading

0 comments on commit da4d4d6

Please sign in to comment.