Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP/2 with location.capture() internal requests #1195

Closed
wangchunpeng opened this issue Nov 22, 2017 · 14 comments
Closed

HTTP/2 with location.capture() internal requests #1195

wangchunpeng opened this issue Nov 22, 2017 · 14 comments

Comments

@wangchunpeng
Copy link

nginx configured supporting http2,
when ngx.location,capture() method is called in a http2 post request as an internal request , if the internal request is hit the local cache, the whole request is blocked, and no data is send back to the client.

location = /internal/api {
internal;
proxy_method GET;
proxy_cache api_key;
proxy_cache_key api_$args;
proxy_pass backends_ip;
}

@agentzh
Copy link
Member

agentzh commented Nov 22, 2017

@wangchunpeng It's known that ngx.location.capture* API does not work inside HTTP/2 requests. we'll disable the API explicitly and always throw out an error.

@wangchunpeng
Copy link
Author

@agentzh very appreciated !

@bjoe2k4
Copy link
Contributor

bjoe2k4 commented Feb 28, 2018

@agentzh sorry for bothering with this on this closed issue, but are you sure it does not work at all with HTTP/2? Maybe it is just related to proxy_pass enabled locations?
I am running a selfwritten rediscache based on lua-resty-redis in front of some php projects which also uses ngx.location.capture for initial fetches and fetching session tokens of the php app. It used to work just fine with nginx 1.11.3 and the recent nginx-lua-module at that time, and also works fantastic with 1.13.9 and the current master (with 3078ca6 reverted), compiled today.

@agentzh
Copy link
Member

agentzh commented Mar 1, 2018

@bjoe2k4 The thing is we have to make it fully working or just disable this altogether :) We don't have the time to dig this up, so if you would like to make this fully working, then please contribute a patch, which will be highly appreciated!

@Webifi
Copy link

Webifi commented Aug 29, 2019

Is there an alternative to "ngx.location.capture" with http/2? Commit 3078ca6 was a breaking change for me, and just like bjoe2k4, it was working perfectly.

Before it was documented that ngx.location.capture was known to have issues with http/2 in some certain cases, but was not documented as slated for removal. Its complete, and abrupt, removal for use with http/2, with no apparent work-around other than disabling http/2, is certainly problematic.

@Webifi
Copy link

Webifi commented Oct 30, 2019

@agentzh I'm sure I'm not alone in the case that ngx.locationcapture with lua was one of the most compelling reasons to use openresty.

If ngx.location.capture can't be fully fixed for HTTP/2, and there is no other viable alternative for loading and testing http requests while processing HTTP/2 requests, please give those of us that were comfortable working around the limitations some way to override the lock-out without having to resort to maintaining our own fork.

@942u3895hjf
Copy link

I agree with Webifi. We also heavily depend on location.capture and location.capture_multi. Since there was no way for us to upgrade and use HTTP/2, we were also forced to fork the project.

@parasyte
Copy link

FWIW, we are switching from ngx.location.capture* to lua-resty-http. It adds socket overhead and transforms HTTP/2 to HTTP/1.1, but we feel it's a fair tradeoff for something that works correctly right now.

@prospekt22
Copy link

@parasyte Did lua-resty-http worked also for internal requests?

@parasyte
Copy link

@prospekt22 No. We put it on its own listener (port) that is not publicly accessible.

@mrpre
Copy link

mrpre commented Mar 4, 2020

Does this problem exist now? I can't re-product it by using the newest Nginx with lua-nginx-module which I just removing the restrict code.

server {
    listen              7080 http2;

    set $ups myups;

    location  /start {
        postpone_output 0;
        access_by_lua_file /my.lua;
        add_header Nginx-Cache $ncache;
        proxy_pass http://www.example.com;
    }

    location  /auth {
        internal;
        proxy_cache_valid 200;
        proxy_method GET;
        proxy_cache my_cache;
        proxy_pass http://$ups;
    }
}

my.lua

ngx.req.set_header("Content-Type", "application/json;charset=utf8");
ngx.req.set_header("Accept", "application/json");

local res = ngx.location.capture('/auth', {
    method = ngx.HTTP_POST,
    body = body,
    args = {hello = 'world'}
});

I'm sure the subrequest hit the cache.

@Triple-Z
Copy link
Contributor

Triple-Z commented Aug 5, 2020

@mrpre The error code is still in master, which lua-nginx-module version do you use?

#if (NGX_HTTP_V2)
if (r->main->stream) {
return luaL_error(L, "http2 requests not supported yet");
}
#endif

@NeoVance
Copy link

NeoVance commented Oct 7, 2022

@mrpre @Triple-Z As far as I can tell most clients won't actually negotiate an HTTP/2 connection unless SSL is enabled, so even though you think you are turning on HTTP/2 the client will likely ask for HTTP1.1 if the connection is unencrypted. I am not even sure if NGINX actually enables HTTP/2 if SSL is not also enabled. HTTP/2 and TLS are very closely bound.

@outsinre
Copy link

outsinre commented Jan 4, 2023

@wangchunpeng It's known that ngx.location.capture* API does not work inside HTTP/2 requests. we'll disable the API explicitly and always throw out an error.

@agentzh Just wondering if is there any Doc that help explain why the ngx.location.capture* not fully compatible with HTTP/2?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests