Latest update - 7569
This commit is contained in:
+19
-24
@@ -421,6 +421,14 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
|
|||||||
|
|
||||||
} while (p != end);
|
} while (p != end);
|
||||||
|
|
||||||
|
h2c->total_bytes += n;
|
||||||
|
|
||||||
|
if (h2c->total_bytes / 8 > h2c->payload_bytes + 1048576) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, 0, "http2 flood detected");
|
||||||
|
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
} while (rev->ready);
|
} while (rev->ready);
|
||||||
|
|
||||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||||
@@ -965,6 +973,8 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||||||
stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
|
stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2c->payload_bytes += size;
|
||||||
|
|
||||||
if (r->request_body) {
|
if (r->request_body) {
|
||||||
rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed);
|
rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed);
|
||||||
|
|
||||||
@@ -2919,9 +2929,9 @@ ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length,
|
|||||||
"requested control frame is too large: %uz", length);
|
"requested control frame is too large: %uz", length);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
frame->length = length;
|
frame->length = length;
|
||||||
#endif
|
|
||||||
|
|
||||||
buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);
|
buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);
|
||||||
|
|
||||||
@@ -2948,6 +2958,8 @@ ngx_http_v2_frame_handler(ngx_http_v2_connection_t *h2c,
|
|||||||
frame->next = h2c->free_frames;
|
frame->next = h2c->free_frames;
|
||||||
h2c->free_frames = frame;
|
h2c->free_frames = frame;
|
||||||
|
|
||||||
|
h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3733,7 +3745,8 @@ ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
|
|||||||
static void
|
static void
|
||||||
ngx_http_v2_run_request(ngx_http_request_t *r)
|
ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ngx_connection_t *fc;
|
ngx_connection_t *fc;
|
||||||
|
ngx_http_v2_connection_t *h2c;
|
||||||
|
|
||||||
fc = r->connection;
|
fc = r->connection;
|
||||||
|
|
||||||
@@ -3765,6 +3778,10 @@ ngx_http_v2_run_request(ngx_http_request_t *r)
|
|||||||
r->headers_in.chunked = 1;
|
r->headers_in.chunked = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2c = r->stream->connection;
|
||||||
|
|
||||||
|
h2c->payload_bytes += r->request_length;
|
||||||
|
|
||||||
ngx_http_process_request(r);
|
ngx_http_process_request(r);
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
@@ -4294,33 +4311,11 @@ ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (!stream->in_closed) {
|
} else if (!stream->in_closed) {
|
||||||
#if 0
|
|
||||||
if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
|
if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
h2c->connection->error = 1;
|
h2c->connection->error = 1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* At the time of writing at least the latest versions of Chrome
|
|
||||||
* do not properly handle RST_STREAM with NO_ERROR status.
|
|
||||||
*
|
|
||||||
* See: https://bugs.chromium.org/p/chromium/issues/detail?id=603182
|
|
||||||
*
|
|
||||||
* As a workaround, the stream window is maximized before closing
|
|
||||||
* the stream. This allows a client to send up to 2 GB of data
|
|
||||||
* before getting blocked on flow control.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW
|
|
||||||
&& ngx_http_v2_send_window_update(h2c, node->id,
|
|
||||||
NGX_HTTP_V2_MAX_WINDOW
|
|
||||||
- stream->recv_window)
|
|
||||||
!= NGX_OK)
|
|
||||||
{
|
|
||||||
h2c->connection->error = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,9 @@ struct ngx_http_v2_connection_s {
|
|||||||
ngx_connection_t *connection;
|
ngx_connection_t *connection;
|
||||||
ngx_http_connection_t *http_connection;
|
ngx_http_connection_t *http_connection;
|
||||||
|
|
||||||
|
off_t total_bytes;
|
||||||
|
off_t payload_bytes;
|
||||||
|
|
||||||
ngx_uint_t processing;
|
ngx_uint_t processing;
|
||||||
ngx_uint_t frames;
|
ngx_uint_t frames;
|
||||||
ngx_uint_t idle;
|
ngx_uint_t idle;
|
||||||
|
|||||||
@@ -1853,6 +1853,8 @@ ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c,
|
|||||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
||||||
+ frame->length;
|
+ frame->length;
|
||||||
|
|
||||||
|
h2c->payload_bytes += frame->length;
|
||||||
|
|
||||||
ngx_http_v2_handle_frame(stream, frame);
|
ngx_http_v2_handle_frame(stream, frame);
|
||||||
|
|
||||||
ngx_http_v2_handle_stream(h2c, stream);
|
ngx_http_v2_handle_stream(h2c, stream);
|
||||||
@@ -1907,6 +1909,8 @@ ngx_http_v2_push_frame_handler(ngx_http_v2_connection_t *h2c,
|
|||||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
||||||
+ frame->length;
|
+ frame->length;
|
||||||
|
|
||||||
|
h2c->payload_bytes += frame->length;
|
||||||
|
|
||||||
ngx_http_v2_handle_frame(stream, frame);
|
ngx_http_v2_handle_frame(stream, frame);
|
||||||
|
|
||||||
ngx_http_v2_handle_stream(h2c, stream);
|
ngx_http_v2_handle_stream(h2c, stream);
|
||||||
@@ -2000,6 +2004,8 @@ done:
|
|||||||
|
|
||||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
|
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
|
||||||
|
|
||||||
|
h2c->payload_bytes += frame->length;
|
||||||
|
|
||||||
ngx_http_v2_handle_frame(stream, frame);
|
ngx_http_v2_handle_frame(stream, frame);
|
||||||
|
|
||||||
ngx_http_v2_handle_stream(h2c, stream);
|
ngx_http_v2_handle_stream(h2c, stream);
|
||||||
@@ -2012,12 +2018,17 @@ static ngx_inline void
|
|||||||
ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
|
ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
|
||||||
ngx_http_v2_out_frame_t *frame)
|
ngx_http_v2_out_frame_t *frame)
|
||||||
{
|
{
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
|
ngx_http_v2_connection_t *h2c;
|
||||||
|
|
||||||
r = stream->request;
|
r = stream->request;
|
||||||
|
|
||||||
r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
||||||
|
|
||||||
|
h2c = stream->connection;
|
||||||
|
|
||||||
|
h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
|
||||||
|
|
||||||
if (frame->fin) {
|
if (frame->fin) {
|
||||||
stream->out_closed = 1;
|
stream->out_closed = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user