Re: [PATCH] HTTP/2: make http2 server support http1
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.
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).
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.
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,