Skip to content

Commit 2a342c9

Browse files
committed
dynamic modules: new body processing ABI (envoyproxy#41790)
1 parent da2e9e1 commit 2a342c9

File tree

8 files changed

+1013
-307
lines changed

8 files changed

+1013
-307
lines changed

changelogs/current.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ date: Pending
22

33
behavior_changes:
44
# *Changes that are expected to cause an incompatibility if applicable; deployment changes are likely required*
5+
- area: dynamic modules
6+
change: |
7+
The dynamic module ABI has been updated to support streaming body manipulation. This change also
8+
fixed potential incorrect behavior when access or modify the request or response body. See
9+
https://github.com/envoyproxy/envoy/issues/40918 for more details.
510
611
minor_behavior_changes:
712
# *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
@@ -1348,14 +1348,53 @@ void envoy_dynamic_module_callback_http_send_response_trailers(
13481348
// ------------------- HTTP Request/Response body callbacks --------------------
13491349

13501350
/**
1351-
* envoy_dynamic_module_callback_http_get_request_body_vector is called by the module to get the
1352-
* request body as a vector of buffers. The body is returned as an array of
1351+
* NOTE: Envoy will handle the request/response as a stream of data. Therefore, the body may not be
1352+
* available in its entirety before the end of stream flag is set. The Envoy will provides both the
1353+
* received body (body pieces received in the latest event) and the buffered body (body pieces
1354+
* buffered so far) to the module. The module should be aware of this distinction when processing
1355+
* the body.
1356+
*
1357+
* NOTE: The received body could only be available during the request/response body
1358+
* event hooks (the envoy_dynamic_module_on_http_filter_request_body and
1359+
* envoy_dynamic_module_on_http_filter_response_body).
1360+
* Outside of these hooks, the received body will be unavailable.
1361+
*
1362+
* NOTE: The buffered body, however, is always available. But only the latest data processing filter
1363+
* in the filter chain could modify the buffered body. That is say for a given filter X, filter X
1364+
* can safely modify the buffered body if and only if the filters following filter X in the filter
1365+
* chain have not yet accessed the body.
1366+
*/
1367+
1368+
/**
1369+
* envoy_dynamic_module_callback_http_get_received_request_body_vector is called by the module to
1370+
* get the current request body as a vector of buffers. The body is returned as an array of
1371+
* envoy_dynamic_module_type_envoy_buffer.
1372+
*
1373+
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
1374+
* to store all the buffers. The module can use
1375+
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size to get the number of
1376+
* buffers before calling this function.
1377+
*
1378+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1379+
* corresponding HTTP filter.
1380+
* @param result_buffer_vector is the pointer to the array of envoy_dynamic_module_type_envoy_buffer
1381+
* where the buffers of the body will be stored. The lifetime of the buffer is guaranteed until the
1382+
* end of the current event hook unless the setter callback is called.
1383+
* @return true if the body is available, false otherwise.
1384+
*/
1385+
bool envoy_dynamic_module_callback_http_get_received_request_body_vector(
1386+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1387+
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
1388+
1389+
/**
1390+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector is called by the module to
1391+
* get the buffered request body as a vector of buffers. The body is returned as an array of
13531392
* envoy_dynamic_module_type_envoy_buffer.
13541393
*
13551394
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
13561395
* to store all the buffers. The module can use
1357-
* envoy_dynamic_module_callback_http_get_request_body_vector_size to get the number of buffers
1358-
* before calling this function.
1396+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size to get the number of
1397+
* buffers before calling this function.
13591398
*
13601399
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
13611400
* corresponding HTTP filter.
@@ -1364,115 +1403,159 @@ void envoy_dynamic_module_callback_http_send_response_trailers(
13641403
* end of the current event hook unless the setter callback is called.
13651404
* @return true if the body is available, false otherwise.
13661405
*/
1367-
bool envoy_dynamic_module_callback_http_get_request_body_vector(
1406+
bool envoy_dynamic_module_callback_http_get_buffered_request_body_vector(
13681407
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
13691408
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
13701409

13711410
/**
1372-
* envoy_dynamic_module_callback_http_get_request_body_vector_size is called by the module to get
1373-
* the number of buffers in the request body. Combined with
1374-
* envoy_dynamic_module_callback_http_get_request_body_vector, this can be used to iterate over all
1375-
* buffers in the request body.
1411+
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size is called by the module
1412+
* to get the number of buffers in the current request body. Combined with
1413+
* envoy_dynamic_module_callback_http_get_received_request_body_vector, this can be used to iterate
1414+
* over all buffers in the request body.
13761415
*
13771416
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
13781417
* corresponding HTTP filter.
13791418
* @param size is the pointer to the variable where the number of buffers will be stored.
13801419
* @return true if the body is available, false otherwise.
13811420
*/
1382-
bool envoy_dynamic_module_callback_http_get_request_body_vector_size(
1421+
bool envoy_dynamic_module_callback_http_get_received_request_body_vector_size(
13831422
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
13841423

13851424
/**
1386-
* envoy_dynamic_module_callback_http_append_request_body is called by the module to append the
1387-
* given data to the end of the request body.
1425+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size is called by the module
1426+
* to get the number of buffers in the buffered request body. Combined with
1427+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector, this can be used to iterate
1428+
* over all buffers in the request body.
1429+
*
1430+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1431+
* corresponding HTTP filter.
1432+
* @param size is the pointer to the variable where the number of buffers will be stored.
1433+
* @return true if the body is available, false otherwise.
1434+
*/
1435+
bool envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size(
1436+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
1437+
1438+
/**
1439+
* envoy_dynamic_module_callback_http_append_received_request_body is called by the module to append
1440+
* the given data to the end of the current request body.
13881441
*
13891442
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
13901443
* corresponding HTTP filter.
13911444
* @param data is the pointer to the buffer of the data to be appended.
13921445
* @param length is the length of the data.
13931446
* @return true if the body is available, false otherwise.
13941447
*/
1395-
bool envoy_dynamic_module_callback_http_append_request_body(
1448+
bool envoy_dynamic_module_callback_http_append_received_request_body(
13961449
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
13971450
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
13981451

13991452
/**
1400-
* envoy_dynamic_module_callback_http_drain_request_body is called by the module to drain the given
1401-
* number of bytes from the request body. If the number of bytes to drain is greater than
1402-
* the size of the body, the whole body will be drained.
1453+
* envoy_dynamic_module_callback_http_append_buffered_request_body is called by the module to append
1454+
* the given data to the end of the buffered request body.
1455+
*
1456+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1457+
* corresponding HTTP filter.
1458+
* @param data is the pointer to the buffer of the data to be appended.
1459+
* @param length is the length of the data.
1460+
* @return true if the body is available, false otherwise.
1461+
*/
1462+
bool envoy_dynamic_module_callback_http_append_buffered_request_body(
1463+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1464+
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
1465+
1466+
/**
1467+
* envoy_dynamic_module_callback_http_drain_received_request_body is called by the module to drain
1468+
* the given number of bytes from the current request body. If the number of bytes to drain is
1469+
* greater than the size of the body, the whole body will be drained.
14031470
*
14041471
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
14051472
* corresponding HTTP filter.
14061473
* @param number_of_bytes is the number of bytes to drain.
14071474
* @return true if the body is available, false otherwise.
14081475
*/
1409-
bool envoy_dynamic_module_callback_http_drain_request_body(
1476+
bool envoy_dynamic_module_callback_http_drain_received_request_body(
14101477
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
14111478

14121479
/**
1413-
* envoy_dynamic_module_callback_http_inject_request_body is called by the module to
1414-
* inject the given request data directly into the filter stream. This method should only be called
1415-
* from a scheduled event.
1480+
* envoy_dynamic_module_callback_http_drain_buffered_request_body is called by the module to drain
1481+
* the given number of bytes from the buffered request body. If the number of bytes to drain is
1482+
* greater than the size of the body, the whole body will be drained.
14161483
*
14171484
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
14181485
* corresponding HTTP filter.
1419-
* @param data is the pointer to the buffer of the data to be injected.
1420-
* @param length is the length of the data.
1421-
* @param end_stream is true if this is the last data to be injected.
1486+
* @param number_of_bytes is the number of bytes to drain.
14221487
* @return true if the body is available, false otherwise.
14231488
*/
1424-
bool envoy_dynamic_module_callback_http_inject_request_body(
1489+
bool envoy_dynamic_module_callback_http_drain_buffered_request_body(
1490+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
1491+
1492+
/**
1493+
* This is the same as envoy_dynamic_module_callback_http_get_received_request_body_vector, but for
1494+
* the current response body. See the comments on
1495+
* envoy_dynamic_module_callback_http_get_received_request_body_vector for more details.
1496+
*/
1497+
bool envoy_dynamic_module_callback_http_get_received_response_body_vector(
14251498
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1426-
envoy_dynamic_module_type_buffer_module_ptr data, size_t length, bool end_stream);
1499+
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
14271500

14281501
/**
1429-
* This is the same as envoy_dynamic_module_callback_http_get_request_body_vector, but for the
1430-
* response body. See the comments on envoy_dynamic_module_callback_http_get_request_body_vector
1431-
* for more details.
1502+
* This is the same as envoy_dynamic_module_callback_http_get_buffered_request_body_vector, but for
1503+
* the buffered response body. See the comments on
1504+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector for more details.
14321505
*/
1433-
bool envoy_dynamic_module_callback_http_get_response_body_vector(
1506+
bool envoy_dynamic_module_callback_http_get_buffered_response_body_vector(
14341507
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
14351508
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
14361509

14371510
/**
1438-
* This is the same as envoy_dynamic_module_callback_http_get_request_body_vector_size, but for the
1439-
* response body. See the comments on
1440-
* envoy_dynamic_module_callback_http_get_request_body_vector_size for more details.
1511+
* This is the same as envoy_dynamic_module_callback_http_get_received_request_body_vector_size, but
1512+
* for the current response body. See the comments on
1513+
* envoy_dynamic_module_callback_http_get_received_request_body_vector_size for more details.
14411514
*/
1442-
bool envoy_dynamic_module_callback_http_get_response_body_vector_size(
1515+
bool envoy_dynamic_module_callback_http_get_received_response_body_vector_size(
14431516
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
14441517

14451518
/**
1446-
* This is the same as envoy_dynamic_module_callback_http_append_request_body, but for the response
1447-
* body. See the comments on envoy_dynamic_module_callback_http_append_request_body for more
1448-
* details.
1519+
* This is the same as envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size, but
1520+
* for the buffered response body. See the comments on
1521+
* envoy_dynamic_module_callback_http_get_buffered_request_body_vector_size for more details.
14491522
*/
1450-
bool envoy_dynamic_module_callback_http_append_response_body(
1523+
bool envoy_dynamic_module_callback_http_get_buffered_response_body_vector_size(
1524+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t* size);
1525+
1526+
/**
1527+
* This is the same as envoy_dynamic_module_callback_http_append_received_request_body, but for the
1528+
* current response body. See the comments on
1529+
* envoy_dynamic_module_callback_http_append_received_request_body for more details.
1530+
*/
1531+
bool envoy_dynamic_module_callback_http_append_received_response_body(
1532+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1533+
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
1534+
1535+
/**
1536+
* This is the same as envoy_dynamic_module_callback_http_append_buffered_request_body, but for the
1537+
* buffered response body. See the comments on
1538+
* envoy_dynamic_module_callback_http_append_buffered_request_body for more details.
1539+
*/
1540+
bool envoy_dynamic_module_callback_http_append_buffered_response_body(
14511541
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
14521542
envoy_dynamic_module_type_buffer_module_ptr data, size_t length);
14531543

14541544
/**
1455-
* This is the same as envoy_dynamic_module_callback_http_drain_request_body, but for the response
1456-
* body. See the comments on envoy_dynamic_module_callback_http_drain_request_body for more details.
1545+
* This is the same as envoy_dynamic_module_callback_http_drain_received_request_body, but for the
1546+
* current response body. See the comments on
1547+
* envoy_dynamic_module_callback_http_drain_received_request_body for more details.
14571548
*/
1458-
bool envoy_dynamic_module_callback_http_drain_response_body(
1549+
bool envoy_dynamic_module_callback_http_drain_received_response_body(
14591550
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
14601551

14611552
/**
1462-
* envoy_dynamic_module_callback_http_inject_response_body is called by the module to
1463-
* inject the given response data directly into the filter stream. This method should only be called
1464-
* from a scheduled event.
1465-
*
1466-
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1467-
* corresponding HTTP filter.
1468-
* @param data is the pointer to the buffer of the data to be injected.
1469-
* @param length is the length of the data.
1470-
* @param end_stream is true if this is the last data to be injected.
1471-
* @return true if the body is available, false otherwise.
1553+
* This is the same as envoy_dynamic_module_callback_http_drain_buffered_request_body, but for the
1554+
* buffered response body. See the comments on
1555+
* envoy_dynamic_module_callback_http_drain_buffered_request_body for more details.
14721556
*/
1473-
bool envoy_dynamic_module_callback_http_inject_response_body(
1474-
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1475-
envoy_dynamic_module_type_buffer_module_ptr data, size_t length, bool end_stream);
1557+
bool envoy_dynamic_module_callback_http_drain_buffered_response_body(
1558+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, size_t number_of_bytes);
14761559

14771560
// ---------------------------- Metadata Callbacks -----------------------------
14781561

0 commit comments

Comments
 (0)