Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ behavior_changes:
hardware thread count and CPU affinity for worker thread calculation. Uses conservative rounding (floor)
to account for non-worker threads and prevent container throttling, which may reduce the total number of
connections.
- area: dynamic modules
change: |
The dynamic module ABI has been updated to support streaming body manipulation. This change also
fixed potential incorrect behavior when access or modify the request or response body. See
https://github.com/envoyproxy/envoy/issues/40918 for more details.

minor_behavior_changes:
# *Changes that may cause incompatibilities for some users, but should not for most*
Expand Down
189 changes: 136 additions & 53 deletions source/extensions/dynamic_modules/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1378,14 +1378,53 @@ void envoy_dynamic_module_callback_http_send_response_trailers(
// ------------------- HTTP Request/Response body callbacks --------------------

/**
* envoy_dynamic_module_callback_http_get_request_body_vector is called by the module to get the
* request body as a vector of buffers. The body is returned as an array of
* NOTE: Envoy will handle the request/response as a stream of data. Therefore, the body
* may not be available in its entirety before the end of stream flag is set. The Envoy all
* provides both the new received body and the buffered body (all historical
* data received so far) to the module. The module should be aware of this distinction
* when processing the body.
*
* NOTE: The new received body could only be available during the request/response body
* event hooks (the envoy_dynamic_module_on_http_filter_request_body and
* envoy_dynamic_module_on_http_filter_response_body).
* Outside of these hooks, the new received body will be unavailable.
*
* NOTE: The buffered body, however, is always available. But only the latest data processing filter
* in the filter chain could modify the buffered body. That is say, for given filter X, the filters
* after filter X in the filter chain should have not accessed the request body yet, then filter X
* could modify the buffered body safely.
*/

/**
* envoy_dynamic_module_callback_http_get_received_request_body_vector is called by the module to
* get the current request body as a vector of buffers. The body is returned as an array of
* envoy_dynamic_module_type_envoy_buffer.
*
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
* to store all the buffers. The module can use
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size to get the number of
* buffers before calling this function.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param result_buffer_vector is the pointer to the array of envoy_dynamic_module_type_envoy_buffer
* where the buffers of the body will be stored. The lifetime of the buffer is guaranteed until the
* end of the current event hook unless the setter callback is called.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_received_request_body_vector(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);

/**
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector is called by the module to
* get the buffered request body as a vector of buffers. The body is returned as an array of
* envoy_dynamic_module_type_envoy_buffer.
*
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
* to store all the buffers. The module can use
* envoy_dynamic_module_callback_http_get_request_body_vector_size to get the number of buffers
* before calling this function.
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size to get the number of
* buffers before calling this function.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
Expand All @@ -1394,115 +1433,159 @@ void envoy_dynamic_module_callback_http_send_response_trailers(
* end of the current event hook unless the setter callback is called.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_request_body_vector(
bool envoy_dynamic_module_callback_http_get_buffered_request_body_vector(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);

/**
* envoy_dynamic_module_callback_http_get_request_body_vector_size is called by the module to get
* the number of buffers in the request body. Combined with
* envoy_dynamic_module_callback_http_get_request_body_vector, this can be used to iterate over all
* buffers in the request body.
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size is called by the module
* to get the number of buffers in the current request body. Combined with
* envoy_dynamic_module_callback_http_get_received_request_body_vector, this can be used to iterate
* over all buffers in the request body.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param size is the pointer to the variable where the number of buffers will be stored.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_request_body_vector_size(
bool envoy_dynamic_module_callback_http_get_received_request_body_vector_size(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);

/**
* envoy_dynamic_module_callback_http_append_request_body is called by the module to append the
* given data to the end of the request body.
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size is called by the module
* to get the number of buffers in the buffered request body. Combined with
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector, this can be used to iterate
* over all buffers in the request body.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param size is the pointer to the variable where the number of buffers will be stored.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);

/**
* envoy_dynamic_module_callback_http_append_received_request_body is called by the module to append
* the given data to the end of the current request body.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param data is the pointer to the buffer of the data to be appended.
* @param length is the length of the data.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_append_request_body(
bool envoy_dynamic_module_callback_http_append_received_request_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);

/**
* envoy_dynamic_module_callback_http_drain_request_body is called by the module to drain the given
* number of bytes from the request body. If the number of bytes to drain is greater than
* the size of the body, the whole body will be drained.
* envoy_dynamic_module_callback_http_append_buffered_request_body is called by the module to append
* the given data to the end of the buffered request body.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param data is the pointer to the buffer of the data to be appended.
* @param length is the length of the data.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_append_buffered_request_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);

/**
* envoy_dynamic_module_callback_http_drain_received_request_body is called by the module to drain
* the given number of bytes from the current request body. If the number of bytes to drain is
* greater than the size of the body, the whole body will be drained.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param number_of_bytes is the number of bytes to drain.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_drain_request_body(
bool envoy_dynamic_module_callback_http_drain_received_request_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);

/**
* envoy_dynamic_module_callback_http_inject_request_body is called by the module to
* inject the given request data directly into the filter stream. This method should only be called
* from a scheduled event.
* envoy_dynamic_module_callback_http_drain_buffered_request_body is called by the module to drain
* the given number of bytes from the buffered request body. If the number of bytes to drain is
* greater than the size of the body, the whole body will be drained.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param data is the pointer to the buffer of the data to be injected.
* @param length is the length of the data.
* @param end_stream is true if this is the last data to be injected.
* @param number_of_bytes is the number of bytes to drain.
* @return true if the body is available, false otherwise.
*/
bool envoy_dynamic_module_callback_http_inject_request_body(
bool envoy_dynamic_module_callback_http_drain_buffered_request_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);

/**
* This is the same as envoy_dynamic_module_callback_http_get_received_request_body_vector, but for
* the current response body. See the comments on
* envoy_dynamic_module_callback_http_get_received_request_body_vector for more details.
*/
bool envoy_dynamic_module_callback_http_get_received_response_body_vector(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_buffer_module_ptr data, size_t length, bool end_stream);
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);

/**
* This is the same as envoy_dynamic_module_callback_http_get_request_body_vector, but for the
* response body. See the comments on envoy_dynamic_module_callback_http_get_request_body_vector
* for more details.
* This is the same as envoy_dynamic_module_callback_http_get_buffered_request_body_vector, but for
* the buffered response body. See the comments on
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector for more details.
*/
bool envoy_dynamic_module_callback_http_get_response_body_vector(
bool envoy_dynamic_module_callback_http_get_buffered_response_body_vector(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);

/**
* This is the same as envoy_dynamic_module_callback_http_get_request_body_vector_size, but for the
* response body. See the comments on
* envoy_dynamic_module_callback_http_get_request_body_vector_size for more details.
* This is the same as envoy_dynamic_module_callback_http_get_received_request_body_vector_size, but
* for the current response body. See the comments on
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size for more details.
*/
bool envoy_dynamic_module_callback_http_get_response_body_vector_size(
bool envoy_dynamic_module_callback_http_get_received_response_body_vector_size(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);

/**
* This is the same as envoy_dynamic_module_callback_http_append_request_body, but for the response
* body. See the comments on envoy_dynamic_module_callback_http_append_request_body for more
* details.
* This is the same as envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size, but
* for the buffered response body. See the comments on
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size for more details.
*/
bool envoy_dynamic_module_callback_http_append_response_body(
bool envoy_dynamic_module_callback_http_get_buffered_response_body_vector_size(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);

/**
* This is the same as envoy_dynamic_module_callback_http_append_received_request_body, but for the
* current response body. See the comments on
* envoy_dynamic_module_callback_http_append_received_request_body for more details.
*/
bool envoy_dynamic_module_callback_http_append_received_response_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);

/**
* This is the same as envoy_dynamic_module_callback_http_append_buffered_request_body, but for the
* buffered response body. See the comments on
* envoy_dynamic_module_callback_http_append_buffered_request_body for more details.
*/
bool envoy_dynamic_module_callback_http_append_buffered_response_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);

/**
* This is the same as envoy_dynamic_module_callback_http_drain_request_body, but for the response
* body. See the comments on envoy_dynamic_module_callback_http_drain_request_body for more details.
* This is the same as envoy_dynamic_module_callback_http_drain_received_request_body, but for the
* current response body. See the comments on
* envoy_dynamic_module_callback_http_drain_received_request_body for more details.
*/
bool envoy_dynamic_module_callback_http_drain_response_body(
bool envoy_dynamic_module_callback_http_drain_received_response_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);

/**
* envoy_dynamic_module_callback_http_inject_response_body is called by the module to
* inject the given response data directly into the filter stream. This method should only be called
* from a scheduled event.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
* corresponding HTTP filter.
* @param data is the pointer to the buffer of the data to be injected.
* @param length is the length of the data.
* @param end_stream is true if this is the last data to be injected.
* @return true if the body is available, false otherwise.
* This is the same as envoy_dynamic_module_callback_http_drain_buffered_request_body, but for the
* buffered response body. See the comments on
* envoy_dynamic_module_callback_http_drain_buffered_request_body for more details.
*/
bool envoy_dynamic_module_callback_http_inject_response_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_buffer_module_ptr data, size_t length, bool end_stream);
bool envoy_dynamic_module_callback_http_drain_buffered_response_body(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);

// ---------------------------- Metadata Callbacks -----------------------------

Expand Down
2 changes: 1 addition & 1 deletion source/extensions/dynamic_modules/abi_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace DynamicModules {
#endif
// This is the ABI version calculated as a sha256 hash of the ABI header files. When the ABI
// changes, this value must change, and the correctness of this value is checked by the test.
const char* kAbiVersion = "dcd3808436396000e681f7014dda187ca87708995367ea1374e4b3191281cb7c";
const char* kAbiVersion = "88c582df7667206f8f412bc65e2e2fef32ce66fc19e8d681d135b69400e989c9";

#ifdef __cplusplus
} // namespace DynamicModules
Expand Down
Loading