summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 08:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 08:52:22 +0000
commit6a7eecec57783a042d12f895d5ae148c44f4d074 (patch)
tree77a2c3c5612655f1dd15e9a2ddf14e13bab90b1f /lib
parentReleasing progress-linux version 1.59.0-1~progress7.99u1. (diff)
downloadnghttp2-6a7eecec57783a042d12f895d5ae148c44f4d074.tar.xz
nghttp2-6a7eecec57783a042d12f895d5ae148c44f4d074.zip
Merging upstream version 1.60.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt69
-rw-r--r--lib/includes/nghttp2/nghttp2.h1236
-rw-r--r--lib/nghttp2_buf.c4
-rw-r--r--lib/nghttp2_buf.h2
-rw-r--r--lib/nghttp2_callbacks.c28
-rw-r--r--lib/nghttp2_callbacks.h45
-rw-r--r--lib/nghttp2_hd.c114
-rw-r--r--lib/nghttp2_hd.h20
-rw-r--r--lib/nghttp2_hd_huffman.c8
-rw-r--r--lib/nghttp2_outbound_item.c26
-rw-r--r--lib/nghttp2_outbound_item.h27
-rw-r--r--lib/nghttp2_session.c332
-rw-r--r--lib/nghttp2_submit.c125
-rw-r--r--lib/nghttp2_submit.h6
14 files changed, 1691 insertions, 351 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 4180748..211c8e4 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -31,6 +31,8 @@ set(NGHTTP2_SOURCES
)
set(NGHTTP2_RES "")
+set(STATIC_LIB "nghttp2_static")
+set(SHARED_LIB "nghttp2")
if(WIN32)
configure_file(
@@ -41,40 +43,61 @@ if(WIN32)
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
endif()
+set(EXPORT_SET "${PROJECT_NAME}-targets")
+
# Public shared library
-if(ENABLE_SHARED_LIB)
- add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
- set_target_properties(nghttp2 PROPERTIES
+if(BUILD_SHARED_LIBS)
+ add_library(${SHARED_LIB} SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
+
+ set_target_properties(${SHARED_LIB} PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden
)
- target_include_directories(nghttp2 INTERFACE
- "${CMAKE_CURRENT_BINARY_DIR}/includes"
- "${CMAKE_CURRENT_SOURCE_DIR}/includes"
+
+ target_include_directories(${SHARED_LIB} INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/includes>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
- install(TARGETS nghttp2
- ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+ install(TARGETS ${SHARED_LIB} EXPORT ${EXPORT_SET})
+ list(APPEND nghttp2_exports ${SHARED_LIB})
endif()
-if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
- # Static library (for unittests because of symbol visibility)
- add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
- set_target_properties(nghttp2_static PROPERTIES
- COMPILE_FLAGS "${WARNCFLAGS}"
- VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
- ARCHIVE_OUTPUT_NAME nghttp2${STATIC_LIB_SUFFIX}
- )
- target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
- if(ENABLE_STATIC_LIB)
- install(TARGETS nghttp2_static
- DESTINATION "${CMAKE_INSTALL_LIBDIR}")
- endif()
+# Static library (for unittests because of symbol visibility)
+add_library(${STATIC_LIB} STATIC ${NGHTTP2_SOURCES})
+
+set_target_properties(${STATIC_LIB} PROPERTIES
+ COMPILE_FLAGS "${WARNCFLAGS}"
+ VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
+ ARCHIVE_OUTPUT_NAME nghttp2${STATIC_LIB_SUFFIX}
+)
+
+target_include_directories(${STATIC_LIB} INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/includes>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB")
+
+if(BUILD_STATIC_LIBS)
+ install(TARGETS ${STATIC_LIB} EXPORT ${EXPORT_SET})
+ list(APPEND nghttp2_exports ${STATIC_LIB})
endif()
+if(BUILD_SHARED_LIBS)
+ set(LIB_SELECTED ${SHARED_LIB})
+else()
+ set(LIB_SELECTED ${STATIC_LIB})
+endif()
+
+add_library(${PROJECT_NAME}::nghttp2 ALIAS ${LIB_SELECTED})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+
+install(EXPORT ${EXPORT_SET}
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
+ NAMESPACE ${PROJECT_NAME}::)
diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
index 7910db2..8891760 100644
--- a/lib/includes/nghttp2/nghttp2.h
+++ b/lib/includes/nghttp2/nghttp2.h
@@ -51,6 +51,7 @@ extern "C" {
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
#include <sys/types.h>
#include <stdarg.h>
+#include <stddef.h>
#include <nghttp2/nghttp2ver.h>
@@ -72,6 +73,13 @@ extern "C" {
#endif /* !defined(WIN32) */
/**
+ * @typedef
+ *
+ * :type:`nghttp2_ssize` is a signed counterpart of size_t.
+ */
+typedef ptrdiff_t nghttp2_ssize;
+
+/**
* @macro
*
* The protocol version identification string of this library
@@ -168,6 +176,12 @@ typedef struct {
/**
* @macro
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* The default weight of stream dependency.
*/
#define NGHTTP2_DEFAULT_WEIGHT 16
@@ -175,6 +189,12 @@ typedef struct {
/**
* @macro
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* The maximum weight of stream dependency.
*/
#define NGHTTP2_MAX_WEIGHT 256
@@ -182,6 +202,12 @@ typedef struct {
/**
* @macro
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* The minimum weight of stream dependency.
*/
#define NGHTTP2_MIN_WEIGHT 1
@@ -255,7 +281,7 @@ typedef enum {
*/
NGHTTP2_ERR_UNSUPPORTED_VERSION = -503,
/**
- * Used as a return value from :type:`nghttp2_send_callback`,
+ * Used as a return value from :type:`nghttp2_send_callback2`,
* :type:`nghttp2_recv_callback` and
* :type:`nghttp2_send_data_callback` to indicate that the operation
* would block.
@@ -275,9 +301,9 @@ typedef enum {
NGHTTP2_ERR_EOF = -507,
/**
* Used as a return value from
- * :func:`nghttp2_data_source_read_callback` to indicate that data
+ * :func:`nghttp2_data_source_read_callback2` to indicate that data
* transfer is postponed. See
- * :func:`nghttp2_data_source_read_callback` for details.
+ * :func:`nghttp2_data_source_read_callback2` for details.
*/
NGHTTP2_ERR_DEFERRED = -508,
/**
@@ -830,7 +856,7 @@ typedef struct {
* @union
*
* This union represents the some kind of data source passed to
- * :type:`nghttp2_data_source_read_callback`.
+ * :type:`nghttp2_data_source_read_callback2`.
*/
typedef union {
/**
@@ -847,7 +873,7 @@ typedef union {
* @enum
*
* The flags used to set in |data_flags| output parameter in
- * :type:`nghttp2_data_source_read_callback`.
+ * :type:`nghttp2_data_source_read_callback2`.
*/
typedef enum {
/**
@@ -861,8 +887,8 @@ typedef enum {
/**
* Indicates that END_STREAM flag must not be set even if
* NGHTTP2_DATA_FLAG_EOF is set. Usually this flag is used to send
- * trailer fields with `nghttp2_submit_request()` or
- * `nghttp2_submit_response()`.
+ * trailer fields with `nghttp2_submit_request2()` or
+ * `nghttp2_submit_response2()`.
*/
NGHTTP2_DATA_FLAG_NO_END_STREAM = 0x02,
/**
@@ -872,9 +898,15 @@ typedef enum {
NGHTTP2_DATA_FLAG_NO_COPY = 0x04
} nghttp2_data_flag;
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_data_source_read_callback2`
+ * instead.
+ *
* Callback function invoked when the library wants to read data from
* the |source|. The read data is sent in the stream |stream_id|.
* The implementation of this function must read at most |length|
@@ -939,9 +971,83 @@ typedef ssize_t (*nghttp2_data_source_read_callback)(
nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
uint32_t *data_flags, nghttp2_data_source *source, void *user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library wants to read data from
+ * the |source|. The read data is sent in the stream |stream_id|.
+ * The implementation of this function must read at most |length|
+ * bytes of data from |source| (or possibly other places) and store
+ * them in |buf| and return number of data stored in |buf|. If EOF is
+ * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag
+ * in |*data_flags|.
+ *
+ * Sometime it is desirable to avoid copying data into |buf| and let
+ * application to send data directly. To achieve this, set
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to
+ * |*data_flags| (and possibly other flags, just like when we do
+ * copy), and return the number of bytes to send without copying data
+ * into |buf|. The library, seeing
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
+ * :type:`nghttp2_send_data_callback`. The application must send
+ * complete DATA frame in that callback.
+ *
+ * If this callback is set by `nghttp2_submit_request2()`,
+ * `nghttp2_submit_response2()` or `nghttp2_submit_headers()` and
+ * `nghttp2_submit_data2()` with flag parameter
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to
+ * |*data_flags|, DATA frame will have END_STREAM flag set. Usually,
+ * this is expected behaviour and all are fine. One exception is send
+ * trailer fields. You cannot send trailer fields after sending frame
+ * with END_STREAM set. To avoid this problem, one can set
+ * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along
+ * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the
+ * library not to set END_STREAM in DATA frame. Then application can
+ * use `nghttp2_submit_trailer()` to send trailer fields.
+ * `nghttp2_submit_trailer()` can be called inside this callback.
+ *
+ * If the application wants to postpone DATA frames (e.g.,
+ * asynchronous I/O, or reading data blocks for long time), it is
+ * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED`
+ * without reading any data in this invocation. The library removes
+ * DATA frame from the outgoing queue temporarily. To move back
+ * deferred DATA frame to outgoing queue, call
+ * `nghttp2_session_resume_data()`.
+ *
+ * By default, |length| is limited to 16KiB at maximum. If peer
+ * allows larger frames, application can enlarge transmission buffer
+ * size. See :type:`nghttp2_data_source_read_length_callback` for
+ * more details.
+ *
+ * If the application just wants to return from
+ * `nghttp2_session_send()` or `nghttp2_session_mem_send2()` without
+ * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`.
+ *
+ * In case of error, there are 2 choices. Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream by issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. If a different
+ * error code is desirable, use `nghttp2_submit_rst_stream()` with a
+ * desired error code and then return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will
+ * signal the entire session failure.
+ */
+typedef nghttp2_ssize (*nghttp2_data_source_read_callback2)(
+ nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
+ uint32_t *data_flags, nghttp2_data_source *source, void *user_data);
+
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @struct
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_data_provider2` instead.
+ *
* This struct represents the data source and the way to read a chunk
* of data from it.
*/
@@ -956,6 +1062,25 @@ typedef struct {
nghttp2_data_source_read_callback read_callback;
} nghttp2_data_provider;
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @struct
+ *
+ * This struct represents the data source and the way to read a chunk
+ * of data from it.
+ */
+typedef struct {
+ /**
+ * The data source.
+ */
+ nghttp2_data_source source;
+ /**
+ * The callback function to read a chunk of data from the |source|.
+ */
+ nghttp2_data_source_read_callback2 read_callback;
+} nghttp2_data_provider2;
+
/**
* @struct
*
@@ -1008,6 +1133,12 @@ typedef enum {
/**
* @struct
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* The structure to specify stream dependency.
*/
typedef struct {
@@ -1042,6 +1173,12 @@ typedef struct {
*/
size_t padlen;
/**
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* The priority specification
*/
nghttp2_priority_spec pri_spec;
@@ -1062,6 +1199,12 @@ typedef struct {
/**
* @struct
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* The PRIORITY frame. It has the following members:
*/
typedef struct {
@@ -1305,9 +1448,14 @@ typedef union {
nghttp2_extension ext;
} nghttp2_frame;
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_send_callback2` instead.
+ *
* Callback function invoked when |session| wants to send data to the
* remote peer. The implementation of this function must send at most
* |length| bytes of data stored in |data|. The |flags| is currently
@@ -1340,6 +1488,44 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
const uint8_t *data, size_t length,
int flags, void *user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when |session| wants to send data to the
+ * remote peer. The implementation of this function must send at most
+ * |length| bytes of data stored in |data|. The |flags| is currently
+ * not used and always 0. It must return the number of bytes sent if
+ * it succeeds. If it cannot send any single byte without blocking,
+ * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. For
+ * other errors, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * This callback is required if the application uses
+ * `nghttp2_session_send()` to send data to the remote endpoint. If
+ * the application uses solely `nghttp2_session_mem_send2()` instead,
+ * this callback function is unnecessary.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_send_callback2()`.
+ *
+ * .. note::
+ *
+ * The |length| may be very small. If that is the case, and
+ * application disables Nagle algorithm (``TCP_NODELAY``), then just
+ * writing |data| to the network stack leads to very small packet,
+ * and it is very inefficient. An application should be responsible
+ * to buffer up small chunks of data as necessary to avoid this
+ * situation.
+ */
+typedef nghttp2_ssize (*nghttp2_send_callback2)(nghttp2_session *session,
+ const uint8_t *data,
+ size_t length, int flags,
+ void *user_data);
+
/**
* @functypedef
*
@@ -1370,7 +1556,7 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
* error; if partial frame data has already sent, it is impossible to
* send another data in that state, and all we can do is tear down
* connection). When data is fully processed, but application wants
- * to make `nghttp2_session_mem_send()` or `nghttp2_session_send()`
+ * to make `nghttp2_session_mem_send2()` or `nghttp2_session_send()`
* return immediately without processing next frames, return
* :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. If application decided to
* reset this stream, return
@@ -1387,9 +1573,14 @@ typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
nghttp2_data_source *source,
void *user_data);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_recv_callback2` instead.
+ *
* Callback function invoked when |session| wants to receive data from
* the remote peer. The implementation of this function must read at
* most |length| bytes of data and store it in |buf|. The |flags| is
@@ -1417,11 +1608,43 @@ typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf,
size_t length, int flags,
void *user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when |session| wants to receive data from
+ * the remote peer. The implementation of this function must read at
+ * most |length| bytes of data and store it in |buf|. The |flags| is
+ * currently not used and always 0. It must return the number of
+ * bytes written in |buf| if it succeeds. If it cannot read any
+ * single byte without blocking, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF
+ * before it reads any single byte, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`. For other errors, it must
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * Returning 0 is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. The |user_data|
+ * pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * This callback is required if the application uses
+ * `nghttp2_session_recv()` to receive data from the remote endpoint.
+ * If the application uses solely `nghttp2_session_mem_recv2()`
+ * instead, this callback function is unnecessary.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_recv_callback2()`.
+ */
+typedef nghttp2_ssize (*nghttp2_recv_callback2)(nghttp2_session *session,
+ uint8_t *buf, size_t length,
+ int flags, void *user_data);
+
/**
* @functypedef
*
* Callback function invoked by `nghttp2_session_recv()` and
- * `nghttp2_session_mem_recv()` when a frame is received. The
+ * `nghttp2_session_mem_recv2()` when a frame is received. The
* |user_data| pointer is the third argument passed in to the call to
* `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
*
@@ -1439,8 +1662,8 @@ typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf,
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero value is returned, it is treated as fatal error and
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1454,7 +1677,7 @@ typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session,
* @functypedef
*
* Callback function invoked by `nghttp2_session_recv()` and
- * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is
+ * `nghttp2_session_mem_recv2()` when an invalid non-DATA frame is
* received. The error is indicated by the |lib_error_code|, which is
* one of the values defined in :type:`nghttp2_error`. When this
* callback function is invoked, the library automatically submits
@@ -1468,8 +1691,8 @@ typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session,
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1492,19 +1715,19 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)(
* argument passed in to the call to `nghttp2_session_client_new()` or
* `nghttp2_session_server_new()`.
*
- * If the application uses `nghttp2_session_mem_recv()`, it can return
- * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
- * `nghttp2_session_mem_recv()` return without processing further
+ * If the application uses `nghttp2_session_mem_recv2()`, it can
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv2()` return without processing further
* input bytes. The memory by pointed by the |data| is retained until
- * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
- * The application must retain the input bytes which was used to
- * produce the |data| parameter, because it may refer to the memory
+ * `nghttp2_session_mem_recv2()` or `nghttp2_session_recv()` is
+ * called. The application must retain the input bytes which was used
+ * to produce the |data| parameter, because it may refer to the memory
* region included in the input bytes.
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error, and
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1531,8 +1754,8 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
* If there is a fatal error while executing this callback, the
* implementation should return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes
- * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* If the other value is returned, it is treated as if
@@ -1556,8 +1779,8 @@ typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session,
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
- * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1579,8 +1802,8 @@ typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session,
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
- * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* `nghttp2_session_get_stream_user_data()` can be used to get
@@ -1601,7 +1824,7 @@ typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session,
* The reason of closure is indicated by the |error_code|. The
* |error_code| is usually one of :enum:`nghttp2_error_code`, but that
* is not guaranteed. The stream_user_data, which was specified in
- * `nghttp2_submit_request()` or `nghttp2_submit_headers()`, is still
+ * `nghttp2_submit_request2()` or `nghttp2_submit_headers()`, is still
* available in this function. The |user_data| pointer is the third
* argument passed in to the call to `nghttp2_session_client_new()` or
* `nghttp2_session_server_new()`.
@@ -1610,8 +1833,8 @@ typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session,
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
- * `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`,
- * `nghttp2_session_send()`, and `nghttp2_session_mem_send()`
+ * `nghttp2_session_recv()`, `nghttp2_session_mem_recv2()`,
+ * `nghttp2_session_send()`, and `nghttp2_session_mem_send2()`
* functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
@@ -1681,7 +1904,7 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session,
* value is returned, it is treated as if
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. If
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
- * `nghttp2_session_mem_recv()` function will immediately return
+ * `nghttp2_session_mem_recv2()` function will immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1726,11 +1949,11 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
* performs validation based on HTTP Messaging rule, which is briefly
* explained in :ref:`http-messaging` section.
*
- * If the application uses `nghttp2_session_mem_recv()`, it can return
- * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
- * `nghttp2_session_mem_recv()` return without processing further
+ * If the application uses `nghttp2_session_mem_recv2()`, it can
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv2()` return without processing further
* input bytes. The memory pointed by |frame|, |name| and |value|
- * parameters are retained until `nghttp2_session_mem_recv()` or
+ * parameters are retained until `nghttp2_session_mem_recv2()` or
* `nghttp2_session_recv()` is called. The application must retain
* the input bytes which was used to produce these parameters, because
* it may refer to the memory region included in the input bytes.
@@ -1757,8 +1980,8 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
* nonzero value is returned, it is treated as
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1873,9 +2096,15 @@ typedef int (*nghttp2_on_invalid_header_callback2)(
nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
nghttp2_rcbuf *value, uint8_t flags, void *user_data);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_select_padding_callback2`
+ * instead.
+ *
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the
* |frame|. The application must choose the total length of payload
@@ -1896,9 +2125,39 @@ typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session,
size_t max_payloadlen,
void *user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library asks application how
+ * many padding bytes are required for the transmission of the
+ * |frame|. The application must choose the total length of payload
+ * including padded bytes in range [frame->hd.length, max_payloadlen],
+ * inclusive. Choosing number not in this range will be treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Returning
+ * ``frame->hd.length`` means no padding is added. Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_select_padding_callback2()`.
+ */
+typedef nghttp2_ssize (*nghttp2_select_padding_callback2)(
+ nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen,
+ void *user_data);
+
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use
+ * :type:`nghttp2_data_source_read_length_callback2` instead.
+ *
* Callback function invoked when library wants to get max length of
* data to send data to the remote peer. The implementation of this
* function should return a value in the following range. [1,
@@ -1926,6 +2185,38 @@ typedef ssize_t (*nghttp2_data_source_read_length_callback)(
int32_t session_remote_window_size, int32_t stream_remote_window_size,
uint32_t remote_max_frame_size, void *user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library wants to get max length of
+ * data to send data to the remote peer. The implementation of this
+ * function should return a value in the following range. [1,
+ * min(|session_remote_window_size|, |stream_remote_window_size|,
+ * |remote_max_frame_size|)]. If a value greater than this range is
+ * returned than the max allow value will be used. Returning a value
+ * smaller than this range is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The
+ * |frame_type| is provided for future extensibility and identifies
+ * the type of frame (see :type:`nghttp2_frame_type`) for which to get
+ * the length for. Currently supported frame types are:
+ * :enum:`nghttp2_frame_type.NGHTTP2_DATA`.
+ *
+ * This callback can be used to control the length in bytes for which
+ * :type:`nghttp2_data_source_read_callback` is allowed to send to the
+ * remote endpoint. This callback is optional. Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the
+ * entire session failure.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_data_source_read_length_callback2()`.
+ */
+typedef nghttp2_ssize (*nghttp2_data_source_read_length_callback2)(
+ nghttp2_session *session, uint8_t frame_type, int32_t stream_id,
+ int32_t session_remote_window_size, int32_t stream_remote_window_size,
+ uint32_t remote_max_frame_size, void *user_data);
+
/**
* @functypedef
*
@@ -1942,8 +2233,8 @@ typedef ssize_t (*nghttp2_data_source_read_length_callback)(
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero value is returned, it is treated as fatal error and
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1967,8 +2258,8 @@ typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session,
*
* If fatal error occurred, application should return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
* values are returned, currently they are treated as
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
@@ -2005,8 +2296,8 @@ typedef int (*nghttp2_on_extension_chunk_recv_callback)(
*
* If fatal error occurred, application should return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
* values are returned, currently they are treated as
* :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
@@ -2016,9 +2307,15 @@ typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
const nghttp2_frame_hd *hd,
void *user_data);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_pack_extension_callback2`
+ * instead.
+ *
* Callback function invoked when library asks the application to pack
* extension payload in its wire format. The frame header will be
* packed by library. Application must pack payload only.
@@ -2049,18 +2346,53 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
const nghttp2_frame *frame,
void *user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library asks the application to pack
+ * extension payload in its wire format. The frame header will be
+ * packed by library. Application must pack payload only.
+ * ``frame->ext.payload`` is the object passed to
+ * `nghttp2_submit_extension()` as payload parameter. Application
+ * must pack extension payload to the |buf| of its capacity |len|
+ * bytes. The |len| is at least 16KiB.
+ *
+ * The implementation of this function should return the number of
+ * bytes written into |buf| when it succeeds.
+ *
+ * To abort processing this extension frame, return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and
+ * :type:`nghttp2_on_frame_not_send_callback` will be invoked.
+ *
+ * If fatal error occurred, application should return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the return
+ * value is strictly larger than |len|, it is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef nghttp2_ssize (*nghttp2_pack_extension_callback2)(
+ nghttp2_session *session, uint8_t *buf, size_t len,
+ const nghttp2_frame *frame, void *user_data);
+
/**
* @functypedef
*
+ * .. warning::
+ *
+ * Deprecated. Use :type:`nghttp2_error_callback2` instead.
+ *
* Callback function invoked when library provides the error message
* intended for human consumption. This callback is solely for
* debugging purpose. The |msg| is typically NULL-terminated string
* of length |len|. |len| does not include the sentinel NULL
* character.
*
- * This function is deprecated. The new application should use
- * :type:`nghttp2_error_callback2`.
- *
* The format of error message may change between nghttp2 library
* versions. The application should not depend on the particular
* format.
@@ -2143,9 +2475,15 @@ nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr);
NGHTTP2_EXTERN void
nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_session_callbacks_set_send_callback2()`
+ * with :type:`nghttp2_send_callback2` instead.
+ *
* Sets callback function invoked when a session wants to send data to
* the remote peer. This callback is not necessary if the application
* uses solely `nghttp2_session_mem_send()` to serialize data to
@@ -2154,9 +2492,28 @@ nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks);
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback(
nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a session wants to send data to
+ * the remote peer. This callback is not necessary if the application
+ * uses solely `nghttp2_session_mem_send2()` to serialize data to
+ * transmit.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback2(
+ nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback);
+
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_session_callbacks_set_recv_callback2()`
+ * with :type:`nghttp2_recv_callback2` instead.
+ *
* Sets callback function invoked when the a session wants to receive
* data from the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_recv()` to process
@@ -2165,11 +2522,24 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback(
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback(
nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the a session wants to receive
+ * data from the remote peer. This callback is not necessary if the
+ * application uses solely `nghttp2_session_mem_recv2()` to process
+ * received data.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback2(
+ nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback);
+
/**
* @function
*
* Sets callback function invoked by `nghttp2_session_recv()` and
- * `nghttp2_session_mem_recv()` when a frame is received.
+ * `nghttp2_session_mem_recv2()` when a frame is received.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback(
nghttp2_session_callbacks *cbs,
@@ -2179,7 +2549,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback(
* @function
*
* Sets callback function invoked by `nghttp2_session_recv()` and
- * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is
+ * `nghttp2_session_mem_recv2()` when an invalid non-DATA frame is
* received.
*/
NGHTTP2_EXTERN void
@@ -2290,9 +2660,16 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use
+ * `nghttp2_session_callbacks_set_select_padding_callback2()` with
+ * :type:`nghttp2_select_padding_callback2` instead.
+ *
* Sets callback function invoked when the library asks application
* how many padding bytes are required for the transmission of the
* given frame.
@@ -2301,9 +2678,29 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback(
nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback select_padding_callback);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
/**
* @function
*
+ * Sets callback function invoked when the library asks application
+ * how many padding bytes are required for the transmission of the
+ * given frame.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback2(
+ nghttp2_session_callbacks *cbs,
+ nghttp2_select_padding_callback2 select_padding_callback);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ * Deprecated. Use
+ * `nghttp2_session_callbacks_set_data_source_read_length_callback2()`
+ * with :type:`nghttp2_data_source_read_length_callback2` instead.
+ *
* Sets callback function determine the length allowed in
* :type:`nghttp2_data_source_read_callback`.
*/
@@ -2312,6 +2709,19 @@ nghttp2_session_callbacks_set_data_source_read_length_callback(
nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback data_source_read_length_callback);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Sets callback function determine the length allowed in
+ * :type:`nghttp2_data_source_read_callback2`.
+ */
+NGHTTP2_EXTERN void
+nghttp2_session_callbacks_set_data_source_read_length_callback2(
+ nghttp2_session_callbacks *cbs,
+ nghttp2_data_source_read_length_callback2 data_source_read_length_callback);
+
/**
* @function
*
@@ -2326,15 +2736,22 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback(
*
* Sets callback function invoked when
* :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
- * :type:`nghttp2_data_source_read_callback` to avoid data copy.
+ * :type:`nghttp2_data_source_read_callback2` to avoid data copy.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback(
nghttp2_session_callbacks *cbs,
nghttp2_send_data_callback send_data_callback);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use
+ * `nghttp2_session_callbacks_set_pack_extension_callback2()` with
+ * :type:`nghttp2_pack_extension_callback2` instead.
+ *
* Sets callback function invoked when the library asks the
* application to pack extension frame payload in wire format.
*/
@@ -2342,6 +2759,18 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_pack_extension_callback pack_extension_callback);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the library asks the
+ * application to pack extension frame payload in wire format.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback2(
+ nghttp2_session_callbacks *cbs,
+ nghttp2_pack_extension_callback2 pack_extension_callback);
+
/**
* @function
*
@@ -2366,12 +2795,15 @@ nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use
+ * `nghttp2_session_callbacks_set_error_callback2()` with
+ * :type:`nghttp2_error_callback2` instead.
+ *
* Sets callback function invoked when library tells error message to
* the application.
*
- * This function is deprecated. The new application should use
- * `nghttp2_session_callbacks_set_error_callback2()`.
- *
* If both :type:`nghttp2_error_callback` and
* :type:`nghttp2_error_callback2` are set, the latter takes
* precedence.
@@ -2568,7 +3000,7 @@ nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
*
* If this option is not used or used with zero value, if MAGIC does
* not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()`
- * and `nghttp2_session_mem_recv()` will return error
+ * and `nghttp2_session_mem_recv2()` will return error
* :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal
* error.
*/
@@ -2781,7 +3213,7 @@ nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
* does not store |callbacks|. The |user_data| is an arbitrary user
* supplied data, which will be passed to the callback functions.
*
- * The :type:`nghttp2_send_callback` must be specified. If the
+ * The :type:`nghttp2_send_callback2` must be specified. If the
* application code uses `nghttp2_session_recv()`, the
* :type:`nghttp2_recv_callback` must be specified. The other members
* of |callbacks| can be ``NULL``.
@@ -2807,7 +3239,7 @@ nghttp2_session_client_new(nghttp2_session **session_ptr,
* does not store |callbacks|. The |user_data| is an arbitrary user
* supplied data, which will be passed to the callback functions.
*
- * The :type:`nghttp2_send_callback` must be specified. If the
+ * The :type:`nghttp2_send_callback2` must be specified. If the
* application code uses `nghttp2_session_recv()`, the
* :type:`nghttp2_recv_callback` must be specified. The other members
* of |callbacks| can be ``NULL``.
@@ -2943,7 +3375,7 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
* This function retrieves the highest prioritized frame from the
* outbound queue and sends it to the remote peer. It does this as
* many times as possible until the user callback
- * :type:`nghttp2_send_callback` returns
+ * :type:`nghttp2_send_callback2` returns
* :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue
* becomes empty or flow control is triggered (remote window size
* becomes depleted or maximum number of concurrent streams is
@@ -2973,7 +3405,7 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
* :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort
* the following steps.
*
- * 8. :type:`nghttp2_send_callback` is invoked one or more times to
+ * 8. :type:`nghttp2_send_callback2` is invoked one or more times to
* send the frame.
*
* 9. :type:`nghttp2_on_frame_send_callback` is invoked.
@@ -2992,9 +3424,14 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
*/
NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_session_mem_send2()` instead.
+ *
* Returns the serialized data to send.
*
* This function behaves like `nghttp2_session_send()` except that it
@@ -3034,6 +3471,50 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
const uint8_t **data_ptr);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Returns the serialized data to send.
+ *
+ * This function behaves like `nghttp2_session_send()` except that it
+ * does not use :type:`nghttp2_send_callback2` to transmit data.
+ * Instead, it assigns the pointer to the serialized data to the
+ * |*data_ptr| and returns its length. The other callbacks are called
+ * in the same way as they are in `nghttp2_session_send()`.
+ *
+ * If no data is available to send, this function returns 0.
+ *
+ * This function may not return all serialized data in one invocation.
+ * To get all data, call this function repeatedly until it returns 0
+ * or one of negative error codes.
+ *
+ * The assigned |*data_ptr| is valid until the next call of
+ * `nghttp2_session_mem_send2()` or `nghttp2_session_send()`.
+ *
+ * The caller must send all data before sending the next chunk of
+ * data.
+ *
+ * This function returns the length of the data pointed by the
+ * |*data_ptr| if it succeeds, or one of the following negative error
+ * codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ *
+ * .. note::
+ *
+ * This function may produce very small byte string. If that is the
+ * case, and application disables Nagle algorithm (``TCP_NODELAY``),
+ * then writing this small chunk leads to very small packet, and it
+ * is very inefficient. An application should be responsible to
+ * buffer up small chunks of data as necessary to avoid this
+ * situation.
+ */
+NGHTTP2_EXTERN nghttp2_ssize
+nghttp2_session_mem_send2(nghttp2_session *session, const uint8_t **data_ptr);
+
/**
* @function
*
@@ -3104,9 +3585,14 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
*/
NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_session_mem_recv2()` instead.
+ *
* Processes data |in| as an input from the remote endpoint. The
* |inlen| indicates the number of bytes to receive in the |in|.
*
@@ -3145,6 +3631,49 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
const uint8_t *in,
size_t inlen);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Processes data |in| as an input from the remote endpoint. The
+ * |inlen| indicates the number of bytes to receive in the |in|.
+ *
+ * This function behaves like `nghttp2_session_recv()` except that it
+ * does not use :type:`nghttp2_recv_callback` to receive data; the
+ * |in| is the only data for the invocation of this function. If all
+ * bytes are processed, this function returns. The other callbacks
+ * are called in the same way as they are in `nghttp2_session_recv()`.
+ *
+ * In the current implementation, this function always tries to
+ * processes |inlen| bytes of input data unless either an error occurs or
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from
+ * :type:`nghttp2_on_header_callback` or
+ * :type:`nghttp2_on_data_chunk_recv_callback`. If
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value
+ * includes the number of bytes which was used to produce the data or
+ * frame for the callback.
+ *
+ * This function returns the number of processed bytes, or one of the
+ * following negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
+ * The callback function failed.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ * Invalid client magic was detected. This error only returns
+ * when |session| was configured as server and
+ * `nghttp2_option_set_no_recv_client_magic()` is not used with
+ * nonzero value.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED`
+ * Flooding was detected in this HTTP/2 session, and it must be
+ * closed. This is most likely caused by misbehaviour of peer.
+ */
+NGHTTP2_EXTERN nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
+ const uint8_t *in,
+ size_t inlen);
+
/**
* @function
*
@@ -3190,7 +3719,7 @@ NGHTTP2_EXTERN int nghttp2_session_want_write(nghttp2_session *session);
* @function
*
* Returns stream_user_data for the stream |stream_id|. The
- * stream_user_data is provided by `nghttp2_submit_request()`,
+ * stream_user_data is provided by `nghttp2_submit_request2()`,
* `nghttp2_submit_headers()` or
* `nghttp2_session_set_stream_user_data()`. Unless it is set using
* `nghttp2_session_set_stream_user_data()`, if the stream is
@@ -3626,6 +4155,13 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return 0 without doing anything.
+ *
* Changes priority of existing stream denoted by |stream_id|. The
* new priority specification is |pri_spec|.
*
@@ -3665,6 +4201,13 @@ nghttp2_session_change_stream_priority(nghttp2_session *session,
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return 0 without doing anything.
+ *
* Creates idle stream with the given |stream_id|, and priority
* |pri_spec|.
*
@@ -3715,10 +4258,6 @@ nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
/**
* @function
*
- * Performs post-process of HTTP Upgrade request. This function can
- * be called from both client and server, but the behavior is very
- * different in each other.
- *
* .. warning::
*
* This function is deprecated in favor of
@@ -3730,6 +4269,10 @@ nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
* HEAD is used in request, the length of response body must be 0
* regardless of value included in content-length header field.
*
+ * Performs post-process of HTTP Upgrade request. This function can
+ * be called from both client and server, but the behavior is very
+ * different in each other.
+ *
* If called from client side, the |settings_payload| must be the
* value sent in ``HTTP2-Settings`` header field and must be decoded
* by base64url decoder. The |settings_payloadlen| is the length of
@@ -3809,9 +4352,14 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
int head_request,
void *stream_user_data);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_pack_settings_payload2()` instead.
+ *
* Serializes the SETTINGS values |iv| in the |buf|. The size of the
* |buf| is specified by |buflen|. The number of entries in the |iv|
* array is given by |niv|. The required space in |buf| for the |niv|
@@ -3833,6 +4381,32 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Serializes the SETTINGS values |iv| in the |buf|. The size of the
+ * |buf| is specified by |buflen|. The number of entries in the |iv|
+ * array is given by |niv|. The required space in |buf| for the |niv|
+ * entries is ``6*niv`` bytes and if the given buffer is too small, an
+ * error is returned. This function is used mainly for creating a
+ * SETTINGS payload to be sent with the ``HTTP2-Settings`` header
+ * field in an HTTP Upgrade request. The data written in |buf| is NOT
+ * base64url encoded and the application is responsible for encoding.
+ *
+ * This function returns the number of bytes written in |buf|, or one
+ * of the following negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |iv| contains duplicate settings ID or invalid value.
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN nghttp2_ssize nghttp2_pack_settings_payload2(
+ uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
+
/**
* @function
*
@@ -3854,6 +4428,12 @@ NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* Initializes |pri_spec| with the |stream_id| of the stream to depend
* on with |weight| and its exclusive flag. If |exclusive| is
* nonzero, exclusive flag is set.
@@ -3868,6 +4448,12 @@ NGHTTP2_EXTERN void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* Initializes |pri_spec| with the default values. The default values
* are: stream_id = 0, weight = :macro:`NGHTTP2_DEFAULT_WEIGHT` and
* exclusive = 0.
@@ -3878,18 +4464,29 @@ nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* Returns nonzero if the |pri_spec| is filled with default values.
*/
NGHTTP2_EXTERN int
nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_submit_request2()` instead.
+ *
* Submits HEADERS frame and optionally one or more DATA frames.
*
- * The |pri_spec| is priority specification of this request. ``NULL``
- * means the default priority (see
+ * The |pri_spec| is a deprecated priority specification of this
+ * request. ``NULL`` means the default priority (see
* `nghttp2_priority_spec_default_init()`). To specify the priority,
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
* this function will copy its data members.
@@ -3970,9 +4567,105 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd,
void *stream_user_data);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
/**
* @function
*
+ * Submits HEADERS frame and optionally one or more DATA frames.
+ *
+ * The |pri_spec| is a deprecated priority specification of this
+ * request. ``NULL`` means the default priority (see
+ * `nghttp2_priority_spec_default_init()`). To specify the priority,
+ * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
+ * this function will copy its data members. In the future release
+ * after the end of 2024, this function will ignore |pri_spec| and
+ * behave as if ``NULL`` is given.
+ *
+ * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
+ * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
+ * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
+ * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
+ * :macro:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is received by a remote endpoint, |pri_spec| is
+ * ignored, and treated as if ``NULL`` is specified.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements. The application is responsible to include
+ * required pseudo-header fields (header field whose name starts with
+ * ":") in |nva| and must place pseudo-headers before regular header
+ * fields.
+ *
+ * This function creates copies of all name/value pairs in |nva|. It
+ * also lower-cases all names in |nva|. The order of elements in
+ * |nva| is preserved. For header fields with
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * HTTP/2 specification has requirement about header fields in the
+ * request HEADERS. See the specification for more details.
+ *
+ * If |data_prd| is not ``NULL``, it provides data which will be sent
+ * in subsequent DATA frames. In this case, a method that allows
+ * request message bodies
+ * (https://tools.ietf.org/html/rfc7231#section-4) must be specified
+ * with ``:method`` key in |nva| (e.g. ``POST``). This function does
+ * not take ownership of the |data_prd|. The function copies the
+ * members of the |data_prd|. If |data_prd| is ``NULL``, HEADERS have
+ * END_STREAM set. The |stream_user_data| is data associated to the
+ * stream opened by this request and can be an arbitrary pointer,
+ * which can be retrieved later by
+ * `nghttp2_session_get_stream_user_data()`.
+ *
+ * This function returns assigned stream ID if it succeeds, or one of
+ * the following negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ * No stream ID is available because maximum stream ID was
+ * reached.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ * Trying to depend on itself (new stream ID equals
+ * ``pri_spec->stream_id``).
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
+ * The |session| is server session.
+ *
+ * .. warning::
+ *
+ * This function returns assigned stream ID if it succeeds. But
+ * that stream is not created yet. The application must not submit
+ * frame to that stream ID before
+ * :type:`nghttp2_before_frame_send_callback` is called for this
+ * frame. This means `nghttp2_session_get_stream_user_data()` does
+ * not work before the callback. But
+ * `nghttp2_session_set_stream_user_data()` handles this situation
+ * specially, and it can set data to a stream during this period.
+ *
+ */
+NGHTTP2_EXTERN int32_t nghttp2_submit_request2(
+ nghttp2_session *session, const nghttp2_priority_spec *pri_spec,
+ const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider2 *data_prd,
+ void *stream_user_data);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_submit_response2()` instead.
+ *
* Submits response HEADERS frame and optionally one or more DATA
* frames against the stream |stream_id|.
*
@@ -4039,6 +4732,77 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider *data_prd);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Submits response HEADERS frame and optionally one or more DATA
+ * frames against the stream |stream_id|.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements. The application is responsible to include
+ * required pseudo-header fields (header field whose name starts with
+ * ":") in |nva| and must place pseudo-headers before regular header
+ * fields.
+ *
+ * This function creates copies of all name/value pairs in |nva|. It
+ * also lower-cases all names in |nva|. The order of elements in
+ * |nva| is preserved. For header fields with
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively. With
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application
+ * is responsible to pass header field name in lowercase. The
+ * application should maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * HTTP/2 specification has requirement about header fields in the
+ * response HEADERS. See the specification for more details.
+ *
+ * If |data_prd| is not ``NULL``, it provides data which will be sent
+ * in subsequent DATA frames. This function does not take ownership
+ * of the |data_prd|. The function copies the members of the
+ * |data_prd|. If |data_prd| is ``NULL``, HEADERS will have
+ * END_STREAM flag set.
+ *
+ * This method can be used as normal HTTP response and push response.
+ * When pushing a resource using this function, the |session| must be
+ * configured using `nghttp2_session_server_new()` or its variants and
+ * the target stream denoted by the |stream_id| must be reserved using
+ * `nghttp2_submit_push_promise()`.
+ *
+ * To send non-final response headers (e.g., HTTP status 101), don't
+ * use this function because this function half-closes the outbound
+ * stream. Instead, use `nghttp2_submit_headers()` for this purpose.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |stream_id| is 0.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
+ * DATA or HEADERS has been already submitted and not fully
+ * processed yet. Normally, this does not happen, but when
+ * application wrongly calls `nghttp2_submit_response2()` twice,
+ * this may happen.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
+ * The |session| is client session.
+ *
+ * .. warning::
+ *
+ * Calling this function twice for the same stream ID may lead to
+ * program crash. It is generally considered to a programming error
+ * to commit response twice.
+ */
+NGHTTP2_EXTERN int
+nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider2 *data_prd);
+
/**
* @function
*
@@ -4064,22 +4828,23 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
* DATA without END_STREAM flat set. The library does not enforce
* this requirement, and applications should do this for themselves.
* If `nghttp2_submit_trailer()` is called before any response HEADERS
- * submission (usually by `nghttp2_submit_response()`), the content of
- * |nva| will be sent as response headers, which will result in error.
+ * submission (usually by `nghttp2_submit_response2()`), the content
+ * of |nva| will be sent as response headers, which will result in
+ * error.
*
* This function has the same effect with `nghttp2_submit_headers()`,
* with flags = :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both
* pri_spec and stream_user_data to NULL.
*
- * To submit trailer fields after `nghttp2_submit_response()` is
+ * To submit trailer fields after `nghttp2_submit_response2()` is
* called, the application has to specify
- * :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
- * Inside of :type:`nghttp2_data_source_read_callback`, when setting
+ * :type:`nghttp2_data_provider2` to `nghttp2_submit_response2()`.
+ * Inside of :type:`nghttp2_data_source_read_callback2`, when setting
* :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set
* :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`. After
* that, the application can send trailer fields using
* `nghttp2_submit_trailer()`. `nghttp2_submit_trailer()` can be used
- * inside :type:`nghttp2_data_source_read_callback`.
+ * inside :type:`nghttp2_data_source_read_callback2`.
*
* This function returns 0 if it succeeds and |stream_id| is -1.
* Otherwise, this function returns 0 if it succeeds, or one of the
@@ -4114,11 +4879,13 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* assigned stream ID will be returned. Otherwise, specify stream ID
* in |stream_id|.
*
- * The |pri_spec| is priority specification of this request. ``NULL``
- * means the default priority (see
+ * The |pri_spec| is a deprecated priority specification of this
+ * request. ``NULL`` means the default priority (see
* `nghttp2_priority_spec_default_init()`). To specify the priority,
* use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
- * this function will copy its data members.
+ * this function will copy its data members. In the future release
+ * after the end of 2024, this function will ignore |pri_spec| and
+ * behave as if ``NULL`` is given.
*
* The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
* :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
@@ -4156,8 +4923,8 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
*
* This function is low-level in a sense that the application code can
* specify flags directly. For usual HTTP request,
- * `nghttp2_submit_request()` is useful. Likewise, for HTTP response,
- * prefer `nghttp2_submit_response()`.
+ * `nghttp2_submit_request2()` is useful. Likewise, for HTTP
+ * response, prefer `nghttp2_submit_response2()`.
*
* This function returns newly assigned stream ID if it succeeds and
* |stream_id| is -1. Otherwise, this function returns 0 if it
@@ -4192,9 +4959,14 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen,
void *stream_user_data);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_submit_data2()` instead.
+ *
* Submits one or more DATA frames to the stream |stream_id|. The
* data to be sent are provided by |data_prd|. If |flags| contains
* :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
@@ -4237,19 +5009,73 @@ NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const nghttp2_data_provider *data_prd);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
/**
* @function
*
+ * Submits one or more DATA frames to the stream |stream_id|. The
+ * data to be sent are provided by |data_prd|. If |flags| contains
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
+ * has END_STREAM flag set.
+ *
+ * This function does not take ownership of the |data_prd|. The
+ * function copies the members of the |data_prd|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
+ * DATA or HEADERS has been already submitted and not fully
+ * processed yet.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ * The |stream_id| is 0.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED`
+ * The stream was already closed; or the |stream_id| is invalid.
+ *
+ * .. note::
+ *
+ * Currently, only one DATA or HEADERS is allowed for a stream at a
+ * time. Submitting these frames more than once before first DATA
+ * or HEADERS is finished results in
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code. The
+ * earliest callback which tells that previous frame is done is
+ * :type:`nghttp2_on_frame_send_callback`. In side that callback,
+ * new data can be submitted using `nghttp2_submit_data2()`. Of
+ * course, all data except for last one must not have
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|.
+ * This sounds a bit complicated, and we recommend to use
+ * `nghttp2_submit_request2()` and `nghttp2_submit_response2()` to
+ * avoid this cascading issue. The experience shows that for HTTP
+ * use, these two functions are enough to implement both client and
+ * server.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_data_provider2 *data_prd);
+
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return 0 without doing anything.
+ *
* Submits PRIORITY frame to change the priority of stream |stream_id|
* to the priority specification |pri_spec|.
*
* The |flags| is currently ignored and should be
* :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
*
- * The |pri_spec| is priority specification of this request. ``NULL``
- * is not allowed for this function. To specify the priority, use
- * `nghttp2_priority_spec_init()`. This function will copy its data
- * members.
+ * The |pri_spec| is a deprecated priority specification of this
+ * request. ``NULL`` is not allowed for this function. To specify the
+ * priority, use `nghttp2_priority_spec_init()`. This function will
+ * copy its data members.
*
* The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
* :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
@@ -4429,7 +5255,7 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
* The client side is not allowed to use this function.
*
* To submit response headers and data, use
- * `nghttp2_submit_response()`.
+ * `nghttp2_submit_response2()`.
*
* This function returns assigned promised stream ID if it succeeds,
* or one of the following negative error codes:
@@ -4568,10 +5394,11 @@ nghttp2_session_get_last_proc_stream_id(nghttp2_session *session);
* reasons are: session is server; stream ID has been spent; GOAWAY
* has been sent or received.
*
- * The application can call `nghttp2_submit_request()` without
- * consulting this function. In that case, `nghttp2_submit_request()`
- * may return error. Or, request is failed to sent, and
- * :type:`nghttp2_on_stream_close_callback` is called.
+ * The application can call `nghttp2_submit_request2()` without
+ * consulting this function. In that case,
+ * `nghttp2_submit_request2()` may return error. Or, request is
+ * failed to sent, and :type:`nghttp2_on_stream_close_callback` is
+ * called.
*/
NGHTTP2_EXTERN int
nghttp2_session_check_request_allowed(nghttp2_session *session);
@@ -4673,11 +5500,11 @@ nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
* Application can pass arbitrary frame flags and stream ID in |flags|
* and |stream_id| respectively. The |payload| is opaque pointer, and
* it can be accessible though ``frame->ext.payload`` in
- * :type:`nghttp2_pack_extension_callback`. The library will not own
+ * :type:`nghttp2_pack_extension_callback2`. The library will not own
* passed |payload| pointer.
*
- * The application must set :type:`nghttp2_pack_extension_callback`
- * using `nghttp2_session_callbacks_set_pack_extension_callback()`.
+ * The application must set :type:`nghttp2_pack_extension_callback2`
+ * using `nghttp2_session_callbacks_set_pack_extension_callback2()`.
*
* The application should retain the memory pointed by |payload| until
* the transmission of extension frame is done (which is indicated by
@@ -4685,7 +5512,7 @@ nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
* (which is indicated by :type:`nghttp2_on_frame_not_send_callback`).
* If application does not touch this memory region after packing it
* into a wire format, application can free it inside
- * :type:`nghttp2_pack_extension_callback`.
+ * :type:`nghttp2_pack_extension_callback2`.
*
* The standard HTTP/2 frame cannot be sent with this function, so
* |type| must be strictly grater than 0x9. Otherwise, this function
@@ -4696,7 +5523,7 @@ nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
* negative error codes:
*
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
- * If :type:`nghttp2_pack_extension_callback` is not set.
+ * If :type:`nghttp2_pack_extension_callback2` is not set.
* :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
* If |type| specifies standard HTTP/2 frame type. The frame
* types in the rage [0x0, 0x9], both inclusive, are standard
@@ -5317,9 +6144,14 @@ NGHTTP2_EXTERN int
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
size_t settings_max_dynamic_table_size);
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_hd_deflate_hd2()` instead.
+ *
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
* the |buf| of length |buflen|.
*
@@ -5349,9 +6181,47 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
const nghttp2_nv *nva,
size_t nvlen);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |buf| of length |buflen|.
+ *
+ * If |buf| is not large enough to store the deflated header block,
+ * this function fails with
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
+ * should use `nghttp2_hd_deflate_bound()` to know the upper bound of
+ * buffer size required to deflate given header name/value pairs.
+ *
+ * Once this function fails, subsequent call of this function always
+ * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns the number of bytes written to |buf| if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
+ * Deflation process has failed.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN nghttp2_ssize
+nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater, uint8_t *buf,
+ size_t buflen, const nghttp2_nv *nva, size_t nvlen);
+
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_hd_deflate_hd_vec2()` instead.
+ *
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
* the |veclen| size of buf vector |vec|. The each size of buffer
* must be set in len field of :type:`nghttp2_vec`. If and only if
@@ -5383,6 +6253,40 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
const nghttp2_nv *nva,
size_t nvlen);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |veclen| size of buf vector |vec|. The each size of buffer
+ * must be set in len field of :type:`nghttp2_vec`. If and only if
+ * one chunk is filled up completely, next chunk will be used. If
+ * |vec| is not large enough to store the deflated header block, this
+ * function fails with
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
+ * should use `nghttp2_hd_deflate_bound()` to know the upper bound of
+ * buffer size required to deflate given header name/value pairs.
+ *
+ * Once this function fails, subsequent call of this function always
+ * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns the number of bytes written to |vec| if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
+ * Deflation process has failed.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
+ * The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_deflate_hd_vec2(
+ nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen,
+ const nghttp2_nv *nva, size_t nvlen);
+
/**
* @function
*
@@ -5496,7 +6400,7 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
* This function must not be called while header block is being
* inflated. In other words, this function must be called after
* initialization of |inflater|, but before calling
- * `nghttp2_hd_inflate_hd2()`, or after
+ * `nghttp2_hd_inflate_hd3()`, or after
* `nghttp2_hd_inflate_end_headers()`. Otherwise,
* `NGHTTP2_ERR_INVALID_STATE` was returned.
*
@@ -5534,6 +6438,7 @@ typedef enum {
NGHTTP2_HD_INFLATE_EMIT = 0x02
} nghttp2_hd_inflate_flag;
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
@@ -5621,9 +6526,16 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
int *inflate_flags, uint8_t *in,
size_t inlen, int in_final);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+#ifndef NGHTTP2_NO_SSIZE_T
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. Use `nghttp2_hd_inflate_hd3()` instead.
+ *
* Inflates name/value block stored in |in| with length |inlen|. This
* function performs decompression. For each successful emission of
* header name/value pair,
@@ -5710,6 +6622,95 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
const uint8_t *in, size_t inlen,
int in_final);
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Inflates name/value block stored in |in| with length |inlen|. This
+ * function performs decompression. For each successful emission of
+ * header name/value pair,
+ * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in
+ * |*inflate_flags| and name/value pair is assigned to the |nv_out|
+ * and the function returns. The caller must not free the members of
+ * |nv_out|.
+ *
+ * The |nv_out| may include pointers to the memory region in the |in|.
+ * The caller must retain the |in| while the |nv_out| is used.
+ *
+ * The application should call this function repeatedly until the
+ * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
+ * return value is non-negative. If that happens, all given input
+ * data (|inlen| bytes) are processed successfully. Then the
+ * application must call `nghttp2_hd_inflate_end_headers()` to prepare
+ * for the next header block input.
+ *
+ * In other words, if |in_final| is nonzero, and this function returns
+ * |inlen|, you can assert that
+ * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in
+ * |*inflate_flags|.
+ *
+ * The caller can feed complete compressed header block. It also can
+ * feed it in several chunks. The caller must set |in_final| to
+ * nonzero if the given input is the last block of the compressed
+ * header.
+ *
+ * This function returns the number of bytes processed if it succeeds,
+ * or one of the following negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
+ * Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
+ * Inflation process has failed.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR`
+ * The header field name or value is too large.
+ *
+ * Example follows::
+ *
+ * int inflate_header_block(nghttp2_hd_inflater *hd_inflater,
+ * uint8_t *in, size_t inlen, int final)
+ * {
+ * nghttp2_ssize rv;
+ *
+ * for(;;) {
+ * nghttp2_nv nv;
+ * int inflate_flags = 0;
+ *
+ * rv = nghttp2_hd_inflate_hd3(hd_inflater, &nv, &inflate_flags,
+ * in, inlen, final);
+ *
+ * if(rv < 0) {
+ * fprintf(stderr, "inflate failed with error code %td", rv);
+ * return -1;
+ * }
+ *
+ * in += rv;
+ * inlen -= rv;
+ *
+ * if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
+ * fwrite(nv.name, nv.namelen, 1, stderr);
+ * fprintf(stderr, ": ");
+ * fwrite(nv.value, nv.valuelen, 1, stderr);
+ * fprintf(stderr, "\n");
+ * }
+ * if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
+ * nghttp2_hd_inflate_end_headers(hd_inflater);
+ * break;
+ * }
+ * if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 &&
+ * inlen == 0) {
+ * break;
+ * }
+ * }
+ *
+ * return 0;
+ * }
+ *
+ */
+NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_inflate_hd3(
+ nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags,
+ const uint8_t *in, size_t inlen, int in_final);
+
/**
* @function
*
@@ -5783,8 +6784,8 @@ typedef struct nghttp2_stream nghttp2_stream;
* `nghttp2_session_get_root_stream()`) if 0 is given in |stream_id|.
*
* Unless |stream_id| == 0, the returned pointer is valid until next
- * call of `nghttp2_session_send()`, `nghttp2_session_mem_send()`,
- * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv()`.
+ * call of `nghttp2_session_send()`, `nghttp2_session_mem_send2()`,
+ * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv2()`.
*/
NGHTTP2_EXTERN nghttp2_stream *
nghttp2_session_find_stream(nghttp2_session *session, int32_t stream_id);
@@ -5838,6 +6839,12 @@ nghttp2_stream_get_state(nghttp2_stream *stream);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme.
+ *
* Returns root of dependency tree, which is imaginary stream with
* stream ID 0. The returned pointer is valid until |session| is
* freed by `nghttp2_session_del()`.
@@ -5848,6 +6855,13 @@ nghttp2_session_get_root_stream(nghttp2_session *session);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return NULL.
+ *
* Returns the parent stream of |stream| in dependency tree. Returns
* NULL if there is no such stream.
*/
@@ -5859,6 +6873,13 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return NULL.
+ *
* Returns the next sibling stream of |stream| in dependency tree.
* Returns NULL if there is no such stream.
*/
@@ -5868,6 +6889,13 @@ nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return NULL.
+ *
* Returns the previous sibling stream of |stream| in dependency tree.
* Returns NULL if there is no such stream.
*/
@@ -5877,6 +6905,13 @@ nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return NULL.
+ *
* Returns the first child stream of |stream| in dependency tree.
* Returns NULL if there is no such stream.
*/
@@ -5886,6 +6921,14 @@ nghttp2_stream_get_first_child(nghttp2_stream *stream);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return
+ * :macro:`NGHTTP2_DEFAULT_WEIGHT`.
+ *
* Returns dependency weight to the parent stream of |stream|.
*/
NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
@@ -5893,6 +6936,13 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
/**
* @function
*
+ * .. warning::
+ *
+ * Deprecated. :rfc:`7540` priorities are deprecated by
+ * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
+ * prioritization scheme. In the future release after the end of
+ * 2024, this function will always return 0.
+ *
* Returns the sum of the weight for |stream|'s children.
*/
NGHTTP2_EXTERN int32_t
diff --git a/lib/nghttp2_buf.c b/lib/nghttp2_buf.c
index a328447..101035f 100644
--- a/lib/nghttp2_buf.c
+++ b/lib/nghttp2_buf.c
@@ -430,7 +430,7 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b) {
return 0;
}
-ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
+nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
size_t len;
nghttp2_buf_chain *chain;
nghttp2_buf *buf;
@@ -462,7 +462,7 @@ ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
*out = res;
- return (ssize_t)len;
+ return (nghttp2_ssize)len;
}
size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) {
diff --git a/lib/nghttp2_buf.h b/lib/nghttp2_buf.h
index 45f62f1..95ff370 100644
--- a/lib/nghttp2_buf.h
+++ b/lib/nghttp2_buf.h
@@ -349,7 +349,7 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
-ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
+nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
/*
* Copies all data stored in |bufs| to |out|. This function assumes
diff --git a/lib/nghttp2_callbacks.c b/lib/nghttp2_callbacks.c
index 3c38214..1776f7d 100644
--- a/lib/nghttp2_callbacks.c
+++ b/lib/nghttp2_callbacks.c
@@ -45,11 +45,21 @@ void nghttp2_session_callbacks_set_send_callback(
cbs->send_callback = send_callback;
}
+void nghttp2_session_callbacks_set_send_callback2(
+ nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) {
+ cbs->send_callback2 = send_callback;
+}
+
void nghttp2_session_callbacks_set_recv_callback(
nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) {
cbs->recv_callback = recv_callback;
}
+void nghttp2_session_callbacks_set_recv_callback2(
+ nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) {
+ cbs->recv_callback2 = recv_callback;
+}
+
void nghttp2_session_callbacks_set_on_frame_recv_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_frame_recv_callback on_frame_recv_callback) {
@@ -128,12 +138,24 @@ void nghttp2_session_callbacks_set_select_padding_callback(
cbs->select_padding_callback = select_padding_callback;
}
+void nghttp2_session_callbacks_set_select_padding_callback2(
+ nghttp2_session_callbacks *cbs,
+ nghttp2_select_padding_callback2 select_padding_callback) {
+ cbs->select_padding_callback2 = select_padding_callback;
+}
+
void nghttp2_session_callbacks_set_data_source_read_length_callback(
nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback data_source_read_length_callback) {
cbs->read_length_callback = data_source_read_length_callback;
}
+void nghttp2_session_callbacks_set_data_source_read_length_callback2(
+ nghttp2_session_callbacks *cbs, nghttp2_data_source_read_length_callback2
+ data_source_read_length_callback) {
+ cbs->read_length_callback2 = data_source_read_length_callback;
+}
+
void nghttp2_session_callbacks_set_on_begin_frame_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_begin_frame_callback on_begin_frame_callback) {
@@ -152,6 +174,12 @@ void nghttp2_session_callbacks_set_pack_extension_callback(
cbs->pack_extension_callback = pack_extension_callback;
}
+void nghttp2_session_callbacks_set_pack_extension_callback2(
+ nghttp2_session_callbacks *cbs,
+ nghttp2_pack_extension_callback2 pack_extension_callback) {
+ cbs->pack_extension_callback2 = pack_extension_callback;
+}
+
void nghttp2_session_callbacks_set_unpack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_unpack_extension_callback unpack_extension_callback) {
diff --git a/lib/nghttp2_callbacks.h b/lib/nghttp2_callbacks.h
index 61e51fa..a611f48 100644
--- a/lib/nghttp2_callbacks.h
+++ b/lib/nghttp2_callbacks.h
@@ -36,19 +36,33 @@
*/
struct nghttp2_session_callbacks {
/**
+ * Deprecated. Use send_callback2 instead. Callback function
+ * invoked when the session wants to send data to the remote peer.
+ * This callback is not necessary if the application uses solely
+ * `nghttp2_session_mem_send()` to serialize data to transmit.
+ */
+ nghttp2_send_callback send_callback;
+ /**
* Callback function invoked when the session wants to send data to
* the remote peer. This callback is not necessary if the
- * application uses solely `nghttp2_session_mem_send()` to serialize
- * data to transmit.
+ * application uses solely `nghttp2_session_mem_send2()` to
+ * serialize data to transmit.
*/
- nghttp2_send_callback send_callback;
+ nghttp2_send_callback2 send_callback2;
+ /**
+ * Deprecated. Use recv_callback2 instead. Callback function
+ * invoked when the session wants to receive data from the remote
+ * peer. This callback is not necessary if the application uses
+ * solely `nghttp2_session_mem_recv()` to process received data.
+ */
+ nghttp2_recv_callback recv_callback;
/**
* Callback function invoked when the session wants to receive data
* from the remote peer. This callback is not necessary if the
- * application uses solely `nghttp2_session_mem_recv()` to process
+ * application uses solely `nghttp2_session_mem_recv2()` to process
* received data.
*/
- nghttp2_recv_callback recv_callback;
+ nghttp2_recv_callback2 recv_callback2;
/**
* Callback function invoked by `nghttp2_session_recv()` when a
* frame is received.
@@ -100,22 +114,39 @@ struct nghttp2_session_callbacks {
nghttp2_on_invalid_header_callback on_invalid_header_callback;
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
/**
+ * Deprecated. Use select_padding_callback2 instead. Callback
+ * function invoked when the library asks application how many
+ * padding bytes are required for the transmission of the given
+ * frame.
+ */
+ nghttp2_select_padding_callback select_padding_callback;
+ /**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given
* frame.
*/
- nghttp2_select_padding_callback select_padding_callback;
+ nghttp2_select_padding_callback2 select_padding_callback2;
/**
- * The callback function used to determine the length allowed in
+ * Deprecated. Use read_length_callback2 instead. The callback
+ * function used to determine the length allowed in
* `nghttp2_data_source_read_callback()`
*/
nghttp2_data_source_read_length_callback read_length_callback;
/**
+ * The callback function used to determine the length allowed in
+ * `nghttp2_data_source_read_callback2()`
+ */
+ nghttp2_data_source_read_length_callback2 read_length_callback2;
+ /**
* Sets callback function invoked when a frame header is received.
*/
nghttp2_on_begin_frame_callback on_begin_frame_callback;
nghttp2_send_data_callback send_data_callback;
+ /**
+ * Deprecated. Use pack_extension_callback2 instead.
+ */
nghttp2_pack_extension_callback pack_extension_callback;
+ nghttp2_pack_extension_callback2 pack_extension_callback2;
nghttp2_unpack_extension_callback unpack_extension_callback;
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback;
diff --git a/lib/nghttp2_hd.c b/lib/nghttp2_hd.c
index 8a2bda6..1b0c713 100644
--- a/lib/nghttp2_hd.c
+++ b/lib/nghttp2_hd.c
@@ -850,9 +850,10 @@ static size_t encode_length(uint8_t *buf, size_t n, size_t prefix) {
* in the next call will be stored in |*shift_ptr|) and returns number
* of bytes processed, or returns -1, indicating decoding error.
*/
-static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
- uint32_t initial, size_t shift, const uint8_t *in,
- const uint8_t *last, size_t prefix) {
+static nghttp2_ssize decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
+ uint32_t initial, size_t shift,
+ const uint8_t *in, const uint8_t *last,
+ size_t prefix) {
uint32_t k = (uint8_t)((1 << prefix) - 1);
uint32_t n = initial;
const uint8_t *start = in;
@@ -871,7 +872,7 @@ static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
if (++in == last) {
*res = n;
- return (ssize_t)(in - start);
+ return (nghttp2_ssize)(in - start);
}
}
@@ -906,12 +907,12 @@ static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
if (in == last) {
*res = n;
- return (ssize_t)(in - start);
+ return (nghttp2_ssize)(in - start);
}
*res = n;
*fin = 1;
- return (ssize_t)(in + 1 - start);
+ return (nghttp2_ssize)(in + 1 - start);
}
static int emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
@@ -1164,7 +1165,7 @@ static int add_hd_table_incremental(nghttp2_hd_context *context,
}
typedef struct {
- ssize_t index;
+ nghttp2_ssize index;
/* Nonzero if both name and value are matched. */
int name_value_match;
} search_result;
@@ -1213,8 +1214,8 @@ static search_result search_hd_table(nghttp2_hd_context *context,
return res;
}
- res.index =
- (ssize_t)(context->next_seq - 1 - ent->seq + NGHTTP2_STATIC_TABLE_LENGTH);
+ res.index = (nghttp2_ssize)(context->next_seq - 1 - ent->seq +
+ NGHTTP2_STATIC_TABLE_LENGTH);
res.name_value_match = exact_match;
return res;
@@ -1343,7 +1344,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
const nghttp2_nv *nv) {
int rv;
search_result res;
- ssize_t idx;
+ nghttp2_ssize idx;
int indexing_mode;
int32_t token;
nghttp2_mem *mem;
@@ -1379,7 +1380,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
if (res.name_value_match) {
- DEBUGF("deflatehd: name/value match index=%zd\n", idx);
+ DEBUGF("deflatehd: name/value match index=%td\n", idx);
rv = emit_indexed_block(bufs, (size_t)idx);
if (rv != 0) {
@@ -1390,7 +1391,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
}
if (res.index != -1) {
- DEBUGF("deflatehd: name match index=%zd\n", res.index);
+ DEBUGF("deflatehd: name match index=%td\n", res.index);
}
if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) {
@@ -1491,6 +1492,12 @@ fail:
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
size_t buflen, const nghttp2_nv *nv,
size_t nvlen) {
+ return (ssize_t)nghttp2_hd_deflate_hd2(deflater, buf, buflen, nv, nvlen);
+}
+
+nghttp2_ssize nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater,
+ uint8_t *buf, size_t buflen,
+ const nghttp2_nv *nv, size_t nvlen) {
nghttp2_bufs bufs;
int rv;
nghttp2_mem *mem;
@@ -1517,12 +1524,18 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
return rv;
}
- return (ssize_t)buflen;
+ return (nghttp2_ssize)buflen;
}
ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
const nghttp2_vec *vec, size_t veclen,
const nghttp2_nv *nv, size_t nvlen) {
+ return (ssize_t)nghttp2_hd_deflate_hd_vec2(deflater, vec, veclen, nv, nvlen);
+}
+
+nghttp2_ssize nghttp2_hd_deflate_hd_vec2(nghttp2_hd_deflater *deflater,
+ const nghttp2_vec *vec, size_t veclen,
+ const nghttp2_nv *nv, size_t nvlen) {
nghttp2_bufs bufs;
int rv;
nghttp2_mem *mem;
@@ -1550,7 +1563,7 @@ ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
return rv;
}
- return (ssize_t)buflen;
+ return (nghttp2_ssize)buflen;
}
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
@@ -1643,10 +1656,11 @@ static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater,
* NGHTTP2_ERR_HEADER_COMP
* Integer decoding failed
*/
-static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
- const uint8_t *in, const uint8_t *last,
- size_t prefix, size_t maxlen) {
- ssize_t rv;
+static nghttp2_ssize hd_inflate_read_len(nghttp2_hd_inflater *inflater,
+ int *rfin, const uint8_t *in,
+ const uint8_t *last, size_t prefix,
+ size_t maxlen) {
+ nghttp2_ssize rv;
uint32_t out;
*rfin = 0;
@@ -1684,10 +1698,10 @@ static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
* NGHTTP2_ERR_HEADER_COMP
* Huffman decoding failed
*/
-static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
- nghttp2_buf *buf, const uint8_t *in,
- const uint8_t *last) {
- ssize_t readlen;
+static nghttp2_ssize hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
+ nghttp2_buf *buf, const uint8_t *in,
+ const uint8_t *last) {
+ nghttp2_ssize readlen;
int fin = 0;
if ((size_t)(last - in) >= inflater->left) {
last = in + inflater->left;
@@ -1721,14 +1735,15 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
* NGHTTP2_ERR_HEADER_COMP
* Header decompression failed
*/
-static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater, nghttp2_buf *buf,
- const uint8_t *in, const uint8_t *last) {
+static nghttp2_ssize hd_inflate_read(nghttp2_hd_inflater *inflater,
+ nghttp2_buf *buf, const uint8_t *in,
+ const uint8_t *last) {
size_t len = nghttp2_min((size_t)(last - in), inflater->left);
buf->last = nghttp2_cpymem(buf->last, in, len);
inflater->left -= len;
- return (ssize_t)len;
+ return (nghttp2_ssize)len;
}
/*
@@ -1843,7 +1858,15 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out,
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen, int in_final) {
- ssize_t rv;
+ return (nghttp2_ssize)nghttp2_hd_inflate_hd3(inflater, nv_out, inflate_flags,
+ in, inlen, in_final);
+}
+
+nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater,
+ nghttp2_nv *nv_out, int *inflate_flags,
+ const uint8_t *in, size_t inlen,
+ int in_final) {
+ nghttp2_ssize rv;
nghttp2_hd_nv hd_nv;
rv = nghttp2_hd_inflate_hd_nv(inflater, &hd_nv, inflate_flags, in, inlen,
@@ -1866,11 +1889,11 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
return rv;
}
-ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
- nghttp2_hd_nv *nv_out, int *inflate_flags,
- const uint8_t *in, size_t inlen,
- int in_final) {
- ssize_t rv = 0;
+nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
+ nghttp2_hd_nv *nv_out,
+ int *inflate_flags, const uint8_t *in,
+ size_t inlen, int in_final) {
+ nghttp2_ssize rv = 0;
const uint8_t *first = in;
const uint8_t *last = in + inlen;
int rfin = 0;
@@ -1992,7 +2015,7 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_OPCODE;
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
} else {
inflater->index = inflater->left;
--inflater->index;
@@ -2050,7 +2073,7 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
in += rv;
- DEBUGF("inflatehd: %zd bytes read\n", rv);
+ DEBUGF("inflatehd: %td bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2072,7 +2095,7 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
in += rv;
- DEBUGF("inflatehd: %zd bytes read\n", rv);
+ DEBUGF("inflatehd: %td bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2138,7 +2161,7 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
in += rv;
- DEBUGF("inflatehd: %zd bytes read\n", rv);
+ DEBUGF("inflatehd: %td bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2162,18 +2185,18 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_OPCODE;
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
case NGHTTP2_HD_STATE_READ_VALUE:
rv = hd_inflate_read(inflater, &inflater->valuebuf, in, last);
if (rv < 0) {
- DEBUGF("inflatehd: value read failure %zd: %s\n", rv,
+ DEBUGF("inflatehd: value read failure %td: %s\n", rv,
nghttp2_strerror((int)rv));
goto fail;
}
in += rv;
- DEBUGF("inflatehd: %zd bytes read\n", rv);
+ DEBUGF("inflatehd: %td bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2196,7 +2219,7 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_OPCODE;
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
}
@@ -2216,7 +2239,7 @@ ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
}
*inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
}
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
almost_ok:
if (in_final) {
@@ -2226,10 +2249,10 @@ almost_ok:
goto fail;
}
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
fail:
- DEBUGF("inflatehd: error return %zd\n", rv);
+ DEBUGF("inflatehd: error return %td\n", rv);
inflater->ctx.bad = 1;
return rv;
@@ -2297,9 +2320,10 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
return emit_table_size(bufs, table_size);
}
-ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
- uint32_t initial, size_t shift, uint8_t *in,
- uint8_t *last, size_t prefix) {
+nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr,
+ int *fin, uint32_t initial, size_t shift,
+ uint8_t *in, uint8_t *last,
+ size_t prefix) {
return decode_length(res, shift_ptr, fin, initial, shift, in, last, prefix);
}
diff --git a/lib/nghttp2_hd.h b/lib/nghttp2_hd.h
index 6de0052..38a31a8 100644
--- a/lib/nghttp2_hd.h
+++ b/lib/nghttp2_hd.h
@@ -357,9 +357,10 @@ void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
* that return values and semantics are the same as
* nghttp2_hd_inflate_hd().
*/
-ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
- nghttp2_hd_nv *nv_out, int *inflate_flags,
- const uint8_t *in, size_t inlen, int in_final);
+nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
+ nghttp2_hd_nv *nv_out,
+ int *inflate_flags, const uint8_t *in,
+ size_t inlen, int in_final);
/* For unittesting purpose */
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
@@ -376,9 +377,10 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
/* For unittesting purpose */
-ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
- uint32_t initial, size_t shift, uint8_t *in,
- uint8_t *last, size_t prefix);
+nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr,
+ int *fin, uint32_t initial, size_t shift,
+ uint8_t *in, uint8_t *last,
+ size_t prefix);
/* Huffman encoding/decoding functions */
@@ -427,9 +429,9 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
* NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed.
*/
-ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
- nghttp2_buf *buf, const uint8_t *src,
- size_t srclen, int fin);
+nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
+ nghttp2_buf *buf, const uint8_t *src,
+ size_t srclen, int fin);
/*
* nghttp2_hd_huff_decode_failure_state returns nonzero if |ctx|
diff --git a/lib/nghttp2_hd_huffman.c b/lib/nghttp2_hd_huffman.c
index ac90f49..959053f 100644
--- a/lib/nghttp2_hd_huffman.c
+++ b/lib/nghttp2_hd_huffman.c
@@ -107,9 +107,9 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
}
-ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
- nghttp2_buf *buf, const uint8_t *src,
- size_t srclen, int final) {
+nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
+ nghttp2_buf *buf, const uint8_t *src,
+ size_t srclen, int final) {
const uint8_t *end = src + srclen;
nghttp2_huff_decode node = {ctx->fstate, 0};
const nghttp2_huff_decode *t = &node;
@@ -136,7 +136,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return NGHTTP2_ERR_HEADER_COMP;
}
- return (ssize_t)srclen;
+ return (nghttp2_ssize)srclen;
}
int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) {
diff --git a/lib/nghttp2_outbound_item.c b/lib/nghttp2_outbound_item.c
index 2a3041d..a9e9f76 100644
--- a/lib/nghttp2_outbound_item.c
+++ b/lib/nghttp2_outbound_item.c
@@ -27,6 +27,32 @@
#include <assert.h>
#include <string.h>
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw,
+ const nghttp2_data_provider *data_prd) {
+ if (!data_prd) {
+ return NULL;
+ }
+
+ dpw->version = NGHTTP2_DATA_PROVIDER_V1;
+ dpw->data_prd.v1 = *data_prd;
+
+ return dpw;
+}
+
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw,
+ const nghttp2_data_provider2 *data_prd) {
+ if (!data_prd) {
+ return NULL;
+ }
+
+ dpw->version = NGHTTP2_DATA_PROVIDER_V2;
+ dpw->data_prd.v2 = *data_prd;
+
+ return dpw;
+}
+
void nghttp2_outbound_item_init(nghttp2_outbound_item *item) {
item->cycle = 0;
item->qnext = NULL;
diff --git a/lib/nghttp2_outbound_item.h b/lib/nghttp2_outbound_item.h
index bd4611b..4e91750 100644
--- a/lib/nghttp2_outbound_item.h
+++ b/lib/nghttp2_outbound_item.h
@@ -33,9 +33,32 @@
#include "nghttp2_frame.h"
#include "nghttp2_mem.h"
+#define NGHTTP2_DATA_PROVIDER_V1 1
+#define NGHTTP2_DATA_PROVIDER_V2 2
+
+typedef struct nghttp2_data_provider_wrap {
+ int version;
+ union {
+ struct {
+ nghttp2_data_source source;
+ void *read_callback;
+ };
+ nghttp2_data_provider v1;
+ nghttp2_data_provider2 v2;
+ } data_prd;
+} nghttp2_data_provider_wrap;
+
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw,
+ const nghttp2_data_provider *data_prd);
+
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw,
+ const nghttp2_data_provider2 *data_prd);
+
/* struct used for HEADERS and PUSH_PROMISE frame */
typedef struct {
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider_wrap dpw;
void *stream_user_data;
/* error code when request HEADERS is canceled by RST_STREAM while
it is in queue. */
@@ -50,7 +73,7 @@ typedef struct {
/**
* The data to be sent for this DATA frame.
*/
- nghttp2_data_provider data_prd;
+ nghttp2_data_provider_wrap dpw;
/**
* The flags of DATA frame. We use separate flags here and
* nghttp2_data frame. The latter contains flags actually sent to
diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
index ce21caf..226cdd5 100644
--- a/lib/nghttp2_session.c
+++ b/lib/nghttp2_session.c
@@ -39,6 +39,7 @@
#include "nghttp2_extpri.h"
#include "nghttp2_time.h"
#include "nghttp2_debug.h"
+#include "nghttp2_submit.h"
/*
* Returns non-zero if the number of outgoing opened streams is larger
@@ -2103,10 +2104,9 @@ static int session_predicate_priority_update_send(nghttp2_session *session,
/* Take into account settings max frame size and both connection-level
flow control here */
-static ssize_t
-nghttp2_session_enforce_flow_control_limits(nghttp2_session *session,
- nghttp2_stream *stream,
- ssize_t requested_window_size) {
+static nghttp2_ssize nghttp2_session_enforce_flow_control_limits(
+ nghttp2_session *session, nghttp2_stream *stream,
+ nghttp2_ssize requested_window_size) {
DEBUGF("send: remote windowsize connection=%d, remote maxframsize=%u, "
"stream(id %d)=%d\n",
session->remote_window_size, session->remote_settings.max_frame_size,
@@ -2126,12 +2126,12 @@ nghttp2_session_enforce_flow_control_limits(nghttp2_session *session,
*/
static size_t nghttp2_session_next_data_read(nghttp2_session *session,
nghttp2_stream *stream) {
- ssize_t window_size;
+ nghttp2_ssize window_size;
window_size = nghttp2_session_enforce_flow_control_limits(
session, stream, NGHTTP2_DATA_PAYLOADLEN);
- DEBUGF("send: available window=%zd\n", window_size);
+ DEBUGF("send: available window=%td\n", window_size);
return window_size > 0 ? (size_t)window_size : 0;
}
@@ -2186,29 +2186,33 @@ static int nghttp2_session_predicate_data_send(nghttp2_session *session,
return NGHTTP2_ERR_INVALID_STREAM_STATE;
}
-static ssize_t session_call_select_padding(nghttp2_session *session,
- const nghttp2_frame *frame,
- size_t max_payloadlen) {
- ssize_t rv;
+static nghttp2_ssize session_call_select_padding(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ size_t max_payloadlen) {
+ nghttp2_ssize rv;
+ size_t max_paddedlen;
- if (frame->hd.length >= max_payloadlen) {
- return (ssize_t)frame->hd.length;
+ if (frame->hd.length >= max_payloadlen ||
+ (!session->callbacks.select_padding_callback2 &&
+ !session->callbacks.select_padding_callback)) {
+ return (nghttp2_ssize)frame->hd.length;
}
- if (session->callbacks.select_padding_callback) {
- size_t max_paddedlen;
-
- max_paddedlen =
- nghttp2_min(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen);
+ max_paddedlen =
+ nghttp2_min(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen);
- rv = session->callbacks.select_padding_callback(
+ if (session->callbacks.select_padding_callback2) {
+ rv = session->callbacks.select_padding_callback2(
session, frame, max_paddedlen, session->user_data);
- if (rv < (ssize_t)frame->hd.length || rv > (ssize_t)max_paddedlen) {
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- }
- return rv;
+ } else {
+ rv = (nghttp2_ssize)session->callbacks.select_padding_callback(
+ session, frame, max_paddedlen, session->user_data);
+ }
+ if (rv < (nghttp2_ssize)frame->hd.length ||
+ rv > (nghttp2_ssize)max_paddedlen) {
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- return (ssize_t)frame->hd.length;
+ return rv;
}
/* Add padding to HEADERS or PUSH_PROMISE. We use
@@ -2216,7 +2220,7 @@ static ssize_t session_call_select_padding(nghttp2_session *session,
frame->push_promise has also padlen in the same position. */
static int session_headers_add_pad(nghttp2_session *session,
nghttp2_frame *frame) {
- ssize_t padded_payloadlen;
+ nghttp2_ssize padded_payloadlen;
nghttp2_active_outbound_item *aob;
nghttp2_bufs *framebufs;
size_t padlen;
@@ -2237,7 +2241,7 @@ static int session_headers_add_pad(nghttp2_session *session,
padlen = (size_t)padded_payloadlen - frame->hd.length;
- DEBUGF("send: padding selected: payloadlen=%zd, padlen=%zu\n",
+ DEBUGF("send: padding selected: payloadlen=%td, padlen=%zu\n",
padded_payloadlen, padlen);
nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0);
@@ -2257,18 +2261,24 @@ static size_t session_estimate_headers_payload(nghttp2_session *session,
static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs,
nghttp2_frame *frame) {
- ssize_t rv;
+ nghttp2_ssize rv;
nghttp2_buf *buf;
size_t buflen;
size_t framelen;
- assert(session->callbacks.pack_extension_callback);
+ assert(session->callbacks.pack_extension_callback2 ||
+ session->callbacks.pack_extension_callback);
buf = &bufs->head->buf;
buflen = nghttp2_min(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN);
- rv = session->callbacks.pack_extension_callback(session, buf->last, buflen,
- frame, session->user_data);
+ if (session->callbacks.pack_extension_callback2) {
+ rv = session->callbacks.pack_extension_callback2(session, buf->last, buflen,
+ frame, session->user_data);
+ } else {
+ rv = (nghttp2_ssize)session->callbacks.pack_extension_callback(
+ session, buf->last, buflen, frame, session->user_data);
+ }
if (rv == NGHTTP2_ERR_CANCEL) {
return (int)rv;
}
@@ -2451,7 +2461,7 @@ static int session_prep_frame(nghttp2_session *session,
return rv;
}
- DEBUGF("send: before padding, HEADERS serialized in %zd bytes\n",
+ DEBUGF("send: before padding, HEADERS serialized in %zu bytes\n",
nghttp2_bufs_len(&session->aob.framebufs));
rv = session_headers_add_pad(session, frame);
@@ -2460,7 +2470,7 @@ static int session_prep_frame(nghttp2_session *session,
return rv;
}
- DEBUGF("send: HEADERS finally serialized in %zd bytes\n",
+ DEBUGF("send: HEADERS finally serialized in %zu bytes\n",
nghttp2_bufs_len(&session->aob.framebufs));
if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
@@ -2877,7 +2887,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
/* Call on_frame_send_callback after
nghttp2_stream_detach_item(), so that application can issue
- nghttp2_submit_data() in the callback. */
+ nghttp2_submit_data2() in the callback. */
if (session->callbacks.on_frame_send_callback) {
rv = session_call_on_frame_send(session, frame);
if (nghttp2_is_fatal(rv)) {
@@ -2949,15 +2959,17 @@ static int session_after_frame_sent1(nghttp2_session *session) {
}
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data = &item->aux_data.headers;
- if (aux_data->data_prd.read_callback) {
- /* nghttp2_submit_data() makes a copy of aux_data->data_prd */
- rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
- frame->hd.stream_id, &aux_data->data_prd);
+ if (aux_data->dpw.data_prd.read_callback) {
+ /* nghttp2_submit_data_shared() makes a copy of
+ aux_data->dpw */
+ rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM,
+ frame->hd.stream_id, &aux_data->dpw);
if (nghttp2_is_fatal(rv)) {
return rv;
}
- /* TODO nghttp2_submit_data() may fail if stream has already
- DATA frame item. We might have to handle it here. */
+ /* TODO nghttp2_submit_data_shared() may fail if stream has
+ already DATA frame item. We might have to handle it
+ here. */
}
return 0;
}
@@ -2978,14 +2990,15 @@ static int session_after_frame_sent1(nghttp2_session *session) {
}
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data = &item->aux_data.headers;
- if (aux_data->data_prd.read_callback) {
- rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
- frame->hd.stream_id, &aux_data->data_prd);
+ if (aux_data->dpw.data_prd.read_callback) {
+ rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM,
+ frame->hd.stream_id, &aux_data->dpw);
if (nghttp2_is_fatal(rv)) {
return rv;
}
- /* TODO nghttp2_submit_data() may fail if stream has already
- DATA frame item. We might have to handle it here. */
+ /* TODO nghttp2_submit_data_shared() may fail if stream has
+ already DATA frame item. We might have to handle it
+ here. */
}
return 0;
default:
@@ -3144,7 +3157,7 @@ static void session_after_frame_sent2(nghttp2_session *session) {
aux_data = &item->aux_data.data;
/* On EOF, we have already detached data. Please note that
- application may issue nghttp2_submit_data() in
+ application may issue nghttp2_submit_data2() in
on_frame_send_callback (call from session_after_frame_sent1),
which attach data to stream. We don't want to detach it. */
if (aux_data->eof) {
@@ -3191,7 +3204,7 @@ static int session_call_send_data(nghttp2_session *session,
aux_data = &item->aux_data.data;
rv = session->callbacks.send_data_callback(session, frame, buf->pos, length,
- &aux_data->data_prd.source,
+ &aux_data->dpw.data_prd.source,
session->user_data);
switch (rv) {
@@ -3205,9 +3218,9 @@ static int session_call_send_data(nghttp2_session *session,
}
}
-static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
- const uint8_t **data_ptr,
- int fast_cb) {
+static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session,
+ const uint8_t **data_ptr,
+ int fast_cb) {
int rv;
nghttp2_active_outbound_item *aob;
nghttp2_bufs *framebufs;
@@ -3385,7 +3398,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
}
}
- DEBUGF("send: start transmitting frame type=%u, length=%zd\n",
+ DEBUGF("send: start transmitting frame type=%u, length=%td\n",
framebufs->cur->buf.pos[3],
framebufs->cur->buf.last - framebufs->cur->buf.pos);
@@ -3425,7 +3438,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
everything, we will adjust it. */
buf->pos += datalen;
- return (ssize_t)datalen;
+ return (nghttp2_ssize)datalen;
}
case NGHTTP2_OB_SEND_NO_COPY: {
nghttp2_stream *stream;
@@ -3502,7 +3515,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
buf->pos += datalen;
- return (ssize_t)datalen;
+ return (nghttp2_ssize)datalen;
}
}
}
@@ -3510,8 +3523,13 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
ssize_t nghttp2_session_mem_send(nghttp2_session *session,
const uint8_t **data_ptr) {
+ return (ssize_t)nghttp2_session_mem_send2(session, data_ptr);
+}
+
+nghttp2_ssize nghttp2_session_mem_send2(nghttp2_session *session,
+ const uint8_t **data_ptr) {
int rv;
- ssize_t len;
+ nghttp2_ssize len;
*data_ptr = NULL;
@@ -3528,7 +3546,7 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session,
rv = session_after_frame_sent1(session);
if (rv < 0) {
assert(nghttp2_is_fatal(rv));
- return (ssize_t)rv;
+ return (nghttp2_ssize)rv;
}
}
@@ -3537,8 +3555,8 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session,
int nghttp2_session_send(nghttp2_session *session) {
const uint8_t *data = NULL;
- ssize_t datalen;
- ssize_t sentlen;
+ nghttp2_ssize datalen;
+ nghttp2_ssize sentlen;
nghttp2_bufs *framebufs;
framebufs = &session->aob.framebufs;
@@ -3548,8 +3566,13 @@ int nghttp2_session_send(nghttp2_session *session) {
if (datalen <= 0) {
return (int)datalen;
}
- sentlen = session->callbacks.send_callback(session, data, (size_t)datalen,
- 0, session->user_data);
+ if (session->callbacks.send_callback2) {
+ sentlen = session->callbacks.send_callback2(
+ session, data, (size_t)datalen, 0, session->user_data);
+ } else {
+ sentlen = (nghttp2_ssize)session->callbacks.send_callback(
+ session, data, (size_t)datalen, 0, session->user_data);
+ }
if (sentlen < 0) {
if (sentlen == NGHTTP2_ERR_WOULDBLOCK) {
/* Transmission canceled. Rewind the offset */
@@ -3564,11 +3587,17 @@ int nghttp2_session_send(nghttp2_session *session) {
}
}
-static ssize_t session_recv(nghttp2_session *session, uint8_t *buf,
- size_t len) {
- ssize_t rv;
- rv = session->callbacks.recv_callback(session, buf, len, 0,
- session->user_data);
+static nghttp2_ssize session_recv(nghttp2_session *session, uint8_t *buf,
+ size_t len) {
+ nghttp2_ssize rv;
+
+ if (session->callbacks.recv_callback2) {
+ rv = session->callbacks.recv_callback2(session, buf, len, 0,
+ session->user_data);
+ } else {
+ rv = (nghttp2_ssize)session->callbacks.recv_callback(session, buf, len, 0,
+ session->user_data);
+ }
if (rv > 0) {
if ((size_t)rv > len) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -3870,7 +3899,7 @@ static int session_inflate_handle_invalid_connection(nghttp2_session *session,
static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
size_t *readlen_ptr, uint8_t *in, size_t inlen,
int final, int call_header_cb) {
- ssize_t proclen;
+ nghttp2_ssize proclen;
int rv;
int inflate_flags;
nghttp2_hd_nv nv;
@@ -3923,7 +3952,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
inlen -= (size_t)proclen;
*readlen_ptr += (size_t)proclen;
- DEBUGF("recv: proclen=%zd\n", proclen);
+ DEBUGF("recv: proclen=%td\n", proclen);
if (call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) {
rv = 0;
@@ -5763,7 +5792,7 @@ static int inbound_frame_handle_pad(nghttp2_inbound_frame *iframe,
* Computes number of padding based on flags. This function returns
* the calculated length if it succeeds, or -1.
*/
-static ssize_t inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
+static nghttp2_ssize inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
size_t padlen;
/* 1 for Pad Length field */
@@ -5778,7 +5807,7 @@ static ssize_t inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
iframe->padlen = padlen;
- return (ssize_t)padlen;
+ return (nghttp2_ssize)padlen;
}
/*
@@ -5787,9 +5816,9 @@ static ssize_t inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
* |payloadleft| does not include |readlen|. If padding was started
* strictly before this data chunk, this function returns -1.
*/
-static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
- size_t payloadleft,
- size_t readlen) {
+static nghttp2_ssize
+inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
+ size_t payloadleft, size_t readlen) {
size_t trail_padlen =
nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen);
@@ -5799,19 +5828,24 @@ static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
if (readlen < padlen) {
return -1;
}
- return (ssize_t)(readlen - padlen);
+ return (nghttp2_ssize)(readlen - padlen);
}
- return (ssize_t)(readlen);
+ return (nghttp2_ssize)(readlen);
}
static const uint8_t static_in[] = {0};
ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
size_t inlen) {
+ return (ssize_t)nghttp2_session_mem_recv2(session, in, inlen);
+}
+
+nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
+ const uint8_t *in, size_t inlen) {
const uint8_t *first, *last;
nghttp2_inbound_frame *iframe = &session->iframe;
size_t readlen;
- ssize_t padlen;
+ nghttp2_ssize padlen;
int rv;
int busy = 0;
nghttp2_frame_hd cont_hd;
@@ -5841,7 +5875,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (!nghttp2_session_want_read(session)) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
for (;;) {
@@ -5871,7 +5905,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
in += readlen;
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS ||
@@ -5893,7 +5927,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
iframe->state = NGHTTP2_IB_READ_HEAD;
@@ -5908,7 +5942,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
in += readlen;
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
nghttp2_frame_unpack_frame_hd(&iframe->frame.hd, iframe->sbuf.pos);
@@ -5929,7 +5963,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
switch (iframe->frame.hd.type) {
@@ -5944,7 +5978,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
rv = session_on_data_received_fail_fast(session);
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
DEBUGF("recv: DATA not allowed stream_id=%d\n",
@@ -5966,7 +6000,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == 1) {
@@ -5993,7 +6027,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == 1) {
@@ -6036,7 +6070,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
busy = 1;
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -6137,7 +6171,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
@@ -6175,7 +6209,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == 1) {
@@ -6235,7 +6269,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
default:
DEBUGF("recv: extension frame\n");
@@ -6346,7 +6380,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (iframe->payloadleft < 4) {
@@ -6404,11 +6438,11 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
in += readlen;
iframe->payloadleft -= readlen;
- DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zd\n", readlen,
+ DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zu\n", readlen,
iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
switch (iframe->frame.hd.type) {
@@ -6424,7 +6458,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
iframe->frame.headers.padlen = (size_t)padlen;
@@ -6451,7 +6485,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
busy = 1;
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -6481,7 +6515,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
}
@@ -6495,7 +6529,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
@@ -6513,7 +6547,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
iframe->frame.push_promise.padlen = (size_t)padlen;
@@ -6539,7 +6573,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
busy = 1;
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -6568,7 +6602,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
@@ -6603,7 +6637,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
@@ -6661,7 +6695,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
case NGHTTP2_IB_READ_HEADER_BLOCK:
case NGHTTP2_IB_IGN_HEADER_BLOCK: {
- ssize_t data_readlen;
+ nghttp2_ssize data_readlen;
size_t trail_padlen;
int final;
#ifdef DEBUGBUILD
@@ -6705,14 +6739,14 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (rv == NGHTTP2_ERR_PAUSE) {
in += hd_proclen;
iframe->payloadleft -= hd_proclen;
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -6819,7 +6853,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
assert(iframe->state == NGHTTP2_IB_IGN_ALL);
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
case NGHTTP2_IB_READ_SETTINGS:
DEBUGF("recv: [IB_READ_SETTINGS]\n");
@@ -6849,7 +6883,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
@@ -6883,7 +6917,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
@@ -6903,7 +6937,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
in += readlen;
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
nghttp2_frame_unpack_frame_hd(&cont_hd, iframe->sbuf.pos);
@@ -6925,7 +6959,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
/* CONTINUATION won't bear NGHTTP2_PADDED flag */
@@ -6961,7 +6995,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
/* Pad Length field is subject to flow control */
@@ -6971,7 +7005,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
/* Pad Length field is consumed immediately */
@@ -6983,7 +7017,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
@@ -7006,7 +7040,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
iframe->frame.data.padlen = (size_t)padlen;
@@ -7033,7 +7067,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->payloadleft);
if (readlen > 0) {
- ssize_t data_readlen;
+ nghttp2_ssize data_readlen;
rv = nghttp2_session_update_recv_connection_window_size(session,
readlen);
@@ -7042,7 +7076,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
rv = nghttp2_session_update_recv_stream_window_size(
@@ -7061,7 +7095,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
data_readlen = 0;
}
- padlen = (ssize_t)readlen - data_readlen;
+ padlen = (nghttp2_ssize)readlen - data_readlen;
if (padlen > 0) {
/* Padding is considered as "consumed" immediately */
@@ -7073,11 +7107,11 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
}
- DEBUGF("recv: data_readlen=%zd\n", data_readlen);
+ DEBUGF("recv: data_readlen=%td\n", data_readlen);
if (data_readlen > 0) {
if (session_enforce_http_messaging(session)) {
@@ -7092,7 +7126,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_DATA) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
}
@@ -7111,7 +7145,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
in - readlen, (size_t)data_readlen, session->user_data);
if (rv == NGHTTP2_ERR_PAUSE) {
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
if (nghttp2_is_fatal(rv)) {
@@ -7153,7 +7187,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
@@ -7166,7 +7200,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
}
}
@@ -7179,7 +7213,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
case NGHTTP2_IB_IGN_ALL:
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
case NGHTTP2_IB_READ_EXTENSION_PAYLOAD:
DEBUGF("recv: [IB_READ_EXTENSION_PAYLOAD]\n");
@@ -7274,7 +7308,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (ssize_t)inlen;
+ return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
@@ -7291,16 +7325,17 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
assert(in == last);
- return (ssize_t)(in - first);
+ return (nghttp2_ssize)(in - first);
}
int nghttp2_session_recv(nghttp2_session *session) {
uint8_t buf[NGHTTP2_INBOUND_BUFFER_LENGTH];
while (1) {
- ssize_t readlen;
+ nghttp2_ssize readlen;
readlen = session_recv(session, buf, sizeof(buf));
if (readlen > 0) {
- ssize_t proclen = nghttp2_session_mem_recv(session, buf, (size_t)readlen);
+ nghttp2_ssize proclen =
+ nghttp2_session_mem_recv2(session, buf, (size_t)readlen);
if (proclen < 0) {
return (int)proclen;
}
@@ -7642,8 +7677,8 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
nghttp2_stream *stream) {
int rv;
uint32_t data_flags;
- ssize_t payloadlen;
- ssize_t padded_payloadlen;
+ nghttp2_ssize payloadlen;
+ nghttp2_ssize padded_payloadlen;
nghttp2_buf *buf;
size_t max_payloadlen;
@@ -7651,19 +7686,26 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
buf = &bufs->cur->buf;
- if (session->callbacks.read_length_callback) {
-
- payloadlen = session->callbacks.read_length_callback(
- session, frame->hd.type, stream->stream_id, session->remote_window_size,
- stream->remote_window_size, session->remote_settings.max_frame_size,
- session->user_data);
+ if (session->callbacks.read_length_callback2 ||
+ session->callbacks.read_length_callback) {
+ if (session->callbacks.read_length_callback2) {
+ payloadlen = session->callbacks.read_length_callback2(
+ session, frame->hd.type, stream->stream_id,
+ session->remote_window_size, stream->remote_window_size,
+ session->remote_settings.max_frame_size, session->user_data);
+ } else {
+ payloadlen = (nghttp2_ssize)session->callbacks.read_length_callback(
+ session, frame->hd.type, stream->stream_id,
+ session->remote_window_size, stream->remote_window_size,
+ session->remote_settings.max_frame_size, session->user_data);
+ }
- DEBUGF("send: read_length_callback=%zd\n", payloadlen);
+ DEBUGF("send: read_length_callback=%td\n", payloadlen);
payloadlen = nghttp2_session_enforce_flow_control_limits(session, stream,
payloadlen);
- DEBUGF("send: read_length_callback after flow control=%zd\n", payloadlen);
+ DEBUGF("send: read_length_callback after flow control=%td\n", payloadlen);
if (payloadlen <= 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -7679,9 +7721,9 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
DEBUGF("send: realloc buffer failed rv=%d", rv);
/* If reallocation failed, old buffers are still in tact. So
use safe limit. */
- payloadlen = (ssize_t)datamax;
+ payloadlen = (nghttp2_ssize)datamax;
- DEBUGF("send: use safe limit payloadlen=%zd", payloadlen);
+ DEBUGF("send: use safe limit payloadlen=%td", payloadlen);
} else {
assert(&session->aob.framebufs == bufs);
@@ -7695,9 +7737,23 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
assert(nghttp2_buf_avail(buf) >= datamax);
data_flags = NGHTTP2_DATA_FLAG_NONE;
- payloadlen = aux_data->data_prd.read_callback(
- session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
- &aux_data->data_prd.source, session->user_data);
+ switch (aux_data->dpw.version) {
+ case NGHTTP2_DATA_PROVIDER_V1:
+ payloadlen = (nghttp2_ssize)aux_data->dpw.data_prd.v1.read_callback(
+ session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
+ &aux_data->dpw.data_prd.source, session->user_data);
+
+ break;
+ case NGHTTP2_DATA_PROVIDER_V2:
+ payloadlen = aux_data->dpw.data_prd.v2.read_callback(
+ session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
+ &aux_data->dpw.data_prd.source, session->user_data);
+
+ break;
+ default:
+ assert(0);
+ abort();
+ }
if (payloadlen == NGHTTP2_ERR_DEFERRED ||
payloadlen == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE ||
@@ -8275,7 +8331,7 @@ int nghttp2_session_change_stream_priority(
/* We don't intentionally call nghttp2_session_adjust_idle_stream()
so that idle stream created by this function, and existing ones
are kept for application. We will adjust number of idle stream
- in nghttp2_session_mem_send or nghttp2_session_mem_recv is
+ in nghttp2_session_mem_send2 or nghttp2_session_mem_recv2 is
called. */
return 0;
}
@@ -8313,7 +8369,7 @@ int nghttp2_session_create_idle_stream(nghttp2_session *session,
/* We don't intentionally call nghttp2_session_adjust_idle_stream()
so that idle stream created by this function, and existing ones
are kept for application. We will adjust number of idle stream
- in nghttp2_session_mem_send or nghttp2_session_mem_recv is
+ in nghttp2_session_mem_send2 or nghttp2_session_mem_recv2 is
called. */
return 0;
}
diff --git a/lib/nghttp2_submit.c b/lib/nghttp2_submit.c
index f5554eb..f947969 100644
--- a/lib/nghttp2_submit.c
+++ b/lib/nghttp2_submit.c
@@ -68,7 +68,7 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const nghttp2_priority_spec *pri_spec,
nghttp2_nv *nva_copy, size_t nvlen,
- const nghttp2_data_provider *data_prd,
+ const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) {
int rv;
uint8_t flags_copy;
@@ -87,8 +87,8 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
nghttp2_outbound_item_init(item);
- if (data_prd != NULL && data_prd->read_callback != NULL) {
- item->aux_data.headers.data_prd = *data_prd;
+ if (dpw != NULL && dpw->data_prd.read_callback != NULL) {
+ item->aux_data.headers.dpw = *dpw;
}
item->aux_data.headers.stream_user_data = stream_user_data;
@@ -143,7 +143,7 @@ static int32_t submit_headers_shared_nva(nghttp2_session *session,
uint8_t flags, int32_t stream_id,
const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen,
- const nghttp2_data_provider *data_prd,
+ const nghttp2_data_provider_wrap *dpw,
void *stream_user_data) {
int rv;
nghttp2_nv *nva_copy;
@@ -165,7 +165,7 @@ static int32_t submit_headers_shared_nva(nghttp2_session *session,
}
return submit_headers_shared(session, flags, stream_id, &copy_pri_spec,
- nva_copy, nvlen, data_prd, stream_user_data);
+ nva_copy, nvlen, dpw, stream_user_data);
}
int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
@@ -740,9 +740,9 @@ fail_item_malloc:
}
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
- const nghttp2_data_provider *data_prd) {
+ const nghttp2_data_provider_wrap *dpw) {
uint8_t flags = NGHTTP2_FLAG_NONE;
- if (data_prd == NULL || data_prd->read_callback == NULL) {
+ if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
flags |= NGHTTP2_FLAG_END_STREAM;
}
@@ -753,11 +753,11 @@ static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
return flags;
}
-int32_t nghttp2_submit_request(nghttp2_session *session,
- const nghttp2_priority_spec *pri_spec,
- const nghttp2_nv *nva, size_t nvlen,
- const nghttp2_data_provider *data_prd,
- void *stream_user_data) {
+static int32_t submit_request_shared(nghttp2_session *session,
+ const nghttp2_priority_spec *pri_spec,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider_wrap *dpw,
+ void *stream_user_data) {
uint8_t flags;
int rv;
@@ -775,23 +775,47 @@ int32_t nghttp2_submit_request(nghttp2_session *session,
pri_spec = NULL;
}
- flags = set_request_flags(pri_spec, data_prd);
+ flags = set_request_flags(pri_spec, dpw);
return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen,
- data_prd, stream_user_data);
+ dpw, stream_user_data);
+}
+
+int32_t nghttp2_submit_request(nghttp2_session *session,
+ const nghttp2_priority_spec *pri_spec,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider *data_prd,
+ void *stream_user_data) {
+ nghttp2_data_provider_wrap dpw;
+
+ return submit_request_shared(session, pri_spec, nva, nvlen,
+ nghttp2_data_provider_wrap_v1(&dpw, data_prd),
+ stream_user_data);
+}
+
+int32_t nghttp2_submit_request2(nghttp2_session *session,
+ const nghttp2_priority_spec *pri_spec,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider2 *data_prd,
+ void *stream_user_data) {
+ nghttp2_data_provider_wrap dpw;
+
+ return submit_request_shared(session, pri_spec, nva, nvlen,
+ nghttp2_data_provider_wrap_v2(&dpw, data_prd),
+ stream_user_data);
}
-static uint8_t set_response_flags(const nghttp2_data_provider *data_prd) {
+static uint8_t set_response_flags(const nghttp2_data_provider_wrap *dpw) {
uint8_t flags = NGHTTP2_FLAG_NONE;
- if (data_prd == NULL || data_prd->read_callback == NULL) {
+ if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
flags |= NGHTTP2_FLAG_END_STREAM;
}
return flags;
}
-int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
- const nghttp2_nv *nva, size_t nvlen,
- const nghttp2_data_provider *data_prd) {
+static int submit_response_shared(nghttp2_session *session, int32_t stream_id,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider_wrap *dpw) {
uint8_t flags;
if (stream_id <= 0) {
@@ -802,14 +826,32 @@ int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
return NGHTTP2_ERR_PROTO;
}
- flags = set_response_flags(data_prd);
+ flags = set_response_flags(dpw);
return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen,
- data_prd, NULL);
+ dpw, NULL);
}
-int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
- int32_t stream_id,
- const nghttp2_data_provider *data_prd) {
+int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider *data_prd) {
+ nghttp2_data_provider_wrap dpw;
+
+ return submit_response_shared(session, stream_id, nva, nvlen,
+ nghttp2_data_provider_wrap_v1(&dpw, data_prd));
+}
+
+int nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id,
+ const nghttp2_nv *nva, size_t nvlen,
+ const nghttp2_data_provider2 *data_prd) {
+ nghttp2_data_provider_wrap dpw;
+
+ return submit_response_shared(session, stream_id, nva, nvlen,
+ nghttp2_data_provider_wrap_v2(&dpw, data_prd));
+}
+
+int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_data_provider_wrap *dpw) {
int rv;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
@@ -832,7 +874,7 @@ int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
frame = &item->frame;
aux_data = &item->aux_data.data;
- aux_data->data_prd = *data_prd;
+ aux_data->dpw = *dpw;
aux_data->eof = 0;
aux_data->flags = nflags;
@@ -848,9 +890,37 @@ int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
return 0;
}
+int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_data_provider *data_prd) {
+ nghttp2_data_provider_wrap dpw;
+
+ assert(data_prd);
+
+ return nghttp2_submit_data_shared(
+ session, flags, stream_id, nghttp2_data_provider_wrap_v1(&dpw, data_prd));
+}
+
+int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_data_provider2 *data_prd) {
+ nghttp2_data_provider_wrap dpw;
+
+ assert(data_prd);
+
+ return nghttp2_submit_data_shared(
+ session, flags, stream_id, nghttp2_data_provider_wrap_v2(&dpw, data_prd));
+}
+
ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
const nghttp2_settings_entry *iv,
size_t niv) {
+ return (ssize_t)nghttp2_pack_settings_payload2(buf, buflen, iv, niv);
+}
+
+nghttp2_ssize nghttp2_pack_settings_payload2(uint8_t *buf, size_t buflen,
+ const nghttp2_settings_entry *iv,
+ size_t niv) {
if (!nghttp2_iv_check(iv, niv)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
@@ -859,7 +929,7 @@ ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
return NGHTTP2_ERR_INSUFF_BUFSIZE;
}
- return (ssize_t)nghttp2_frame_pack_settings_payload(buf, iv, niv);
+ return (nghttp2_ssize)nghttp2_frame_pack_settings_payload(buf, iv, niv);
}
int nghttp2_submit_extension(nghttp2_session *session, uint8_t type,
@@ -875,7 +945,8 @@ int nghttp2_submit_extension(nghttp2_session *session, uint8_t type,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
- if (!session->callbacks.pack_extension_callback) {
+ if (!session->callbacks.pack_extension_callback2 &&
+ !session->callbacks.pack_extension_callback) {
return NGHTTP2_ERR_INVALID_STATE;
}
diff --git a/lib/nghttp2_submit.h b/lib/nghttp2_submit.h
index 74d702f..96781d2 100644
--- a/lib/nghttp2_submit.h
+++ b/lib/nghttp2_submit.h
@@ -31,4 +31,10 @@
#include <nghttp2/nghttp2.h>
+typedef struct nghttp2_data_provider_wrap nghttp2_data_provider_wrap;
+
+int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const nghttp2_data_provider_wrap *dpw);
+
#endif /* NGHTTP2_SUBMIT_H */