Implement BLOCKED frame
This commit is contained in:
parent
2d4b92fc2b
commit
6bb410d603
|
@ -443,7 +443,11 @@ typedef enum {
|
||||||
/**
|
/**
|
||||||
* The ALTSVC frame.
|
* The ALTSVC frame.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_ALTSVC = 0x0a
|
NGHTTP2_ALTSVC = 0x0a,
|
||||||
|
/**
|
||||||
|
* The BLOCKED frame.
|
||||||
|
*/
|
||||||
|
NGHTTP2_BLOCKED = 0x0b
|
||||||
} nghttp2_frame_type;
|
} nghttp2_frame_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -982,6 +986,18 @@ typedef struct {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
} nghttp2_altsvc;
|
} nghttp2_altsvc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct
|
||||||
|
*
|
||||||
|
* The BLOCKED frame. It has following members:
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* The frame header.
|
||||||
|
*/
|
||||||
|
nghttp2_frame_hd hd;
|
||||||
|
} nghttp2_blocked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @union
|
* @union
|
||||||
*
|
*
|
||||||
|
@ -1034,6 +1050,10 @@ typedef union {
|
||||||
* The ALTSVC frame.
|
* The ALTSVC frame.
|
||||||
*/
|
*/
|
||||||
nghttp2_altsvc altsvc;
|
nghttp2_altsvc altsvc;
|
||||||
|
/**
|
||||||
|
* The BLOCKED frame.
|
||||||
|
*/
|
||||||
|
nghttp2_blocked blocked;
|
||||||
} nghttp2_frame;
|
} nghttp2_frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -216,6 +216,15 @@ void nghttp2_frame_altsvc_free(nghttp2_altsvc *frame)
|
||||||
free(frame->protocol_id);
|
free(frame->protocol_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nghttp2_frame_blocked_init(nghttp2_blocked *frame, int32_t stream_id)
|
||||||
|
{
|
||||||
|
nghttp2_frame_set_hd(&frame->hd, 0, NGHTTP2_BLOCKED, NGHTTP2_FLAG_NONE,
|
||||||
|
stream_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_frame_blocked_free(nghttp2_blocked *frame)
|
||||||
|
{}
|
||||||
|
|
||||||
void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata)
|
void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata)
|
||||||
{
|
{
|
||||||
frame->hd = pdata->hd;
|
frame->hd = pdata->hd;
|
||||||
|
@ -797,6 +806,20 @@ int nghttp2_frame_unpack_altsvc_payload(nghttp2_altsvc *frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_blocked *frame)
|
||||||
|
{
|
||||||
|
nghttp2_buf *buf;
|
||||||
|
|
||||||
|
assert(bufs->head == bufs->cur);
|
||||||
|
|
||||||
|
buf = &bufs->head->buf;
|
||||||
|
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||||
|
|
||||||
|
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
nghttp2_settings_entry* nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
nghttp2_settings_entry* nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
||||||
size_t niv)
|
size_t niv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -444,6 +444,16 @@ int nghttp2_frame_unpack_altsvc_payload(nghttp2_altsvc *frame,
|
||||||
uint8_t *var_gift_payload,
|
uint8_t *var_gift_payload,
|
||||||
size_t var_gift_payloadlen);
|
size_t var_gift_payloadlen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Packs BLOCKED frame |frame| in wire format and store it in |bufs|.
|
||||||
|
*
|
||||||
|
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||||
|
* before calling this function.
|
||||||
|
*
|
||||||
|
* This function always returns 0.
|
||||||
|
*/
|
||||||
|
int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_blocked *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
||||||
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
||||||
|
@ -534,6 +544,10 @@ void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id,
|
||||||
|
|
||||||
void nghttp2_frame_altsvc_free(nghttp2_altsvc *frame);
|
void nghttp2_frame_altsvc_free(nghttp2_altsvc *frame);
|
||||||
|
|
||||||
|
void nghttp2_frame_blocked_init(nghttp2_blocked *frame, int32_t stream_id);
|
||||||
|
|
||||||
|
void nghttp2_frame_blocked_free(nghttp2_blocked *frame);
|
||||||
|
|
||||||
void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata);
|
void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -196,6 +196,9 @@ static void nghttp2_inbound_frame_reset(nghttp2_session *session)
|
||||||
case NGHTTP2_ALTSVC:
|
case NGHTTP2_ALTSVC:
|
||||||
nghttp2_frame_altsvc_free(&iframe->frame.altsvc);
|
nghttp2_frame_altsvc_free(&iframe->frame.altsvc);
|
||||||
break;
|
break;
|
||||||
|
case NGHTTP2_BLOCKED:
|
||||||
|
nghttp2_frame_blocked_free(&iframe->frame.blocked);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
memset(&iframe->frame, 0, sizeof(nghttp2_frame));
|
memset(&iframe->frame, 0, sizeof(nghttp2_frame));
|
||||||
|
|
||||||
|
@ -628,6 +631,8 @@ int nghttp2_session_add_frame(nghttp2_session *session,
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_ALTSVC:
|
case NGHTTP2_ALTSVC:
|
||||||
break;
|
break;
|
||||||
|
case NGHTTP2_BLOCKED:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(frame->hd.type == NGHTTP2_HEADERS &&
|
if(frame->hd.type == NGHTTP2_HEADERS &&
|
||||||
|
@ -1292,6 +1297,41 @@ static int nghttp2_session_predicate_altsvc_send
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function checks BLOCKED with the stream ID |stream_id| can be
|
||||||
|
* sent at this time. If |stream_id| is 0, BLOCKED frame is always
|
||||||
|
* allowed to send.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_STREAM_CLOSED
|
||||||
|
* The stream is already closed or does not exist.
|
||||||
|
* NGHTTP2_ERR_STREAM_CLOSING
|
||||||
|
* RST_STREAM was queued for this stream.
|
||||||
|
*/
|
||||||
|
static int nghttp2_session_predicate_blocked_send
|
||||||
|
(nghttp2_session *session, int32_t stream_id)
|
||||||
|
{
|
||||||
|
nghttp2_stream *stream;
|
||||||
|
|
||||||
|
if(stream_id == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = nghttp2_session_get_stream(session, stream_id);
|
||||||
|
|
||||||
|
if(stream == NULL) {
|
||||||
|
return NGHTTP2_ERR_STREAM_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stream->state == NGHTTP2_STREAM_CLOSING) {
|
||||||
|
return NGHTTP2_ERR_STREAM_CLOSING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function checks SETTINGS can be sent at this time.
|
* This function checks SETTINGS can be sent at this time.
|
||||||
*
|
*
|
||||||
|
@ -1436,6 +1476,69 @@ static int session_headers_add_pad(nghttp2_session *session,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds BLOCKED frame to outbound queue. The |stream_id| could be 0,
|
||||||
|
* which means DATA is blocked by connection level flow control.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory
|
||||||
|
*/
|
||||||
|
static int session_add_blocked(nghttp2_session *session, int32_t stream_id)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
nghttp2_frame *frame;
|
||||||
|
|
||||||
|
frame = malloc(sizeof(nghttp2_frame));
|
||||||
|
|
||||||
|
if(frame == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp2_frame_blocked_init(&frame->blocked, stream_id);
|
||||||
|
|
||||||
|
rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL);
|
||||||
|
|
||||||
|
if(rv != 0) {
|
||||||
|
nghttp2_frame_blocked_free(&frame->blocked);
|
||||||
|
free(frame);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds BLOCKED frame(s) to outbound queue if they are allowed to
|
||||||
|
* send. We check BLOCKED frame can be sent for connection and stream
|
||||||
|
* individually.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory
|
||||||
|
*/
|
||||||
|
static int session_consider_blocked(nghttp2_session *session,
|
||||||
|
nghttp2_stream *stream)
|
||||||
|
{
|
||||||
|
if(session->blocked_sent == 0 && session->remote_window_size <= 0) {
|
||||||
|
session->blocked_sent = 1;
|
||||||
|
|
||||||
|
return session_add_blocked(session, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stream->blocked_sent == 0 && stream->remote_window_size <= 0) {
|
||||||
|
stream->blocked_sent = 1;
|
||||||
|
|
||||||
|
return session_add_blocked(session, stream->stream_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function serializes frame for transmission.
|
* This function serializes frame for transmission.
|
||||||
*
|
*
|
||||||
|
@ -1646,6 +1749,21 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
|
||||||
return framerv;
|
return framerv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NGHTTP2_BLOCKED:
|
||||||
|
rv = nghttp2_session_predicate_blocked_send(session,
|
||||||
|
frame->hd.stream_id);
|
||||||
|
if(rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
framerv = nghttp2_frame_pack_blocked(&session->aob.framebufs,
|
||||||
|
&frame->blocked);
|
||||||
|
|
||||||
|
if(framerv < 0) {
|
||||||
|
return framerv;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
|
@ -1682,6 +1800,12 @@ static int nghttp2_session_prep_frame(nghttp2_session *session,
|
||||||
next_readmax = nghttp2_session_next_data_read(session, stream);
|
next_readmax = nghttp2_session_next_data_read(session, stream);
|
||||||
|
|
||||||
if(next_readmax == 0) {
|
if(next_readmax == 0) {
|
||||||
|
rv = session_consider_blocked(session, stream);
|
||||||
|
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
rv = nghttp2_stream_defer_data(stream,
|
rv = nghttp2_stream_defer_data(stream,
|
||||||
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL,
|
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL,
|
||||||
&session->ob_pq);
|
&session->ob_pq);
|
||||||
|
@ -2020,6 +2144,9 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
|
||||||
case NGHTTP2_ALTSVC:
|
case NGHTTP2_ALTSVC:
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
break;
|
break;
|
||||||
|
case NGHTTP2_BLOCKED:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
nghttp2_active_outbound_item_reset(&session->aob);
|
nghttp2_active_outbound_item_reset(&session->aob);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2092,6 +2219,12 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
|
||||||
next_readmax = nghttp2_session_next_data_read(session, stream);
|
next_readmax = nghttp2_session_next_data_read(session, stream);
|
||||||
|
|
||||||
if(next_readmax == 0) {
|
if(next_readmax == 0) {
|
||||||
|
rv = session_consider_blocked(session, stream);
|
||||||
|
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
rv = nghttp2_stream_defer_data
|
rv = nghttp2_stream_defer_data
|
||||||
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_pq);
|
(stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_pq);
|
||||||
|
|
||||||
|
@ -3072,6 +3205,11 @@ static int nghttp2_update_remote_initial_window_size_func
|
||||||
return nghttp2_session_terminate_session(arg->session,
|
return nghttp2_session_terminate_session(arg->session,
|
||||||
NGHTTP2_FLOW_CONTROL_ERROR);
|
NGHTTP2_FLOW_CONTROL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stream->remote_window_size > 0) {
|
||||||
|
stream->blocked_sent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If window size gets positive, push deferred DATA frame to
|
/* If window size gets positive, push deferred DATA frame to
|
||||||
outbound queue. */
|
outbound queue. */
|
||||||
if(nghttp2_stream_check_deferred_by_flow_control(stream) &&
|
if(nghttp2_stream_check_deferred_by_flow_control(stream) &&
|
||||||
|
@ -3561,6 +3699,20 @@ static int session_process_altsvc_frame(nghttp2_session *session)
|
||||||
return nghttp2_session_on_altsvc_received(session, frame);
|
return nghttp2_session_on_altsvc_received(session, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nghttp2_session_on_blocked_received(nghttp2_session *session,
|
||||||
|
nghttp2_frame *frame)
|
||||||
|
{
|
||||||
|
return nghttp2_session_call_on_frame_received(session, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int session_process_blocked_frame(nghttp2_session *session)
|
||||||
|
{
|
||||||
|
nghttp2_inbound_frame *iframe = &session->iframe;
|
||||||
|
nghttp2_frame *frame = &iframe->frame;
|
||||||
|
|
||||||
|
return nghttp2_session_on_blocked_received(session, frame);
|
||||||
|
}
|
||||||
|
|
||||||
static int nghttp2_push_back_deferred_data_func(nghttp2_map_entry *entry,
|
static int nghttp2_push_back_deferred_data_func(nghttp2_map_entry *entry,
|
||||||
void *ptr)
|
void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -3609,6 +3761,8 @@ static int session_on_connection_window_update_received
|
||||||
/* To queue the DATA deferred by connection-level flow-control, we
|
/* To queue the DATA deferred by connection-level flow-control, we
|
||||||
have to check all streams. Bad. */
|
have to check all streams. Bad. */
|
||||||
if(session->remote_window_size > 0) {
|
if(session->remote_window_size > 0) {
|
||||||
|
session->blocked_sent = 0;
|
||||||
|
|
||||||
rv = nghttp2_session_push_back_deferred_data(session);
|
rv = nghttp2_session_push_back_deferred_data(session);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
/* FATAL */
|
/* FATAL */
|
||||||
|
@ -3642,6 +3796,11 @@ static int session_on_stream_window_update_received
|
||||||
NGHTTP2_FLOW_CONTROL_ERROR);
|
NGHTTP2_FLOW_CONTROL_ERROR);
|
||||||
}
|
}
|
||||||
stream->remote_window_size += frame->window_update.window_size_increment;
|
stream->remote_window_size += frame->window_update.window_size_increment;
|
||||||
|
|
||||||
|
if(stream->remote_window_size > 0) {
|
||||||
|
stream->blocked_sent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(stream->remote_window_size > 0 &&
|
if(stream->remote_window_size > 0 &&
|
||||||
session->remote_window_size > 0 &&
|
session->remote_window_size > 0 &&
|
||||||
nghttp2_stream_check_deferred_by_flow_control(stream)) {
|
nghttp2_stream_check_deferred_by_flow_control(stream)) {
|
||||||
|
@ -4364,6 +4523,27 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
|
||||||
iframe->state = NGHTTP2_IB_READ_NBYTE;
|
iframe->state = NGHTTP2_IB_READ_NBYTE;
|
||||||
inbound_frame_set_mark(iframe, 8);
|
inbound_frame_set_mark(iframe, 8);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NGHTTP2_BLOCKED:
|
||||||
|
DEBUGF(fprintf(stderr, "recv: BLOCKED\n"));
|
||||||
|
|
||||||
|
iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
|
||||||
|
|
||||||
|
if(iframe->payloadleft != 0) {
|
||||||
|
busy = 1;
|
||||||
|
|
||||||
|
iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = session_process_blocked_frame(session);
|
||||||
|
if(nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp2_inbound_frame_reset(session);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DEBUGF(fprintf(stderr, "recv: unknown frame\n"));
|
DEBUGF(fprintf(stderr, "recv: unknown frame\n"));
|
||||||
|
|
|
@ -199,6 +199,9 @@ struct nghttp2_session {
|
||||||
/* Flags indicating GOAWAY is sent and/or recieved. The flags are
|
/* Flags indicating GOAWAY is sent and/or recieved. The flags are
|
||||||
composed by bitwise OR-ing nghttp2_goaway_flag. */
|
composed by bitwise OR-ing nghttp2_goaway_flag. */
|
||||||
uint8_t goaway_flags;
|
uint8_t goaway_flags;
|
||||||
|
/* nonzero if blocked was sent and remote_window_size is still 0 or
|
||||||
|
negative */
|
||||||
|
uint8_t blocked_sent;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Struct used when updating initial window size of each active
|
/* Struct used when updating initial window size of each active
|
||||||
|
@ -573,6 +576,19 @@ int nghttp2_session_on_window_update_received(nghttp2_session *session,
|
||||||
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
||||||
nghttp2_frame *frame);
|
nghttp2_frame *frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when BLOCKED is received, assuming |frame| is properly
|
||||||
|
* initialized.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||||
|
* The callback function failed.
|
||||||
|
*/
|
||||||
|
int nghttp2_session_on_blocked_received(nghttp2_session *session,
|
||||||
|
nghttp2_frame *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when DATA is received, assuming |frame| is properly
|
* Called when DATA is received, assuming |frame| is properly
|
||||||
* initialized.
|
* initialized.
|
||||||
|
|
|
@ -49,6 +49,7 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
|
||||||
stream->local_window_size = local_initial_window_size;
|
stream->local_window_size = local_initial_window_size;
|
||||||
stream->recv_window_size = 0;
|
stream->recv_window_size = 0;
|
||||||
stream->recv_reduction = 0;
|
stream->recv_reduction = 0;
|
||||||
|
stream->blocked_sent = 0;
|
||||||
|
|
||||||
stream->dep_prev = NULL;
|
stream->dep_prev = NULL;
|
||||||
stream->dep_next = NULL;
|
stream->dep_next = NULL;
|
||||||
|
|
|
@ -173,6 +173,9 @@ struct nghttp2_stream {
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
/* Bitwise OR of zero or more nghttp2_shut_flag values */
|
/* Bitwise OR of zero or more nghttp2_shut_flag values */
|
||||||
uint8_t shut_flags;
|
uint8_t shut_flags;
|
||||||
|
/* nonzero if blocked was sent and remote_window_size is still 0 or
|
||||||
|
negative */
|
||||||
|
uint8_t blocked_sent;
|
||||||
};
|
};
|
||||||
|
|
||||||
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
|
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
|
||||||
|
|
|
@ -127,6 +127,8 @@ const char* strframetype(uint8_t type)
|
||||||
return "WINDOW_UPDATE";
|
return "WINDOW_UPDATE";
|
||||||
case NGHTTP2_ALTSVC:
|
case NGHTTP2_ALTSVC:
|
||||||
return "ALTSVC";
|
return "ALTSVC";
|
||||||
|
case NGHTTP2_BLOCKED:
|
||||||
|
return "BLOCKED";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue