diff --git a/lib/nghttp2_http.c b/lib/nghttp2_http.c index 115b4007..1f4cfa8b 100644 --- a/lib/nghttp2_http.c +++ b/lib/nghttp2_http.c @@ -382,15 +382,33 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv, int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, nghttp2_frame *frame, nghttp2_nv *nv, int trailer) { - if (!nghttp2_check_header_name(nv->name, nv->namelen) || - !nghttp2_check_header_value(nv->value, nv->valuelen)) { - /* We are strict for pseudo header field. One bad character - should lead to fail. OTOH, we should be a bit forgiving for - regular headers, since existing public internet has so much - illegal headers floating around and if we kill the stream - because of this, we may disrupt many web sites and/or - libraries. So we become conservative here, and just ignore - those illegal regular headers. */ + /* We are strict for pseudo header field. One bad character should + lead to fail. OTOH, we should be a bit forgiving for regular + headers, since existing public internet has so much illegal + headers floating around and if we kill the stream because of + this, we may disrupt many web sites and/or libraries. So we + become conservative here, and just ignore those illegal regular + headers. */ + if (!nghttp2_check_header_name(nv->name, nv->namelen)) { + size_t i; + if (nv->namelen > 0 && nv->name[0] == ':') { + return -1; + } + /* header field name must be lower-cased without exception */ + for (i = 0; i < nv->namelen; ++i) { + char c = nv->name[i]; + if ('A' <= c && c <= 'Z') { + return -1; + } + } + /* When ignoring regular headers, we set this flag so that we + still enforce header field ordering rule for pseudo header + fields. */ + stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED; + return 1; + } + + if (!nghttp2_check_header_value(nv->value, nv->valuelen)) { if (nv->namelen > 0 && nv->name[0] == ':') { return -1; }