lua-resty-http icon indicating copy to clipboard operation
lua-resty-http copied to clipboard

httpc request twice,the second time return err of closed

Open Jhq9 opened this issue 2 years ago • 3 comments

` -- 引入必要的Lua库 local http = require("resty.http")

-- 创建全局的连接池 local httpc_pool = {} -- 获取参数变量url local url = ngx.var.arg_url

if not url then ngx.status = ngx.HTTP_BAD_REQUEST ngx.say("Missing 'url' parameter") ngx.exit(ngx.HTTP_BAD_REQUEST) end

-- 从连接池中获取连接 local httpc = httpc_pool[url] if not httpc then -- 连接池中没有可用的连接,创建一个新的连接 httpc = http.new() httpc_pool[url] = httpc end

-- 发起HTTP请求获取URL的响应 local res, err = httpc:request_uri(url, { method = "GET", ssl_verify = false, headers = { ["User-Agent"] = "Mozilla/5.0 (compatible; Lua-resty-http/0.15; +https://github.com/pintsized/lua-resty-http)", } })

if not res then ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR ngx.say("Failed to request meiya image URL: ", err) ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end

-- 获取响应的文本内容 local body = res.body

-- 请求并返回图片数据 res, err = httpc:request_uri("body ", { method = "GET", ssl_verify = false, headers = { ["User-Agent"] = "Mozilla/5.0 (compatible; Lua-resty-http/0.15; +https://github.com/pintsized/lua-resty-http)", } })

if not res then ngx.log(ngx.ERR, "request err.", err) ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR ngx.say('请求失败!',err) ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end

ngx.header["Content-Type"] = res.headers["Content-Type"] ngx.print(res.body) ngx.flush(true) `

this is my lua script; when i modify body as url constant, the second reuqest is all right. when body is a variable, second request's res is nil and err msg is closed.

can anyone figure out code's mistake?

Jhq9 avatar Jun 14 '23 08:06 Jhq9

Don't try to reuse your httpc. In particular when you use the request_uri interface, the entire request is completed and the connection closed or placed back on the pool. Hence closed.

I don't really understand what your httpc_pool is trying to achieve, but please be aware that httpc.new() is cheap, and connections are kept alive where possible by the underlying TCP connection pool. You don't need to cache your connections in Lua.

In short, always call http.new() before making a request.

pintsized avatar Jun 14 '23 11:06 pintsized

`ocal http = require("resty.http")

-- 获取参数变量url local url = ngx.var.arg_url

if not url then ngx.status = ngx.HTTP_BAD_REQUEST ngx.say("Missing 'url' parameter") ngx.exit(ngx.HTTP_BAD_REQUEST) end

local httpc = http.new()

-- 发起HTTP请求获取URL的响应 local res, err = httpc:request_uri(url, { method = "GET", ssl_verify = false, headers = { ["User-Agent"] = "Mozilla/5.0 (compatible; Lua-resty-http/0.15; +https://github.com/pintsized/lua-resty-http)", } })

if not res then ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR ngx.say("Failed to request meiya image URL: ", err) ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end

-- 获取响应的文本内容 local body = res.body

httpc = http.new() -- 请求并返回图片数据 res, err = httpc:request_uri("body ", { method = "GET", ssl_verify = false, headers = { ["User-Agent"] = "Mozilla/5.0 (compatible; Lua-resty-http/0.15; +https://github.com/pintsized/lua-resty-http)", } })

if not res then ngx.log(ngx.ERR, "request err.", err) ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR ngx.say('请求失败!',err) ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) end

ngx.header["Content-Type"] = res.headers["Content-Type"] ngx.print(res.body) ngx.flush(true)`

at first,i had tried your way. but i also get some err of closed. then i use chatgpt who advised me to use connection pool. however, i do not known why new http instance also get closed err. anyway, thanks for your answer.

Jhq9 avatar Jun 14 '23 11:06 Jhq9

Well turns out ChatGPT doesn't know what it's talking about. Who could have guessed? ;)

Why are you passing the string "body " as a URL? Do you not mean to use it as a variable? It wouldn't hurt to log the body to be sure you have a proper URL.

An undocumented tip: Call http.debug(true) at the top. It will print the actual request details to your logs so that you can see what it is attempting to send over the wire, which should help you figure out what you're doing wrong. Obviously don't do that in production.

pintsized avatar Jun 14 '23 11:06 pintsized