Skip to content

Commit 855fe18

Browse files
committed
add resty http client
1 parent 6dbfb5b commit 855fe18

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

lapis-dev-1.rockspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ build = {
9898
["lapis.nginx.context"] = "lapis/nginx/context.lua",
9999
["lapis.nginx.http"] = "lapis/nginx/http.lua",
100100
["lapis.nginx.postgres"] = "lapis/nginx/postgres.lua",
101+
["lapis.nginx.resty_http"] = "lapis/nginx/resty_http.lua",
101102
["lapis.request"] = "lapis/request.lua",
102103
["lapis.router"] = "lapis/router.lua",
103104
["lapis.server"] = "lapis/server.lua",

lapis/nginx/resty_http.lua

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
local lapis_config = require("lapis.config")
2+
local increment_perf
3+
increment_perf = require("lapis.nginx.context").increment_perf
4+
local request
5+
request = function(url, str_body)
6+
local http = require("resty.http")
7+
local ltn12 = require("ltn12")
8+
local config = lapis_config.get()
9+
local start_time
10+
if config.measure_performance then
11+
ngx.update_time()
12+
start_time = ngx.now()
13+
end
14+
local return_res_body
15+
local req
16+
if type(url) == "table" then
17+
req = url
18+
else
19+
return_res_body = true
20+
req = {
21+
url = url,
22+
source = str_body and ltn12.source.string(str_body),
23+
headers = str_body and {
24+
["Content-type"] = "application/x-www-form-urlencoded"
25+
}
26+
}
27+
end
28+
req.method = req.method or (req.source and "POST" or "GET")
29+
local httpc = http.new()
30+
local res, err = httpc:request_uri(req.url, {
31+
method = req.method,
32+
headers = req.headers,
33+
body = req.source,
34+
ssl_verify = true
35+
})
36+
if not (res) then
37+
error("resty.http request failed: " .. tostring(err))
38+
end
39+
local out
40+
if return_res_body then
41+
out = res.body
42+
else
43+
if req.sink then
44+
ltn12.pump.all(ltn12.source.string(res.body), req.sink)
45+
end
46+
out = 1
47+
end
48+
if start_time then
49+
ngx.update_time()
50+
increment_perf("http_count", 1)
51+
increment_perf("http_time", ngx.now() - start_time)
52+
end
53+
return out, res.status, res.headers
54+
end
55+
return {
56+
request = request
57+
}

lapis/nginx/resty_http.moon

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
2+
-- This implements a basic LuaSocket's http.request interface using lua-resty-http.
3+
--
4+
-- Usage:
5+
-- http = require "lapis.nginx.resty_http"
6+
-- body, status, headers = http.request("http://example.com")
7+
8+
lapis_config = require "lapis.config"
9+
10+
import increment_perf from require "lapis.nginx.context"
11+
12+
---Make an HTTP request using lua-resty-http
13+
---@param url string|table URL string or request table with url, method, source, sink, headers fields
14+
---@param str_body string? Request body for simple POST requests
15+
---@return string|number body Response body (or 1 if sink was provided)
16+
---@return number status HTTP status code
17+
---@return table headers Response headers
18+
request = (url, str_body) ->
19+
http = require "resty.http"
20+
ltn12 = require "ltn12"
21+
22+
config = lapis_config.get!
23+
start_time = if config.measure_performance
24+
ngx.update_time!
25+
ngx.now!
26+
27+
local return_res_body
28+
req = if type(url) == "table"
29+
url
30+
else
31+
return_res_body = true
32+
{
33+
:url
34+
source: str_body and ltn12.source.string str_body
35+
headers: str_body and {
36+
"Content-type": "application/x-www-form-urlencoded"
37+
}
38+
}
39+
40+
req.method or= req.source and "POST" or "GET"
41+
42+
httpc = http.new!
43+
-- TODO: if source iterator returns an error, resty.http treats it as end of stream and does not surface the error
44+
res, err = httpc\request_uri req.url, {
45+
method: req.method
46+
headers: req.headers
47+
body: req.source -- ltn12 source is compatible as body iterator; caller provides Content-Length header if needed
48+
ssl_verify: true
49+
}
50+
51+
unless res
52+
error "resty.http request failed: #{err}"
53+
54+
out = if return_res_body
55+
res.body
56+
else
57+
-- TODO: support streaming response body to sink, would need to use lower level API
58+
if req.sink
59+
ltn12.pump.all ltn12.source.string(res.body), req.sink
60+
1
61+
62+
if start_time
63+
ngx.update_time!
64+
increment_perf "http_count", 1
65+
increment_perf "http_time", ngx.now! - start_time
66+
67+
out, res.status, res.headers
68+
69+
{ :request }

0 commit comments

Comments
 (0)