Add nghttp2_frame_add_pad to deal with adding pads
This commit is contained in:
parent
748f6e65bd
commit
2ff3d97b2e
|
@ -647,3 +647,42 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t nghttp2_frame_add_pad(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||
size_t *bufoff_ptr,
|
||||
uint8_t *flags_ptr,
|
||||
size_t payloadlen,
|
||||
size_t payloadmax,
|
||||
size_t align)
|
||||
{
|
||||
int rv;
|
||||
size_t nextlen = nghttp2_min((payloadlen + align - 1) / align * align,
|
||||
payloadmax);
|
||||
size_t padlen = nextlen - payloadlen;
|
||||
size_t trail_padlen = 0;
|
||||
size_t headoff = 2;
|
||||
size_t trail_padoff = headoff + NGHTTP2_FRAME_HEAD_LENGTH + payloadlen;
|
||||
if(padlen > 257) {
|
||||
headoff = 0;
|
||||
trail_padlen = padlen - 2;
|
||||
*flags_ptr |= NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW;
|
||||
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH] = trail_padlen >> 8;
|
||||
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH + 1] = trail_padlen & 0xff;
|
||||
} else if(padlen > 0) {
|
||||
headoff = 1;
|
||||
trail_padlen = padlen - 1;
|
||||
*flags_ptr |= NGHTTP2_FLAG_PAD_LOW;
|
||||
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH + 1] = trail_padlen;
|
||||
}
|
||||
|
||||
rv = nghttp2_reserve_buffer(buf_ptr, buflen_ptr,
|
||||
trail_padoff + trail_padlen);
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
memset((*buf_ptr) + trail_padoff, 0, trail_padlen);
|
||||
*bufoff_ptr = headoff;
|
||||
|
||||
return padlen;
|
||||
}
|
||||
|
|
|
@ -492,4 +492,35 @@ void nghttp2_nv_array_del(nghttp2_nv *nva);
|
|||
*/
|
||||
int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
/*
|
||||
* Add padding to the payload in the |*buf_ptr| of length
|
||||
* |*buflen_ptr|. The payload length is given in |payloadlen|. The
|
||||
* payload must start at offset NGHTTP2_FRAME_HEAD_LENGTH + 2 from
|
||||
* |*buf_ptr| to account for PAD_HIGH and PAD_LOW. The maximum payload
|
||||
* allowed is given in the |payloadmax|. The padding will not be made
|
||||
* more than |payloadmax|. The padding alignment is given in the
|
||||
* |align|.
|
||||
*
|
||||
* The |*flags_ptr| is updated to include NGHTTP2_FLAG_PAD_LOW and
|
||||
* NGHTTP2_FLAG_PAD_HIGH based on the padding length. The
|
||||
* |*bufoff_ptr| will have the offset starting the frame header in
|
||||
* |*buf_ptr|.
|
||||
*
|
||||
* The |*buf_ptr| and |*buflen_ptr| may be extended to include padding
|
||||
* bytes.
|
||||
*
|
||||
* This function returns the number of padding added to the payload
|
||||
* including PAD_HIGH and PAD_LOW if it succeeds, or one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
ssize_t nghttp2_frame_add_pad(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||
size_t *bufoff_ptr,
|
||||
uint8_t *flags_ptr,
|
||||
size_t payloadlen,
|
||||
size_t payloadmax,
|
||||
size_t align);
|
||||
|
||||
#endif /* NGHTTP2_FRAME_H */
|
||||
|
|
|
@ -4019,23 +4019,27 @@ ssize_t nghttp2_session_pack_data(nghttp2_session *session,
|
|||
for padding. Based on the padding length, we adjust the starting
|
||||
offset of frame data. The starting offset is assigned into
|
||||
|*bufoff_ptr|. */
|
||||
size_t headoff = 2;
|
||||
size_t dataoff = NGHTTP2_FRAME_HEAD_LENGTH + headoff;
|
||||
ssize_t framelen = dataoff + datamax;
|
||||
ssize_t r;
|
||||
size_t payloadoff = NGHTTP2_FRAME_HEAD_LENGTH + 2;
|
||||
ssize_t framelen = payloadoff + datamax;
|
||||
ssize_t rv;
|
||||
int eof_flags;
|
||||
uint8_t flags;
|
||||
r = nghttp2_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||
if(r != 0) {
|
||||
return r;
|
||||
ssize_t payloadlen;
|
||||
|
||||
rv = nghttp2_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
eof_flags = 0;
|
||||
r = frame->data_prd.read_callback
|
||||
(session, frame->hd.stream_id, (*buf_ptr) + dataoff, datamax,
|
||||
payloadlen = frame->data_prd.read_callback
|
||||
(session, frame->hd.stream_id, (*buf_ptr) + payloadoff, datamax,
|
||||
&eof_flags, &frame->data_prd.source, session->user_data);
|
||||
if(r == NGHTTP2_ERR_DEFERRED || r == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||
return r;
|
||||
} else if(r < 0 || datamax < (size_t)r) {
|
||||
|
||||
if(payloadlen == NGHTTP2_ERR_DEFERRED ||
|
||||
payloadlen == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||
return payloadlen;
|
||||
}
|
||||
if(payloadlen < 0 || datamax < (size_t)payloadlen) {
|
||||
/* This is the error code when callback is failed. */
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
@ -4046,37 +4050,27 @@ ssize_t nghttp2_session_pack_data(nghttp2_session *session,
|
|||
flags = 0;
|
||||
|
||||
if((session->opt_flags & NGHTTP2_OPTMASK_NO_DATA_PADDING) == 0 &&
|
||||
r > 0 && (size_t)r < datamax) {
|
||||
const size_t align = session->data_pad_alignment;
|
||||
size_t nextlen = nghttp2_min((r + align - 1) / align * align, datamax);
|
||||
size_t padlen = nextlen - r;
|
||||
size_t trail_padlen = 0;
|
||||
if(padlen > 257) {
|
||||
headoff = 0;
|
||||
trail_padlen = padlen - 2;
|
||||
flags |= NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW;
|
||||
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH] = trail_padlen >> 8;
|
||||
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH + 1] = trail_padlen & 0xff;
|
||||
} else if(padlen > 0) {
|
||||
headoff = 1;
|
||||
trail_padlen = padlen - 1;
|
||||
flags |= NGHTTP2_FLAG_PAD_LOW;
|
||||
(*buf_ptr)[NGHTTP2_FRAME_HEAD_LENGTH + 1] = trail_padlen;
|
||||
payloadlen > 0 && (size_t)payloadlen < datamax) {
|
||||
rv = nghttp2_frame_add_pad(buf_ptr, buflen_ptr, bufoff_ptr,
|
||||
&flags, payloadlen, datamax,
|
||||
session->data_pad_alignment);
|
||||
if(rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
frame->padlen = padlen;
|
||||
memset((*buf_ptr) + dataoff + r, 0, trail_padlen);
|
||||
frame->hd.length = nextlen;
|
||||
frame->padlen = rv;
|
||||
frame->hd.length = payloadlen + rv;
|
||||
} else {
|
||||
*bufoff_ptr = 0;
|
||||
frame->padlen = 0;
|
||||
frame->hd.length = r;
|
||||
frame->hd.length = payloadlen;
|
||||
}
|
||||
|
||||
/* Set PAD flags so that we can supply frame to the callback with
|
||||
the correct flags */
|
||||
frame->hd.flags |= flags;
|
||||
|
||||
memset(*buf_ptr + headoff, 0, NGHTTP2_FRAME_HEAD_LENGTH);
|
||||
nghttp2_put_uint16be(&(*buf_ptr)[headoff], frame->hd.length);
|
||||
memset(*buf_ptr + *bufoff_ptr, 0, NGHTTP2_FRAME_HEAD_LENGTH);
|
||||
nghttp2_put_uint16be(&(*buf_ptr)[*bufoff_ptr], frame->hd.length);
|
||||
|
||||
if(eof_flags) {
|
||||
frame->eof = 1;
|
||||
|
@ -4084,11 +4078,10 @@ ssize_t nghttp2_session_pack_data(nghttp2_session *session,
|
|||
flags |= NGHTTP2_FLAG_END_STREAM;
|
||||
}
|
||||
}
|
||||
(*buf_ptr)[headoff + 3] = flags;
|
||||
nghttp2_put_uint32be(&(*buf_ptr)[headoff + 4], frame->hd.stream_id);
|
||||
*bufoff_ptr = headoff;
|
||||
(*buf_ptr)[*bufoff_ptr + 3] = flags;
|
||||
nghttp2_put_uint32be(&(*buf_ptr)[*bufoff_ptr + 4], frame->hd.stream_id);
|
||||
|
||||
return frame->hd.length + NGHTTP2_FRAME_HEAD_LENGTH + headoff;
|
||||
return frame->hd.length + NGHTTP2_FRAME_HEAD_LENGTH + *bufoff_ptr;
|
||||
}
|
||||
|
||||
void* nghttp2_session_get_stream_user_data(nghttp2_session *session,
|
||||
|
|
Loading…
Reference in New Issue