Commit 693fba3b authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Add more docs about NGHTTP2_ERR_DATA_EXIST and its condition

This commit documents NGHTTP2_ERR_DATA_EXIST also occurs if HEADERS
has been already attached to stream too.  This commit also fixes
possible assertion error, and now nghttp2_submit_headers() and
nghttp2_submit_response() may return NGHTTP2_ERR_DATA_EXIST.  But we
recommend to use nghttp2_submit_request() and
nghttp2_submit_response(), and using them will avoid this error.
parent 8fcf5f60
......@@ -350,8 +350,10 @@ typedef enum {
*/
NGHTTP2_ERR_PUSH_DISABLED = -528,
/**
* DATA frame for a given stream has been already submitted and has
* not been fully processed yet.
* DATA or HEADERS frame for a given stream has been already
* submitted and has not been fully processed yet. Application
* should wait for the transmission of the previously submitted
* frame before submitting another.
*/
NGHTTP2_ERR_DATA_EXIST = -529,
/**
......@@ -3000,6 +3002,11 @@ NGHTTP2_EXTERN int32_t
* Out of memory.
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
* :enum:`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_response()` twice,
* this may happen.
*
* .. warning::
*
......@@ -3109,7 +3116,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.
* `nghttp2_submit_request()` is useful. Likewise, for HTTP response,
* prefer `nghttp2_submit_response()`.
*
* This function returns newly assigned stream ID if it succeeds and
* |stream_id| is -1. Otherwise, this function returns 0 if it
......@@ -3122,6 +3130,10 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* reached.
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
* :enum:`NGHTTP2_ERR_DATA_EXIST`
* DATA or HEADERS has been already submitted and not fully
* processed yet. This happens if stream denoted by |stream_id|
* is in reserved state.
*
* .. warning::
*
......@@ -3156,7 +3168,8 @@ NGHTTP2_EXTERN int32_t
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`NGHTTP2_ERR_DATA_EXIST`
* DATA has been already submitted and not fully processed yet.
* DATA or HEADERS has been already submitted and not fully
* processed yet.
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is 0.
* :enum:`NGHTTP2_ERR_STREAM_CLOSED`
......@@ -3164,14 +3177,19 @@ NGHTTP2_EXTERN int32_t
*
* .. note::
*
* Currently, only one data is allowed for a stream at a time.
* Submitting data more than once before first data is finished
* results in :enum:`NGHTTP2_ERR_DATA_EXIST` error code. The
* earliest callback which tells that previous data is done is
* :type:`nghttp2_on_frame_send_callback`. In side that callback,
* new data can be submitted using `nghttp2_submit_data()`. Of
* course, all data except for last one must not have
* :enum:`NGHTTP2_FLAG_END_STREAM` flag set in |flags|.
* 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_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_data()`. Of course, all data except for last one
* must not have :enum:`NGHTTP2_FLAG_END_STREAM` flag set in
* |flags|. This sounds a bit complicated, and we recommend to use
* `nghttp2_submit_request()` and `nghttp2_submit_response()` 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_data(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
......
......@@ -292,7 +292,7 @@ const char *nghttp2_strerror(int error_code) {
case NGHTTP2_ERR_PUSH_DISABLED:
return "Server push is disabled by peer";
case NGHTTP2_ERR_DATA_EXIST:
return "DATA frame already exists";
return "DATA or HEADERS frame has already been submitted for the stream";
case NGHTTP2_ERR_SESSION_CLOSING:
return "The current session is closing";
case NGHTTP2_ERR_HTTP_HEADER:
......
......@@ -713,6 +713,10 @@ int nghttp2_session_add_item(nghttp2_session *session,
if (stream && (stream->state == NGHTTP2_STREAM_RESERVED ||
item->aux_data.headers.attach_stream)) {
if (stream->item) {
return NGHTTP2_ERR_DATA_EXIST;
}
rv = nghttp2_stream_attach_item(stream, item, session);
if (rv != 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment