Welcome! Log In Create A New Profile

Advanced

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv
March 20, 2018 11:38PM
Thank you for reviewing.

And here is the patch that fix the breaking PROXY protocol functionality.

Sorry for disturbing.

diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 2db7a627..9f1b8544 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -17,6 +17,10 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
ngx_uint_t request_line);

+#if (NGX_HTTP_V2)
+static void ngx_http_wait_v2_preface_handler(ngx_event_t *rev);
+#endif
+
static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
@@ -325,7 +329,7 @@ ngx_http_init_connection(ngx_connection_t *c)

#if (NGX_HTTP_V2)
if (hc->addr_conf->http2) {
- rev->handler = ngx_http_v2_init;
+ rev->handler = ngx_http_wait_v2_preface_handler;
}
#endif

@@ -381,6 +385,131 @@ ngx_http_init_connection(ngx_connection_t *c)
}


+#if (NGX_HTTP_V2)
+static void
+ngx_http_wait_v2_preface_handler(ngx_event_t *rev)
+{
+ size_t size;
+ ssize_t n;
+ u_char *p;
+ ngx_buf_t *b;
+ ngx_connection_t *c;
+ ngx_http_connection_t *hc;
+ static const u_char preface[] = "PRI";
+
+ c = rev->data;
+ hc = c->data;
+
+ size = sizeof(preface) - 1;
+
+ if (hc->proxy_protocol) {
+ size += NGX_PROXY_PROTOCOL_MAX_HEADER;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http wait h2 preface handler");
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ if (c->close) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ b = c->buffer;
+
+ if (b == NULL) {
+ b = ngx_create_temp_buf(c->pool, size);
+ if (b == NULL) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ c->buffer = b;
+
+ } else if (b->start == NULL) {
+
+ b->start = ngx_palloc(c->pool, size);
+ if (b->start == NULL) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ b->pos = b->start;
+ b->last = b->start;
+ b->end = b->last + size;
+ }
+
+ n = c->recv(c, b->last, b->end - b->last);
+
+ if (n == NGX_AGAIN) {
+
+ if (!rev->timer_set) {
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
+ ngx_reusable_connection(c, 1);
+ }
+
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ /*
+ * We are trying to not hold c->buffer's memory for an idle connection.
+ */
+
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+ b->start = NULL;
+ }
+
+ return;
+ }
+
+ if (n == NGX_ERROR) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ if (n == 0) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client closed connection");
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ b->last += n;
+
+ if (hc->proxy_protocol) {
+ hc->proxy_protocol = 0;
+
+ p = ngx_proxy_protocol_read(c, b->pos, b->last);
+
+ if (p == NULL) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ b->pos = p;
+ }
+
+ if (b->last >= b->pos + sizeof(preface) - 1) {
+ /* b will be freed in ngx_http_v2_init/ngx_http_wait_request_handler */
+
+ if (ngx_strncmp(b->pos, preface, sizeof(preface) - 1) == 0) {
+ ngx_http_v2_init(rev);
+ } else {
+ rev->handler = ngx_http_wait_request_handler;
+ ngx_http_wait_request_handler(rev);
+ }
+ }
+}
+#endif
+
+
static void
ngx_http_wait_request_handler(ngx_event_t *rev)
{
@@ -393,6 +522,7 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
ngx_http_core_srv_conf_t *cscf;

c = rev->data;
+ n = NGX_AGAIN;

ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");

@@ -434,9 +564,27 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
b->pos = b->start;
b->last = b->start;
b->end = b->last + size;
+ } else {
+
+ p = ngx_palloc(c->pool, size);
+ if (p == NULL) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ n = b->last - b->pos;
+ ngx_memcpy(p, b->pos, n);
+ ngx_pfree(c->pool, b->start);
+
+ b->start = p;
+ b->pos = b->start;
+ b->last = b->start + n;
+ b->end = b->last + size;
}

- n = c->recv(c, b->last, size);
+ if (n == NGX_AGAIN) {
+ n = c->recv(c, b->last, size);
+ }

if (n == NGX_AGAIN) {

diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index 77ebb847..6724b662 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -229,6 +229,8 @@ static ngx_http_v2_parse_header_t ngx_http_v2_parse_headers[] = {
void
ngx_http_v2_init(ngx_event_t *rev)
{
+ size_t size;
+ ngx_buf_t *b;
ngx_connection_t *c;
ngx_pool_cleanup_t *cln;
ngx_http_connection_t *hc;
@@ -260,6 +262,23 @@ ngx_http_v2_init(ngx_event_t *rev)
return;
}

+ b = c->buffer;
+
+ if (b != NULL) {
+ size = b->last - b->pos;
+
+ if (size > h2mcf->recv_buffer_size) {
+ size = h2mcf->recv_buffer_size;
+ }
+
+ ngx_memcpy(h2mcf->recv_buffer, b->pos, size);
+ h2c->state.buffer_used = size;
+
+ ngx_pfree(c->pool, b->start);
+ ngx_pfree(c->pool, b);
+ c->buffer = NULL;
+ }
+
h2c->connection = c;
h2c->http_connection = hc;

@@ -379,13 +398,15 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
h2mcf = ngx_http_get_module_main_conf(h2c->http_connection->conf_ctx,
ngx_http_v2_module);

- available = h2mcf->recv_buffer_size - 2 * NGX_HTTP_V2_STATE_BUFFER_SIZE;
+ available = h2mcf->recv_buffer_size - h2c->state.buffer_used - 2 * NGX_HTTP_V2_STATE_BUFFER_SIZE;

do {
p = h2mcf->recv_buffer;

- ngx_memcpy(p, h2c->state.buffer, NGX_HTTP_V2_STATE_BUFFER_SIZE);
end = p + h2c->state.buffer_used;
+ if (h2c->state.buffer_used == 0) {
+ ngx_memcpy(p, h2c->state.buffer, NGX_HTTP_V2_STATE_BUFFER_SIZE);
+ }

n = c->recv(c, end, available);



> On Mar 21, 2018, at 00:02, Valentin V. Bartenev <vbart@nginx.com> wrote:
>
> On Thursday 08 March 2018 08:42:27 Haitao Lv wrote:
>> Sorry for disturbing. But I have to fix a buffer overflow bug.
>> Here is the latest patch.
>>
>> Sorry. But please make your comments. Thank you.
> [..]
>
> There's no way for this patch to be accepted as it breaks PROXY protocol
> functionality.
>
> wbr, Valentin V. Bartenev
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel



_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH] HTTP/2: make http2 server support http1

Haitao Lv 631 March 02, 2018 02:54AM

Re: [PATCH] HTTP/2: make http2 server support http1

Valentin V. Bartenev 275 March 02, 2018 12:32PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 276 March 03, 2018 10:02PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 144 March 04, 2018 12:52AM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 140 March 04, 2018 10:12PM

Re: [PATCH] HTTP/2: make http2 server support http1

ru@nginx.com 246 March 05, 2018 04:04AM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 147 March 05, 2018 09:38AM

Re: [PATCH] HTTP/2: make http2 server support http1

Valentin V. Bartenev 152 March 05, 2018 10:08AM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 212 March 05, 2018 10:54AM

Re: [PATCH] HTTP/2: make http2 server support http1

Maxim Dounin 334 March 05, 2018 02:16PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 188 March 05, 2018 09:22PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 136 March 07, 2018 07:30PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 103 March 07, 2018 07:44PM

Re: [PATCH] HTTP/2: make http2 server support http1

吕海涛 303 March 12, 2018 12:46PM

Re: [PATCH] HTTP/2: make http2 server support http1

Valentin V. Bartenev 185 March 12, 2018 01:12PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 181 March 18, 2018 01:00PM

Re: [PATCH] HTTP/2: make http2 server support http1

Valentin V. Bartenev 121 March 20, 2018 12:04PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 139 March 20, 2018 11:38PM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 125 April 01, 2018 08:36PM

Re: [PATCH] HTTP/2: make http2 server support http1

吕海涛 139 June 13, 2018 07:42PM

Re: [PATCH] HTTP/2: make http2 server support http1

Valentin V. Bartenev 243 March 04, 2018 08:02AM

Re: [PATCH] HTTP/2: make http2 server support http1

Haitao Lv 317 March 04, 2018 10:06PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 72
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready