Opened 6 years ago
Last modified 5 years ago
#1743 new defect
Can't flush HTTP response header under TLS+HTTP2
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.14.x |
Keywords: | http2 | Cc: | |
uname -a: | centos7 CST 2017 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: | --with-stream --with-stream_ssl_module --with-http_ssl_module --with-http_v2_module |
Description
I want to send HTTP response header first before data is sent to client.
so I do like this:
/*Want to response Header and flush*/ ngx_http_idle_send_header(r); /*ngx_http_send_special doesn't work under HTTP2 but works under HTTP1*/ ngx_http_send_special(r, NGX_HTTP_FLUSH); ...... /*send Data later*/ ngx_http_output_filter(r, &out);
I had already set postpone_output to 0, and then I found HTTP response header was cached in ssl_buffer( in function ngx_ssl_send_chain ).
Under HTTP 1, function ngx_ssl_send_chain will set c->buffered which c was the real connection and then we call ngx_http_send_special->...->ngx_http_write_filter->ngx_ssl_send_chain, the header was sent on network. That was I want.
Under HTTP 2, function ngx_ssl_send_chain will set c->buffered which c was the real connection but when ngx_http_send_special->...->ngx_http_write_filter was called, ngx_ssl_send_chain wasn't called, because the c in ngx_http_write_filter was the H2 fake connection and c->buffered was not set
if (size == 0 && !(c->buffered & NGX_LOWLEVEL_BUFFERED) && !(last && c->need_last_buf)) { /*return here*/ if (last || flush || sync) { for (cl = r->out; cl; /* void */) { ln = cl; cl = cl->next; ngx_free_chain(r->pool, ln); } r->out = NULL; c->buffered &= ~NGX_HTTP_WRITE_BUFFERED; return NGX_OK; } ngx_log_error(NGX_LOG_ALERT, c->log, 0, "the http output chain is empty"); ngx_debug_point(); return NGX_ERROR; }
What should I do if I want to flush HTTP response header into network before data is sent ?
Update
What I want is that DATA frame is delayed one minute.