Add promised_stream_user_data parameter to nghttp2_submit_push_promise
This is very useful to associate application specific data to promised stream. nghttp2_nv_array_copy now does not complain the header field is large.
This commit is contained in:
parent
86aa905c10
commit
d1c1deaf03
|
@ -2140,6 +2140,13 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
|
|||
* This function creates copies of all name/value pairs in |nva|. It
|
||||
* also lower-cases all names in |nva|.
|
||||
*
|
||||
* The |promised_stream_user_data| is a pointer to an arbitrary data
|
||||
* which is associated to the promised stream this frame will open and
|
||||
* make it in reserved state. It is available using
|
||||
* `nghttp2_session_get_stream_user_data()`. The application can
|
||||
* access it in :type:`nghttp2_before_frame_send_callback` and
|
||||
* :type:`nghttp2_on_frame_send_callback` of this frame.
|
||||
*
|
||||
* Since the library reorders the frames and tries to send the highest
|
||||
* prioritized one first and the HTTP/2.0 specification requires the
|
||||
* stream ID must be strictly increasing, the promised stream ID
|
||||
|
@ -2160,7 +2167,8 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
|
|||
*/
|
||||
int nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
|
||||
int32_t stream_id,
|
||||
const nghttp2_nv *nva, size_t nvlen);
|
||||
const nghttp2_nv *nva, size_t nvlen,
|
||||
void *promised_stream_user_data);
|
||||
|
||||
/**
|
||||
* @function
|
||||
|
|
|
@ -598,10 +598,6 @@ ssize_t nghttp2_nv_array_copy(nghttp2_nv **nva_ptr,
|
|||
size_t buflen = 0;
|
||||
nghttp2_nv *p;
|
||||
for(i = 0; i < nvlen; ++i) {
|
||||
if(nva[i].namelen > NGHTTP2_HD_MAX_NAME ||
|
||||
nva[i].valuelen > NGHTTP2_HD_MAX_VALUE) {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
buflen += nva[i].namelen + nva[i].valuelen;
|
||||
}
|
||||
/* If all name/value pair is 0-length, remove them */
|
||||
|
|
|
@ -481,9 +481,6 @@ void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen);
|
|||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The length of name or value in |nva| is strictly larger than
|
||||
* NGHTTP2_MAX_HD_VALUE_LENGTH.
|
||||
*/
|
||||
ssize_t nghttp2_nv_array_copy(nghttp2_nv **nva_ptr,
|
||||
const nghttp2_nv *nva, size_t nvlen);
|
||||
|
|
|
@ -1303,6 +1303,9 @@ static ssize_t nghttp2_session_prep_frame(nghttp2_session *session,
|
|||
}
|
||||
case NGHTTP2_PUSH_PROMISE: {
|
||||
nghttp2_stream *stream;
|
||||
nghttp2_headers_aux_data *aux_data;
|
||||
aux_data = (nghttp2_headers_aux_data*)item->aux_data;
|
||||
|
||||
rv = nghttp2_session_predicate_push_promise_send(session,
|
||||
frame->hd.stream_id);
|
||||
if(rv != 0) {
|
||||
|
@ -1325,12 +1328,13 @@ static ssize_t nghttp2_session_prep_frame(nghttp2_session *session,
|
|||
|
||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||
assert(stream);
|
||||
if(nghttp2_session_open_stream
|
||||
if(!nghttp2_session_open_stream
|
||||
(session, frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_STREAM_FLAG_PUSH,
|
||||
nghttp2_pushed_stream_pri(stream),
|
||||
NGHTTP2_STREAM_RESERVED,
|
||||
NULL) == NULL) {
|
||||
aux_data ?
|
||||
aux_data->stream_user_data : NULL)) {
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -181,28 +181,41 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
|
|||
|
||||
int nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
|
||||
int32_t stream_id,
|
||||
const nghttp2_nv *nva, size_t nvlen)
|
||||
const nghttp2_nv *nva, size_t nvlen,
|
||||
void *promised_stream_user_data)
|
||||
{
|
||||
nghttp2_frame *frame;
|
||||
nghttp2_nv *nva_copy;
|
||||
uint8_t flags_copy;
|
||||
nghttp2_headers_aux_data *aux_data = NULL;
|
||||
int rv;
|
||||
|
||||
frame = malloc(sizeof(nghttp2_frame));
|
||||
if(frame == NULL) {
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
if(promised_stream_user_data) {
|
||||
aux_data = malloc(sizeof(nghttp2_headers_aux_data));
|
||||
if(aux_data == NULL) {
|
||||
free(frame);
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
aux_data->data_prd = NULL;
|
||||
aux_data->stream_user_data = promised_stream_user_data;
|
||||
}
|
||||
rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen);
|
||||
if(rv < 0) {
|
||||
free(aux_data);
|
||||
free(frame);
|
||||
return rv;
|
||||
}
|
||||
flags_copy = NGHTTP2_FLAG_END_HEADERS;
|
||||
nghttp2_frame_push_promise_init(&frame->push_promise, flags_copy,
|
||||
stream_id, -1, nva_copy, nvlen);
|
||||
rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL);
|
||||
rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, aux_data);
|
||||
if(rv != 0) {
|
||||
nghttp2_frame_push_promise_free(&frame->push_promise);
|
||||
free(aux_data);
|
||||
free(frame);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -515,7 +515,8 @@ int Http2Handler::submit_push_promise(Request *req,
|
|||
http2::make_nv_ls(":authority", (*itr).second)
|
||||
};
|
||||
return nghttp2_submit_push_promise(session_, NGHTTP2_FLAG_END_HEADERS,
|
||||
req->stream_id, nva.data(), nva.size());
|
||||
req->stream_id, nva.data(), nva.size(),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void Http2Handler::add_stream(int32_t stream_id, std::unique_ptr<Request> req)
|
||||
|
|
|
@ -406,8 +406,9 @@ void test_nghttp2_nv_array_copy(void)
|
|||
|
||||
nghttp2_nv_array_del(nva);
|
||||
|
||||
/* Large header field is acceptable */
|
||||
rv = nghttp2_nv_array_copy(&nva, &bignv, 1);
|
||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == rv);
|
||||
CU_ASSERT(1 == rv);
|
||||
|
||||
free(bignv.value);
|
||||
}
|
||||
|
|
|
@ -2201,7 +2201,7 @@ void test_nghttp2_session_reprioritize_stream(void)
|
|||
|
||||
CU_ASSERT(0 == nghttp2_submit_push_promise(session,
|
||||
NGHTTP2_FLAG_END_HEADERS,
|
||||
3, NULL, 0));
|
||||
3, NULL, 0, NULL));
|
||||
ud.block_count = 0;
|
||||
CU_ASSERT(0 == nghttp2_session_send(session));
|
||||
/* Now PUSH_PROMISE is in aob */
|
||||
|
@ -2846,7 +2846,7 @@ void test_nghttp2_submit_push_promise(void)
|
|||
NGHTTP2_PRI_DEFAULT,
|
||||
NGHTTP2_STREAM_OPENING, NULL);
|
||||
CU_ASSERT(0 == nghttp2_submit_push_promise(session, NGHTTP2_FLAG_NONE, 1,
|
||||
nv, ARRLEN(nv)));
|
||||
nv, ARRLEN(nv), &ud));
|
||||
|
||||
ud.frame_send_cb_called = 0;
|
||||
ud.sent_frame_type = 0;
|
||||
|
@ -2855,6 +2855,7 @@ void test_nghttp2_submit_push_promise(void)
|
|||
CU_ASSERT(NGHTTP2_PUSH_PROMISE == ud.sent_frame_type);
|
||||
stream = nghttp2_session_get_stream(session, 2);
|
||||
CU_ASSERT(NGHTTP2_STREAM_RESERVED == stream->state);
|
||||
CU_ASSERT(&ud == nghttp2_session_get_stream_user_data(session, 2));
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
@ -3039,7 +3040,8 @@ void test_nghttp2_submit_invalid_nv(void)
|
|||
/* nghttp2_submit_push_promise */
|
||||
CU_ASSERT(0 ==
|
||||
nghttp2_submit_push_promise(session, NGHTTP2_FLAG_NONE, 2,
|
||||
empty_name_nv, ARRLEN(empty_name_nv)));
|
||||
empty_name_nv, ARRLEN(empty_name_nv),
|
||||
NULL));
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
@ -4128,7 +4130,7 @@ void test_nghttp2_session_pack_headers_with_padding(void)
|
|||
/* Check PUSH_PROMISE */
|
||||
CU_ASSERT(0 ==
|
||||
nghttp2_submit_push_promise(sv_session, NGHTTP2_FLAG_NONE, 1,
|
||||
nva, ARRLEN(nva)));
|
||||
nva, ARRLEN(nva), NULL));
|
||||
acc.length = 0;
|
||||
CU_ASSERT(0 == nghttp2_session_send(sv_session));
|
||||
|
||||
|
|
Loading…
Reference in New Issue