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

2018-06-13 Thread 吕海涛
hello?

发自我的 iPhone

> 在 2018年4月2日,08:28,Haitao Lv  写道:
> 
> Any body is here?
> 
>> On Mar 21, 2018, at 11:36, Haitao Lv  wrote:
>> 
>> 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_tn;
>> +u_char*p;
>> +ngx_buf_t *b;
>> +ngx_connection_t  *c;
>> +ngx_http_connection_t *hc;
>> +static const u_charpreface[] = "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 @@ 

[njs] http internalRedirect() method.

2018-06-13 Thread Dmitry Volyntsev
details:   http://hg.nginx.org/njs/rev/c939541c37bc
branches:  
changeset: 535:c939541c37bc
user:  Dmitry Volyntsev 
date:  Wed Jun 13 14:15:43 2018 +0300
description:
http internalRedirect() method.

Performs internal redirect to the specified uri.

req.internalRedirect():
uri - string. If uri starts with '@' it is considered as a
named location.

diffstat:

 nginx/ngx_http_js_module.c |  92 +-
 1 files changed, 82 insertions(+), 10 deletions(-)

diffs (158 lines):

diff -r bf3d32cc6716 -r c939541c37bc nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cWed Jun 13 14:11:58 2018 +0300
+++ b/nginx/ngx_http_js_module.cWed Jun 13 14:15:43 2018 +0300
@@ -31,6 +31,7 @@ typedef struct {
 ngx_uint_t   done;
 ngx_int_tstatus;
 njs_opaque_value_t   request_body;
+ngx_str_tredirect_uri;
 } ngx_http_js_ctx_t;
 
 
@@ -51,6 +52,8 @@ typedef struct {
 static ngx_int_t ngx_http_js_content_handler(ngx_http_request_t *r);
 static void ngx_http_js_content_event_handler(ngx_http_request_t *r);
 static void ngx_http_js_content_write_event_handler(ngx_http_request_t *r);
+static void ngx_http_js_content_finalize(ngx_http_request_t *r,
+ngx_http_js_ctx_t *ctx);
 static ngx_int_t ngx_http_js_variable(ngx_http_request_t *r,
 ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_js_init_vm(ngx_http_request_t *r);
@@ -89,6 +92,8 @@ static njs_ret_t ngx_http_js_ext_finish(
 nxt_uint_t nargs, njs_index_t unused);
 static njs_ret_t ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args,
 nxt_uint_t nargs, njs_index_t unused);
+static njs_ret_t ngx_http_js_ext_internal_redirect(njs_vm_t *vm,
+njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 
 static njs_ret_t ngx_http_js_ext_log(njs_vm_t *vm, njs_value_t *args,
 nxt_uint_t nargs, njs_index_t unused);
@@ -589,6 +594,18 @@ static njs_external_t  ngx_http_js_ext_r
   NULL,
   ngx_http_js_ext_return,
   0 },
+
+{ nxt_string("internalRedirect"),
+  NJS_EXTERN_METHOD,
+  NULL,
+  0,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  ngx_http_js_ext_internal_redirect,
+  0 },
 };
 
 
@@ -683,8 +700,9 @@ ngx_http_js_content_event_handler(ngx_ht
 }
 
 /*
- * status is expected to be overriden by finish() or return() methods,
- * otherwise the content handler is considered invalid.
+ * status is expected to be overriden by finish(), return() or
+ * internalRedirect() methods, otherwise the content handler is
+ * considered invalid.
  */
 
 ctx->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -704,10 +722,7 @@ ngx_http_js_content_event_handler(ngx_ht
 return;
 }
 
-ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-   "http js content rc: %i", ctx->status);
-
-ngx_http_finalize_request(r, ctx->status);
+ngx_http_js_content_finalize(r, ctx);
 }
 
 
@@ -725,10 +740,7 @@ ngx_http_js_content_write_event_handler(
 ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
 
 if (!njs_vm_pending(ctx->vm)) {
-ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-   "http js content rc: %i", ctx->status);
-
-ngx_http_finalize_request(r, ctx->status);
+ngx_http_js_content_finalize(r, ctx);
 return;
 }
 
@@ -764,6 +776,28 @@ ngx_http_js_content_write_event_handler(
 }
 
 
+static void
+ngx_http_js_content_finalize(ngx_http_request_t *r, ngx_http_js_ctx_t *ctx)
+{
+ngx_str_t  args;
+
+ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+   "http js content rc: %i", ctx->status);
+
+if (ctx->redirect_uri.len) {
+if (ctx->redirect_uri.data[0] == '@') {
+ngx_http_named_location(r, >redirect_uri);
+
+} else {
+ngx_http_split_args(r, >redirect_uri, );
+ngx_http_internal_redirect(r, >redirect_uri, );
+}
+}
+
+ngx_http_finalize_request(r, ctx->status);
+}
+
+
 static ngx_int_t
 ngx_http_js_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 uintptr_t data)
@@ -1391,6 +1425,44 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs
 
 
 static njs_ret_t
+ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *args,
+nxt_uint_t nargs, njs_index_t unused)
+{
+nxt_str_turi;
+ngx_http_js_ctx_t   *ctx;
+ngx_http_request_t  *r;
+
+if (nargs < 2) {
+njs_vm_error(vm, "too few arguments");
+return NJS_ERROR;
+}
+
+r = njs_value_data(njs_argument(args, 0));
+
+ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
+
+if (njs_vm_value_to_ext_string(vm, , njs_argument(args, 1), 0)
+== NJS_ERROR)
+{
+njs_vm_error(vm, "failed to convert uri arg");
+return NJS_ERROR;
+}
+
+if (uri.length == 0) {
+njs_vm_error(vm, "uri is empty");
+   

[nginx] Upstream: disable body cleanup with preserve_output (ticket #1565).

2018-06-13 Thread Maxim Dounin
details:   http://hg.nginx.org/nginx/rev/a10e5fe44762
branches:  
changeset: 7297:a10e5fe44762
user:  Maxim Dounin 
date:  Wed Jun 13 15:28:11 2018 +0300
description:
Upstream: disable body cleanup with preserve_output (ticket #1565).

With u->conf->preserve_output set the request body file might be used
after the response header is sent, so avoid cleaning it.  (Normally
this is not a problem as u->conf->preserve_output is only set with
r->request_body_no_buffering, but the request body might be already
written to a file in a different context.)

diffstat:

 src/http/ngx_http_upstream.c |  3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diffs (13 lines):

diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2901,7 +2901,8 @@ ngx_http_upstream_send_response(ngx_http
 }
 
 if (r->request_body && r->request_body->temp_file
-&& r == r->main && !r->preserve_body)
+&& r == r->main && !r->preserve_body
+&& !u->conf->preserve_output)
 {
 ngx_pool_run_cleanup_file(r->pool, 
r->request_body->temp_file->file.fd);
 r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Merged HTTP Response and Reply into Request.

2018-06-13 Thread Dmitry Volyntsev
details:   http://hg.nginx.org/njs/rev/bf3d32cc6716
branches:  
changeset: 534:bf3d32cc6716
user:  Dmitry Volyntsev 
date:  Wed Jun 13 14:11:58 2018 +0300
description:
Merged HTTP Response and Reply into Request.

Splitting HTTP functionality into 3 objects Request, Response and Reply
introduced a lot of confusion as to which method should belong to which object.

New members of Request:
- req.status (res.status)
- req.parent (reply.parent)
- req.requestBody (req.body)
- req.responseBody (reply.body)
- req.headersIn (req.headers)
- req.headersOut (res.headers)
- req.sendHeader() (res.sendHeader())
- req.send() (res.send())
- req.finish() (res.finish())
- req.return() (res.return())

Deprecated members of Request:
- req.body (use req.requestBody or req.responseBody)
- req.headers (use req.headersIn or req.headersOut)
- req.response

Response is remained in place for backward compatibility and will be removed in
the following releases.  Reply is replaced with Request in the req.subrequest()
callback.  The deprecated properties will be removed in the following releases.

diffstat:

 nginx/ngx_http_js_module.c |  245 +++-
 1 files changed, 151 insertions(+), 94 deletions(-)

diffs (389 lines):

diff -r bc3f64aab9f9 -r bf3d32cc6716 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cTue Jun 05 15:21:20 2018 +0300
+++ b/nginx/ngx_http_js_module.cWed Jun 13 14:11:58 2018 +0300
@@ -16,7 +16,6 @@ typedef struct {
 njs_vm_t*vm;
 const njs_extern_t  *req_proto;
 const njs_extern_t  *res_proto;
-const njs_extern_t  *rep_proto;
 } ngx_http_js_main_conf_t;
 
 
@@ -106,6 +105,10 @@ static njs_ret_t ngx_http_js_ext_get_rem
 njs_value_t *value, void *obj, uintptr_t data);
 static njs_ret_t ngx_http_js_ext_get_request_body(njs_vm_t *vm,
 njs_value_t *value, void *obj, uintptr_t data);
+static njs_ret_t ngx_http_js_ext_get_headers(njs_vm_t *vm, njs_value_t *value,
+void *obj, uintptr_t data);
+static njs_ret_t ngx_http_js_ext_foreach_headers(njs_vm_t *vm, void *obj,
+void *next); /*FIXME*/
 static njs_ret_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t 
*value,
 void *obj, uintptr_t data);
 static njs_ret_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj,
@@ -359,10 +362,34 @@ static njs_external_t  ngx_http_js_ext_r
   NULL,
   0 },
 
+{ nxt_string("parent"),
+  NJS_EXTERN_PROPERTY,
+  NULL,
+  0,
+  ngx_http_js_ext_get_parent,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  0 },
+
 { nxt_string("body"),
   NJS_EXTERN_PROPERTY,
   NULL,
   0,
+  ngx_http_js_ext_get_reply_body,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  0 },
+
+{ nxt_string("requestBody"),
+  NJS_EXTERN_PROPERTY,
+  NULL,
+  0,
   ngx_http_js_ext_get_request_body,
   NULL,
   NULL,
@@ -371,10 +398,34 @@ static njs_external_t  ngx_http_js_ext_r
   NULL,
   0 },
 
+{ nxt_string("responseBody"),
+  NJS_EXTERN_PROPERTY,
+  NULL,
+  0,
+  ngx_http_js_ext_get_reply_body,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  0 },
+
 { nxt_string("headers"),
   NJS_EXTERN_OBJECT,
   NULL,
   0,
+  ngx_http_js_ext_get_headers,
+  NULL,
+  NULL,
+  ngx_http_js_ext_foreach_headers,
+  ngx_http_js_ext_next_header,
+  NULL,
+  0 },
+
+{ nxt_string("headersIn"),
+  NJS_EXTERN_OBJECT,
+  NULL,
+  0,
   ngx_http_js_ext_get_header_in,
   NULL,
   NULL,
@@ -407,6 +458,30 @@ static njs_external_t  ngx_http_js_ext_r
   NULL,
   0 },
 
+{ nxt_string("status"),
+  NJS_EXTERN_PROPERTY,
+  NULL,
+  0,
+  ngx_http_js_ext_get_status,
+  ngx_http_js_ext_set_status,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  offsetof(ngx_http_request_t, headers_out.status) },
+
+{ nxt_string("headersOut"),
+  NJS_EXTERN_OBJECT,
+  NULL,
+  0,
+  ngx_http_js_ext_get_header_out,
+  ngx_http_js_ext_set_header_out,
+  NULL,
+  ngx_http_js_ext_foreach_header_out,
+  ngx_http_js_ext_next_header,
+  NULL,
+  0 },
+
 { nxt_string("response"),
   NJS_EXTERN_PROPERTY,
   NULL,
@@ -466,105 +541,53 @@ static njs_external_t  ngx_http_js_ext_r
   NULL,
   ngx_http_js_ext_error,
   0 },
-};
-
-
-static njs_external_t  ngx_http_js_ext_reply[] = {
-
-{ nxt_string("headers"),
-  NJS_EXTERN_OBJECT,
+
+{ nxt_string("sendHeader"),
+  NJS_EXTERN_METHOD,
   NULL,
   0,
-  ngx_http_js_ext_get_header_out,
-  NULL,
-  NULL,
-  ngx_http_js_ext_foreach_header_out,
-  ngx_http_js_ext_next_header,
-  NULL,
-  0 },
-
-{ nxt_string("status"),
-  NJS_EXTERN_PROPERTY,
-  NULL,
-  0,
-  ngx_http_js_ext_get_status,
   NULL,
   NULL,
   NULL,
   NULL,