Skip to content

Commit

Permalink
Separate extension frames from core frames
Browse files Browse the repository at this point in the history
ALTSVC and BLOCKED frames are now extension frames.  To add new
extension frame without modifying nghttp2_frame union, which causes so
name bump, we separated extension frames from core frames.
nghttp2_frame includes generic nghttp2_extension.  The payload member
of nghttp2_extension will point to the structure of extension frame
payload.  The frame types of extension frames are defined in
nghttp2_ext_frame_type.
  • Loading branch information
tatsuhiro-t committed Jun 9, 2014
1 parent 317b8ba commit dacc9b2
Show file tree
Hide file tree
Showing 11 changed files with 264 additions and 145 deletions.
72 changes: 41 additions & 31 deletions lib/includes/nghttp2/nghttp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,8 @@ typedef struct {

/**
* @enum
* The control frame types in HTTP/2.
*
* The frame types in HTTP/2 specification.
*/
typedef enum {
/**
Expand Down Expand Up @@ -438,16 +439,27 @@ typedef enum {
/**
* The CONTINUATION frame.
*/
NGHTTP2_CONTINUATION = 0x09,
NGHTTP2_CONTINUATION = 0x09
} nghttp2_frame_type;

/**
* @enum
*
* The extension frame types.
*
* TODO: The assigned frame types were carried from draft-12, and now
* actually TBD.
*/
typedef enum {
/**
* The ALTSVC frame.
* The ALTSVC extension frame.
*/
NGHTTP2_ALTSVC = 0x0a,
NGHTTP2_EXT_ALTSVC = 0x0a,
/**
* The BLOCKED frame.
* The BLOCKED extension frame.
*/
NGHTTP2_BLOCKED = 0x0b
} nghttp2_frame_type;
NGHTTP2_EXT_BLOCKED = 0x0b
} nghttp2_ext_frame_type;

/**
* @enum
Expand Down Expand Up @@ -938,16 +950,30 @@ typedef struct {
int32_t window_size_increment;
} nghttp2_window_update;

/**
* @struct
*
* The ALTSVC frame. It has following members:
*/
typedef struct {
/**
* The frame header.
*/
nghttp2_frame_hd hd;
/**
* The pointer to extension payload. The exact pointer type is
* determined by hd.type.
*
* If hd.type == :enum:`NGHTTP2_EXT_ALTSVC`, it is a pointer to
* :type:`nghttp2_ext_altsvc`.
*
* If hd.type == :enum:`NGHTTP2_EXT_BLOCKED`, it points to ``NULL``,
* since BLOCKED extension frame has no payload.
*/
void *payload;
} nghttp2_extension;

/**
* @struct
*
* The ALTSVC extension frame payload. It has following members:
*/
typedef struct {
/**
* Protocol ID
*/
Expand Down Expand Up @@ -980,19 +1006,7 @@ typedef struct {
* Port
*/
uint16_t port;
} nghttp2_altsvc;

/**
* @struct
*
* The BLOCKED frame. It has following members:
*/
typedef struct {
/**
* The frame header.
*/
nghttp2_frame_hd hd;
} nghttp2_blocked;
} nghttp2_ext_altsvc;

/**
* @union
Expand Down Expand Up @@ -1043,13 +1057,9 @@ typedef union {
*/
nghttp2_window_update window_update;
/**
* The ALTSVC frame.
*/
nghttp2_altsvc altsvc;
/**
* The BLOCKED frame.
* The extension frame.
*/
nghttp2_blocked blocked;
nghttp2_extension ext;
} nghttp2_frame;

/**
Expand Down
91 changes: 54 additions & 37 deletions lib/nghttp2_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
void nghttp2_frame_window_update_free(nghttp2_window_update *frame)
{}

void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id,
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
uint32_t max_age,
uint16_t port,
uint8_t *protocol_id,
Expand All @@ -195,34 +195,45 @@ void nghttp2_frame_altsvc_init(nghttp2_altsvc *frame, int32_t stream_id,
uint8_t *origin, size_t origin_len)
{
size_t payloadlen;
nghttp2_ext_altsvc *altsvc;

altsvc = frame->payload;

payloadlen = NGHTTP2_ALTSVC_MINLEN + protocol_id_len + host_len + origin_len;

frame_set_hd(&frame->hd, payloadlen, NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE,
frame_set_hd(&frame->hd, payloadlen, NGHTTP2_EXT_ALTSVC, NGHTTP2_FLAG_NONE,
stream_id);

frame->max_age = max_age;
frame->port = port;
frame->protocol_id = protocol_id;
frame->protocol_id_len = protocol_id_len;
frame->host = host;
frame->host_len = host_len;
frame->origin = origin;
frame->origin_len = origin_len;
altsvc->max_age = max_age;
altsvc->port = port;
altsvc->protocol_id = protocol_id;
altsvc->protocol_id_len = protocol_id_len;
altsvc->host = host;
altsvc->host_len = host_len;
altsvc->origin = origin;
altsvc->origin_len = origin_len;
}

void nghttp2_frame_altsvc_free(nghttp2_altsvc *frame)
void nghttp2_frame_altsvc_free(nghttp2_extension *frame)
{
free(frame->protocol_id);
nghttp2_ext_altsvc *altsvc;

altsvc = frame->payload;

if(altsvc == NULL) {
return;
}

free(altsvc->protocol_id);
}

void nghttp2_frame_blocked_init(nghttp2_blocked *frame, int32_t stream_id)
void nghttp2_frame_blocked_init(nghttp2_extension *frame, int32_t stream_id)
{
frame_set_hd(&frame->hd, 0, NGHTTP2_BLOCKED, NGHTTP2_FLAG_NONE,
frame_set_hd(&frame->hd, 0, NGHTTP2_EXT_BLOCKED, NGHTTP2_FLAG_NONE,
stream_id);
}

void nghttp2_frame_blocked_free(nghttp2_blocked *frame)
void nghttp2_frame_blocked_free(nghttp2_extension *frame)
{}

void nghttp2_frame_data_init(nghttp2_data *frame, nghttp2_private_data *pdata)
Expand Down Expand Up @@ -757,44 +768,47 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
}

int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_altsvc *frame)
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame)
{
int rv;
nghttp2_buf *buf;
nghttp2_ext_altsvc *altsvc;

assert(bufs->head == bufs->cur);

altsvc = frame->payload;

buf = &bufs->head->buf;

buf->pos -= NGHTTP2_FRAME_HDLEN;

nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);

nghttp2_put_uint32be(buf->last, frame->max_age);
nghttp2_put_uint32be(buf->last, altsvc->max_age);
buf->last += 4;

nghttp2_put_uint16be(buf->last, frame->port);
nghttp2_put_uint16be(buf->last, altsvc->port);
buf->last += 2;

buf->last[0] = frame->protocol_id_len;
buf->last[0] = altsvc->protocol_id_len;
++buf->last;

rv = nghttp2_bufs_add(bufs, frame->protocol_id, frame->protocol_id_len);
rv = nghttp2_bufs_add(bufs, altsvc->protocol_id, altsvc->protocol_id_len);
if(rv != 0) {
goto fail;
}

rv = nghttp2_bufs_addb(bufs, frame->host_len);
rv = nghttp2_bufs_addb(bufs, altsvc->host_len);
if(rv != 0) {
goto fail;
}

rv = nghttp2_bufs_add(bufs, frame->host, frame->host_len);
rv = nghttp2_bufs_add(bufs, altsvc->host, altsvc->host_len);
if(rv != 0) {
goto fail;
}

rv = nghttp2_bufs_add(bufs, frame->origin, frame->origin_len);
rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
if(rv != 0) {
goto fail;
}
Expand All @@ -810,50 +824,53 @@ int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_altsvc *frame)
return rv;
}

int nghttp2_frame_unpack_altsvc_payload(nghttp2_altsvc *frame,
int nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen,
uint8_t *var_gift_payload,
size_t var_gift_payloadlen)
{
nghttp2_buf buf;
nghttp2_ext_altsvc *altsvc;

altsvc = frame->payload;

frame->max_age = nghttp2_get_uint32(payload);
altsvc->max_age = nghttp2_get_uint32(payload);
payload += 4;

frame->port = nghttp2_get_uint16(payload);
altsvc->port = nghttp2_get_uint16(payload);
payload += 2;

frame->protocol_id_len = *payload;
altsvc->protocol_id_len = *payload;

nghttp2_buf_wrap_init(&buf, var_gift_payload, var_gift_payloadlen);
buf.last += var_gift_payloadlen;

/* 1 for Host-Len */
if(nghttp2_buf_len(&buf) < 1 + (ssize_t)frame->protocol_id_len) {
if(nghttp2_buf_len(&buf) < 1 + (ssize_t)altsvc->protocol_id_len) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}

frame->protocol_id = buf.pos;
buf.pos += frame->protocol_id_len;
altsvc->protocol_id = buf.pos;
buf.pos += altsvc->protocol_id_len;

frame->host_len = *buf.pos;
altsvc->host_len = *buf.pos;
++buf.pos;

if(nghttp2_buf_len(&buf) < (ssize_t)frame->host_len) {
if(nghttp2_buf_len(&buf) < (ssize_t)altsvc->host_len) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}

frame->host = buf.pos;
buf.pos += frame->host_len;
altsvc->host = buf.pos;
buf.pos += altsvc->host_len;

frame->origin = buf.pos;
frame->origin_len = nghttp2_buf_len(&buf);
altsvc->origin = buf.pos;
altsvc->origin_len = nghttp2_buf_len(&buf);

return 0;
}

int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_blocked *frame)
int nghttp2_frame_pack_blocked(nghttp2_bufs *bufs, nghttp2_extension *frame)
{
nghttp2_buf *buf;

Expand Down
Loading

0 comments on commit dacc9b2

Please sign in to comment.