Skip to content

Commit 0cf83d2

Browse files
authored
dynamic modules: new body processing ABI (#41790)
1 parent 06dba59 commit 0cf83d2

File tree

9 files changed

+1014
-308
lines changed

9 files changed

+1014
-308
lines changed

changelogs/current.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ behavior_changes:
1414
hardware thread count and CPU affinity for worker thread calculation. Uses conservative rounding (floor)
1515
to account for non-worker threads and prevent container throttling, which may reduce the total number of
1616
connections.
17+
- area: dynamic modules
18+
change: |
19+
The dynamic module ABI has been updated to support streaming body manipulation. This change also
20+
fixed potential incorrect behavior when access or modify the request or response body. See
21+
https://github.com/envoyproxy/envoy/issues/40918 for more details.
1722
1823
minor_behavior_changes:
1924
# *Changes that may cause incompatibilities for some users, but should not for most*

source/extensions/dynamic_modules/abi.h

Lines changed: 136 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,14 +1378,53 @@ void envoy_dynamic_module_callback_http_send_response_trailers(
13781378
// ------------------- HTTP Request/Response body callbacks --------------------
13791379

13801380
/**
1381-
* envoy_dynamic_module_callback_http_get_request_body_vector is called by the module to get the
1382-
* request body as a vector of buffers. The body is returned as an array of
1381+
* NOTE: Envoy will handle the request/response as a stream of data. Therefore, the body may not be
1382+
* available in its entirety before the end of stream flag is set. The Envoy will provides both the
1383+
* received body (body pieces received in the latest event) and the buffered body (body pieces
1384+
* buffered so far) to the module. The module should be aware of this distinction when processing
1385+
* the body.
1386+
*
1387+
* NOTE: The received body could only be available during the request/response body
1388+
* event hooks (the envoy_dynamic_module_on_http_filter_request_body and
1389+
* envoy_dynamic_module_on_http_filter_response_body).
1390+
* Outside of these hooks, the received body will be unavailable.
1391+
*
1392+
* NOTE: The buffered body, however, is always available. But only the latest data processing filter
1393+
* in the filter chain could modify the buffered body. That is say for a given filter X, filter X
1394+
* can safely modify the buffered body if and only if the filters following filter X in the filter
1395+
* chain have not yet accessed the body.
1396+
*/
1397+
1398+
/**
1399+
* envoy_dynamic_module_callback_http_get_received_request_body_vector is called by the module to
1400+
* get the current request body as a vector of buffers. The body is returned as an array of
1401+
* envoy_dynamic_module_type_envoy_buffer.
1402+
*
1403+
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
1404+
* to store all the buffers. The module can use
1405+
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size to get the number of
1406+
* buffers before calling this function.
1407+
*
1408+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1409+
* corresponding HTTP filter.
1410+
* @param result_buffer_vector is the pointer to the array of envoy_dynamic_module_type_envoy_buffer
1411+
* where the buffers of the body will be stored. The lifetime of the buffer is guaranteed until the
1412+
* end of the current event hook unless the setter callback is called.
1413+
* @return true if the body is available, false otherwise.
1414+
*/
1415+
bool envoy_dynamic_module_callback_http_get_received_request_body_vector(
1416+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1417+
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
1418+
1419+
/**
1420+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector is called by the module to
1421+
* get the buffered request body as a vector of buffers. The body is returned as an array of
13831422
* envoy_dynamic_module_type_envoy_buffer.
13841423
*
13851424
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
13861425
* to store all the buffers. The module can use
1387-
* envoy_dynamic_module_callback_http_get_request_body_vector_size to get the number of buffers
1388-
* before calling this function.
1426+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size to get the number of
1427+
* buffers before calling this function.
13891428
*
13901429
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
13911430
* corresponding HTTP filter.
@@ -1394,115 +1433,159 @@ void envoy_dynamic_module_callback_http_send_response_trailers(
13941433
* end of the current event hook unless the setter callback is called.
13951434
* @return true if the body is available, false otherwise.
13961435
*/
1397-
bool envoy_dynamic_module_callback_http_get_request_body_vector(
1436+
bool envoy_dynamic_module_callback_http_get_buffered_request_body_vector(
13981437
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
13991438
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
14001439

14011440
/**
1402-
* envoy_dynamic_module_callback_http_get_request_body_vector_size is called by the module to get
1403-
* the number of buffers in the request body. Combined with
1404-
* envoy_dynamic_module_callback_http_get_request_body_vector, this can be used to iterate over all
1405-
* buffers in the request body.
1441+
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size is called by the module
1442+
* to get the number of buffers in the current request body. Combined with
1443+
* envoy_dynamic_module_callback_http_get_received_request_body_vector, this can be used to iterate
1444+
* over all buffers in the request body.
14061445
*
14071446
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
14081447
* corresponding HTTP filter.
14091448
* @param size is the pointer to the variable where the number of buffers will be stored.
14101449
* @return true if the body is available, false otherwise.
14111450
*/
1412-
bool envoy_dynamic_module_callback_http_get_request_body_vector_size(
1451+
bool envoy_dynamic_module_callback_http_get_received_request_body_vector_size(
14131452
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
14141453

14151454
/**
1416-
* envoy_dynamic_module_callback_http_append_request_body is called by the module to append the
1417-
* given data to the end of the request body.
1455+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size is called by the module
1456+
* to get the number of buffers in the buffered request body. Combined with
1457+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector, this can be used to iterate
1458+
* over all buffers in the request body.
1459+
*
1460+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1461+
* corresponding HTTP filter.
1462+
* @param size is the pointer to the variable where the number of buffers will be stored.
1463+
* @return true if the body is available, false otherwise.
1464+
*/
1465+
bool envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size(
1466+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
1467+
1468+
/**
1469+
* envoy_dynamic_module_callback_http_append_received_request_body is called by the module to append
1470+
* the given data to the end of the current request body.
14181471
*
14191472
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
14201473
* corresponding HTTP filter.
14211474
* @param data is the pointer to the buffer of the data to be appended.
14221475
* @param length is the length of the data.
14231476
* @return true if the body is available, false otherwise.
14241477
*/
1425-
bool envoy_dynamic_module_callback_http_append_request_body(
1478+
bool envoy_dynamic_module_callback_http_append_received_request_body(
14261479
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
14271480
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
14281481

14291482
/**
1430-
* envoy_dynamic_module_callback_http_drain_request_body is called by the module to drain the given
1431-
* number of bytes from the request body. If the number of bytes to drain is greater than
1432-
* the size of the body, the whole body will be drained.
1483+
* envoy_dynamic_module_callback_http_append_buffered_request_body is called by the module to append
1484+
* the given data to the end of the buffered request body.
1485+
*
1486+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1487+
* corresponding HTTP filter.
1488+
* @param data is the pointer to the buffer of the data to be appended.
1489+
* @param length is the length of the data.
1490+
* @return true if the body is available, false otherwise.
1491+
*/
1492+
bool envoy_dynamic_module_callback_http_append_buffered_request_body(
1493+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1494+
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
1495+
1496+
/**
1497+
* envoy_dynamic_module_callback_http_drain_received_request_body is called by the module to drain
1498+
* the given number of bytes from the current request body. If the number of bytes to drain is
1499+
* greater than the size of the body, the whole body will be drained.
14331500
*
14341501
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
14351502
* corresponding HTTP filter.
14361503
* @param number_of_bytes is the number of bytes to drain.
14371504
* @return true if the body is available, false otherwise.
14381505
*/
1439-
bool envoy_dynamic_module_callback_http_drain_request_body(
1506+
bool envoy_dynamic_module_callback_http_drain_received_request_body(
14401507
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
14411508

14421509
/**
1443-
* envoy_dynamic_module_callback_http_inject_request_body is called by the module to
1444-
* inject the given request data directly into the filter stream. This method should only be called
1445-
* from a scheduled event.
1510+
* envoy_dynamic_module_callback_http_drain_buffered_request_body is called by the module to drain
1511+
* the given number of bytes from the buffered request body. If the number of bytes to drain is
1512+
* greater than the size of the body, the whole body will be drained.
14461513
*
14471514
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
14481515
* corresponding HTTP filter.
1449-
* @param data is the pointer to the buffer of the data to be injected.
1450-
* @param length is the length of the data.
1451-
* @param end_stream is true if this is the last data to be injected.
1516+
* @param number_of_bytes is the number of bytes to drain.
14521517
* @return true if the body is available, false otherwise.
14531518
*/
1454-
bool envoy_dynamic_module_callback_http_inject_request_body(
1519+
bool envoy_dynamic_module_callback_http_drain_buffered_request_body(
1520+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
1521+
1522+
/**
1523+
* This is the same as envoy_dynamic_module_callback_http_get_received_request_body_vector, but for
1524+
* the current response body. See the comments on
1525+
* envoy_dynamic_module_callback_http_get_received_request_body_vector for more details.
1526+
*/
1527+
bool envoy_dynamic_module_callback_http_get_received_response_body_vector(
14551528
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1456-
envoy_dynamic_module_type_buffer_module_ptr data, size_t length, bool end_stream);
1529+
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
14571530

14581531
/**
1459-
* This is the same as envoy_dynamic_module_callback_http_get_request_body_vector, but for the
1460-
* response body. See the comments on envoy_dynamic_module_callback_http_get_request_body_vector
1461-
* for more details.
1532+
* This is the same as envoy_dynamic_module_callback_http_get_buffered_request_body_vector, but for
1533+
* the buffered response body. See the comments on
1534+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector for more details.
14621535
*/
1463-
bool envoy_dynamic_module_callback_http_get_response_body_vector(
1536+
bool envoy_dynamic_module_callback_http_get_buffered_response_body_vector(
14641537
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
14651538
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
14661539

14671540
/**
1468-
* This is the same as envoy_dynamic_module_callback_http_get_request_body_vector_size, but for the
1469-
* response body. See the comments on
1470-
* envoy_dynamic_module_callback_http_get_request_body_vector_size for more details.
1541+
* This is the same as envoy_dynamic_module_callback_http_get_received_request_body_vector_size, but
1542+
* for the current response body. See the comments on
1543+
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size for more details.
14711544
*/
1472-
bool envoy_dynamic_module_callback_http_get_response_body_vector_size(
1545+
bool envoy_dynamic_module_callback_http_get_received_response_body_vector_size(
14731546
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
14741547

14751548
/**
1476-
* This is the same as envoy_dynamic_module_callback_http_append_request_body, but for the response
1477-
* body. See the comments on envoy_dynamic_module_callback_http_append_request_body for more
1478-
* details.
1549+
* This is the same as envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size, but
1550+
* for the buffered response body. See the comments on
1551+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size for more details.
14791552
*/
1480-
bool envoy_dynamic_module_callback_http_append_response_body(
1553+
bool envoy_dynamic_module_callback_http_get_buffered_response_body_vector_size(
1554+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
1555+
1556+
/**
1557+
* This is the same as envoy_dynamic_module_callback_http_append_received_request_body, but for the
1558+
* current response body. See the comments on
1559+
* envoy_dynamic_module_callback_http_append_received_request_body for more details.
1560+
*/
1561+
bool envoy_dynamic_module_callback_http_append_received_response_body(
1562+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1563+
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
1564+
1565+
/**
1566+
* This is the same as envoy_dynamic_module_callback_http_append_buffered_request_body, but for the
1567+
* buffered response body. See the comments on
1568+
* envoy_dynamic_module_callback_http_append_buffered_request_body for more details.
1569+
*/
1570+
bool envoy_dynamic_module_callback_http_append_buffered_response_body(
14811571
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
14821572
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
14831573

14841574
/**
1485-
* This is the same as envoy_dynamic_module_callback_http_drain_request_body, but for the response
1486-
* body. See the comments on envoy_dynamic_module_callback_http_drain_request_body for more details.
1575+
* This is the same as envoy_dynamic_module_callback_http_drain_received_request_body, but for the
1576+
* current response body. See the comments on
1577+
* envoy_dynamic_module_callback_http_drain_received_request_body for more details.
14871578
*/
1488-
bool envoy_dynamic_module_callback_http_drain_response_body(
1579+
bool envoy_dynamic_module_callback_http_drain_received_response_body(
14891580
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
14901581

14911582
/**
1492-
* envoy_dynamic_module_callback_http_inject_response_body is called by the module to
1493-
* inject the given response data directly into the filter stream. This method should only be called
1494-
* from a scheduled event.
1495-
*
1496-
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1497-
* corresponding HTTP filter.
1498-
* @param data is the pointer to the buffer of the data to be injected.
1499-
* @param length is the length of the data.
1500-
* @param end_stream is true if this is the last data to be injected.
1501-
* @return true if the body is available, false otherwise.
1583+
* This is the same as envoy_dynamic_module_callback_http_drain_buffered_request_body, but for the
1584+
* buffered response body. See the comments on
1585+
* envoy_dynamic_module_callback_http_drain_buffered_request_body for more details.
15021586
*/
1503-
bool envoy_dynamic_module_callback_http_inject_response_body(
1504-
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1505-
envoy_dynamic_module_type_buffer_module_ptr data, size_t length, bool end_stream);
1587+
bool envoy_dynamic_module_callback_http_drain_buffered_response_body(
1588+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
15061589

15071590
// ---------------------------- Metadata Callbacks -----------------------------
15081591

source/extensions/dynamic_modules/abi_version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace DynamicModules {
66
#endif
77
// This is the ABI version calculated as a sha256 hash of the ABI header files. When the ABI
88
// changes, this value must change, and the correctness of this value is checked by the test.
9-
const char* kAbiVersion = "dcd3808436396000e681f7014dda187ca87708995367ea1374e4b3191281cb7c";
9+
const char* kAbiVersion = "52972436b8fd594556e76e1f9adfe1c22b7fd4a6bd3bbe6d9cdc8e0d7903dc68";
1010

1111
#ifdef __cplusplus
1212
} // namespace DynamicModules

0 commit comments

Comments
 (0)