@@ -333,45 +333,50 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
333333 const char * name , size_t nlen ,
334334 const char * value , size_t vlen )
335335{
336+ int error = 0 ;
336337 ap_assert (stream );
337338
338- if (!stream -> has_response ) {
339- if (name [0 ] == ':' ) {
340- if ((vlen ) > stream -> session -> s -> limit_req_line ) {
341- /* pseudo header: approximation of request line size check */
342- ap_log_cerror (APLOG_MARK , APLOG_TRACE1 , 0 , stream -> session -> c ,
343- "h2_stream(%ld-%d): pseudo header %s too long" ,
344- stream -> session -> id , stream -> id , name );
345- return h2_stream_set_error (stream ,
346- HTTP_REQUEST_URI_TOO_LARGE );
347- }
348- }
349- else if ((nlen + 2 + vlen ) > stream -> session -> s -> limit_req_fieldsize ) {
350- /* header too long */
339+ if (stream -> has_response ) {
340+ return APR_EINVAL ;
341+ }
342+ ++ stream -> request_headers_added ;
343+ if (name [0 ] == ':' ) {
344+ if ((vlen ) > stream -> session -> s -> limit_req_line ) {
345+ /* pseudo header: approximation of request line size check */
351346 ap_log_cerror (APLOG_MARK , APLOG_TRACE1 , 0 , stream -> session -> c ,
352- "h2_stream(%ld-%d): header %s too long" ,
347+ "h2_stream(%ld-%d): pseudo header %s too long" ,
353348 stream -> session -> id , stream -> id , name );
354- return h2_stream_set_error (stream ,
355- HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE );
349+ error = HTTP_REQUEST_URI_TOO_LARGE ;
356350 }
357-
358- if (name [0 ] != ':' ) {
359- ++ stream -> request_headers_added ;
360- if (stream -> request_headers_added
361- > stream -> session -> s -> limit_req_fields ) {
362- /* too many header lines */
363- ap_log_cerror (APLOG_MARK , APLOG_TRACE1 , 0 , stream -> session -> c ,
364- "h2_stream(%ld-%d): too many header lines" ,
365- stream -> session -> id , stream -> id );
366- return h2_stream_set_error (stream ,
367- HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE );
368- }
351+ }
352+ else if ((nlen + 2 + vlen ) > stream -> session -> s -> limit_req_fieldsize ) {
353+ /* header too long */
354+ ap_log_cerror (APLOG_MARK , APLOG_TRACE1 , 0 , stream -> session -> c ,
355+ "h2_stream(%ld-%d): header %s too long" ,
356+ stream -> session -> id , stream -> id , name );
357+ error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE ;
358+ }
359+
360+ if (stream -> request_headers_added
361+ > stream -> session -> s -> limit_req_fields + 4 ) {
362+ /* too many header lines, include 4 pseudo headers */
363+ if (stream -> request_headers_added
364+ > stream -> session -> s -> limit_req_fields + 4 + 100 ) {
365+ /* yeah, right */
366+ return APR_ECONNRESET ;
369367 }
368+ ap_log_cerror (APLOG_MARK , APLOG_TRACE1 , 0 , stream -> session -> c ,
369+ "h2_stream(%ld-%d): too many header lines" ,
370+ stream -> session -> id , stream -> id );
371+ error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE ;
370372 }
371373
372374 if (h2_stream_is_scheduled (stream )) {
373375 return add_trailer (stream , name , nlen , value , vlen );
374376 }
377+ else if (error ) {
378+ return h2_stream_set_error (stream , error );
379+ }
375380 else {
376381 if (!stream -> rtmp ) {
377382 stream -> rtmp = h2_req_create (stream -> id , stream -> pool ,
0 commit comments