Skip to content

Commit

Permalink
Move name/value validation functions to src
Browse files Browse the repository at this point in the history
nghttp2 library itself now accept octet header/value pairs,
completely not restricted by HTTP/1 header name/value rule.
The applications may impose restriction about them using
validators.
  • Loading branch information
tatsuhiro-t committed Jan 16, 2014
1 parent 0e4b3d4 commit 707a0b4
Show file tree
Hide file tree
Showing 21 changed files with 304 additions and 378 deletions.
2 changes: 0 additions & 2 deletions lib/includes/nghttp2/nghttp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -2143,8 +2143,6 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The |nva| includes empty name, or name which contains invalid
* characters.
* :enum:`NGHTTP2_ERR_STREAM_CLOSED`
* The stream is already closed or does not exist.
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
Expand Down
40 changes: 0 additions & 40 deletions lib/nghttp2_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,46 +550,6 @@ nghttp2_settings_entry* nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
return iv_copy;
}

int nghttp2_nv_array_check_nocase(const nghttp2_nv *nva, size_t nvlen)
{
size_t i;
for(i = 0; i < nvlen; ++i) {
if(!nghttp2_check_header_name_nocase(nva[i].name, nva[i].namelen)) {
return 0;
}
if(!nghttp2_check_header_value(nva[i].value, nva[i].valuelen)) {
return 0;
}
}
return 1;
}

int nghttp2_nv_array_check(const nghttp2_nv *nva, size_t nvlen)
{
size_t i;
for(i = 0; i < nvlen; ++i) {
if(!nghttp2_check_header_name(nva[i].name, nva[i].namelen)) {
return 0;
}
if(!nghttp2_check_header_value(nva[i].value, nva[i].valuelen)) {
return 0;
}
}
return 1;
}

int nghttp2_nv_check(const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen)
{
if(!nghttp2_check_header_name(name, namelen)) {
return 0;
}
if(!nghttp2_check_header_value(value, valuelen)) {
return 0;
}
return 1;
}

int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b)
{
return a->namelen == b->namelen && a->valuelen == b->valuelen &&
Expand Down
19 changes: 0 additions & 19 deletions lib/nghttp2_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,25 +558,6 @@ int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b);
*/
void nghttp2_nv_array_del(nghttp2_nv *nva);

/*
* Checks header name/value pair is well-formed. This function allows
* captital alphabet letters in name.
*
* This function returns nonzero if it succeeds, or 0.
*/
int nghttp2_nv_array_check_nocase(const nghttp2_nv *nva, size_t nvlen);

/*
* Checks header name/value pair is well-formed. This function does
* not allow captital alphabet letters in name.
*
* This function returns nonzero if it succeeds, or 0.
*/
int nghttp2_nv_array_check(const nghttp2_nv *nva, size_t nvlen);

int nghttp2_nv_check(const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen);

/*
* Checks that the |iv|, which includes |niv| entries, does not have
* invalid values. The |flow_control_opt| is current flow control
Expand Down
177 changes: 0 additions & 177 deletions lib/nghttp2_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,183 +154,6 @@ int nghttp2_should_send_window_update(int32_t local_window_size,
return recv_window_size >= local_window_size / 2;
}

static int VALID_HD_NAME_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
};

static int check_header_name(const uint8_t *name, size_t len, int nocase)
{
const uint8_t *last;
if(len == 0) {
return 0;
}
if(*name == ':') {
if(len == 1) {
return 0;
}
++name;
--len;
}
for(last = name + len; name != last; ++name) {
if(nocase && 'A' <= *name && *name <= 'Z') continue;
if(!VALID_HD_NAME_CHARS[*name]) {
return 0;
}
}
return 1;
}

int nghttp2_check_header_name(const uint8_t *name, size_t len)
{
return check_header_name(name, len, 0);
}

int nghttp2_check_header_name_nocase(const uint8_t *name, size_t len)
{
return check_header_name(name, len, 1);
}

static int VALID_HD_VALUE_CHARS[] = {
1 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
};

int nghttp2_check_header_value(const uint8_t* value, size_t len)
{
const uint8_t *last;
for(last = value + len; value != last; ++value) {
if(!VALID_HD_VALUE_CHARS[*value]) {
return 0;
}
}
return 1;
}

const char* nghttp2_strerror(int error_code)
{
switch(error_code) {
Expand Down
22 changes: 0 additions & 22 deletions lib/nghttp2_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,28 +118,6 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
int nghttp2_should_send_window_update(int32_t local_window_size,
int32_t recv_window_size);

/*
* Checks the header name in |name| with |len| bytes is well-formed.
*
* This function returns nonzero if it succeeds, or 0.
*/
int nghttp2_check_header_name(const uint8_t *name, size_t len);

/*
* Checks the header name in |name| with |len| bytes is
* well-formed. This function accepts also characters in [A-Z].
*
* This function returns nonzero if it succeeds, or 0.
*/
int nghttp2_check_header_name_nocase(const uint8_t *name, size_t len);

/*
* Checks the header value in |value| with |len| bytes is well-formed.
*
* This function returns nonzero if it succeeds, or 0.
*/
int nghttp2_check_header_value(const uint8_t* value, size_t len);

/*
* Deallocates memory space pointed by |ptr|. This function exists for
* the application to free the memory space allocated by the library
Expand Down
9 changes: 0 additions & 9 deletions lib/nghttp2_submit.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ static int nghttp2_submit_headers_shared_nva
{
ssize_t rv;
nghttp2_nv *nva_copy;
if(!nghttp2_nv_array_check_nocase(nva, nvlen)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen);
if(rv < 0) {
return rv;
Expand Down Expand Up @@ -195,12 +192,6 @@ int nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
uint8_t flags_copy;
int rv;

if(!nghttp2_nv_array_check_nocase(nva, nvlen)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if(nghttp2_session_get_stream(session, stream_id) == NULL) {
return NGHTTP2_ERR_STREAM_CLOSED;
}
frame = malloc(sizeof(nghttp2_frame));
if(frame == NULL) {
return NGHTTP2_ERR_NOMEM;
Expand Down
3 changes: 3 additions & 0 deletions src/HttpServer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ int on_header_callback(nghttp2_session *session,
if(!stream) {
return 0;
}
if(!http2::check_nv(name, namelen, value, valuelen)) {
return 0;
}
http2::split_add_header(stream->headers, name, namelen, value, valuelen);
return 0;
}
Expand Down
Loading

0 comments on commit 707a0b4

Please sign in to comment.