Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.

Commit 0e41e7a

Browse files
committed
Spike out upstream.add_server_to_upstream()
This is based heavily on the work in openresty#13 but involves slightly fewer changes to the module as a whole.
1 parent bbe6865 commit 0e41e7a

File tree

3 files changed

+167
-12
lines changed

3 files changed

+167
-12
lines changed

README.md

+2-12
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,9 @@ The return value is an array-like Lua table. Each table entry is a hash-like Lua
130130

131131
add_server_to_upstream
132132
-----------
133-
`syntax: err = upstream.add_server_to_upstream(upstream_name, server)`
133+
`syntax: ok, err = upstream.add_server(upstream_name, ip:port, weight, max_fails, fail_timeout)`
134134

135-
Add a server to a given upstream. The server should be a hash-like Lua table and may contain the following keys (bolded keys are required):
136-
137-
* **name**
138-
* **addr**
139-
socket address(es). can be either a Lua string or an array-like Lua table of Lua strings.
140-
* backup
141-
* fail_timeout
142-
* max_fails
143-
* weight
144-
145-
The return value is an error string or nil.
135+
The return values are a boolean denoting the success of the operation and an associated error if one occurs.
146136

147137
[Back to TOC](#table-of-contents)
148138

src/ngx_http_lua_upstream_module.c

+116
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static ngx_int_t ngx_http_lua_upstream_init(ngx_conf_t *cf);
2323
static int ngx_http_lua_upstream_create_module(lua_State * L);
2424
static int ngx_http_lua_upstream_get_upstreams(lua_State * L);
2525
static int ngx_http_lua_upstream_get_servers(lua_State * L);
26+
static int ngx_http_lua_upstream_add_server_to_upstream(lua_State * L);
2627
static ngx_http_upstream_main_conf_t *
2728
ngx_http_lua_upstream_get_upstream_main_conf(lua_State *L);
2829
static int ngx_http_lua_upstream_get_primary_peers(lua_State * L);
@@ -31,12 +32,15 @@ static int ngx_http_lua_get_peer(lua_State *L,
3132
ngx_http_upstream_rr_peer_t *peer, ngx_uint_t id);
3233
static ngx_http_upstream_srv_conf_t *
3334
ngx_http_lua_upstream_find_upstream(lua_State *L, ngx_str_t *host);
35+
static ngx_http_upstream_server_t*
36+
ngx_http_lua_upstream_find_server(ngx_http_upstream_srv_conf_t * us, ngx_url_t u);
3437
static ngx_http_upstream_rr_peer_t *
3538
ngx_http_lua_upstream_lookup_peer(lua_State *L);
3639
static int ngx_http_lua_upstream_set_peer_down(lua_State * L);
3740
static int ngx_http_lua_upstream_current_upstream_name(lua_State *L);
3841

3942

43+
4044
static ngx_http_module_t ngx_http_lua_upstream_ctx = {
4145
NULL, /* preconfiguration */
4246
ngx_http_lua_upstream_init, /* postconfiguration */
@@ -141,6 +145,92 @@ ngx_http_lua_upstream_get_upstreams(lua_State * L)
141145
return 1;
142146
}
143147

148+
static int
149+
ngx_http_lua_upstream_add_server_to_upstream(lua_State * L)
150+
{
151+
ngx_str_t host;
152+
ngx_http_upstream_server_t *us;
153+
ngx_http_upstream_srv_conf_t *uscf;
154+
ngx_url_t u;
155+
ngx_http_request_t *r;
156+
ngx_int_t weight, max_fails;
157+
ngx_uint_t backup;
158+
time_t fail_timeout;
159+
u_char *p;
160+
161+
if (lua_gettop(L) != 6) {
162+
/*
163+
* "upstream name", "host:port", "weight", "max_fails", "fail_timeout", "backup"
164+
*/
165+
return luaL_error(L, "exactly 6 arguments expected");
166+
}
167+
168+
r = ngx_http_lua_get_request(L);
169+
if (r == NULL) {
170+
lua_pushnil(L);
171+
lua_pushliteral(L, "get request error \n");
172+
return 2;
173+
}
174+
175+
host.data = (u_char *) luaL_checklstring(L, 1, &host.len);
176+
177+
ngx_memzero(&u, sizeof(ngx_url_t));
178+
p = (u_char *) luaL_checklstring(L, 2, &u.url.len);
179+
u.default_port = 80;
180+
181+
weight = (ngx_int_t) luaL_checkint(L, 3);
182+
max_fails = (ngx_int_t) luaL_checkint(L, 4);
183+
fail_timeout = (time_t) luaL_checklong(L, 5);
184+
backup = lua_toboolean(L, 6);
185+
#if (NGX_DEBUG)
186+
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "%s %s params: %s,%s,%d,%d,%d\n", __FILE__, __FUNCTION__, host.data, p, weight, max_fails, fail_timeout);
187+
#endif
188+
189+
uscf = ngx_http_lua_upstream_find_upstream(L, &host);
190+
if (uscf == NULL) {
191+
lua_pushnil(L);
192+
lua_pushliteral(L, "upstream not found\n");
193+
return 2;
194+
}
195+
196+
u.url.data = ngx_pcalloc(uscf->servers->pool, u.url.len+1);
197+
ngx_memcpy(u.url.data, p, u.url.len);
198+
199+
if (ngx_http_lua_upstream_find_server(uscf, u) != NULL) {
200+
lua_pushnil(L);
201+
lua_pushliteral(L, "server already exists\n");
202+
return 2;
203+
} else {
204+
// validate URL
205+
if (ngx_parse_url(uscf->servers->pool, &u) != NGX_OK) {
206+
if (u.err) {
207+
lua_pushnil(L);
208+
lua_pushliteral(L, "url parser error\n");
209+
return 2;
210+
}
211+
}
212+
213+
us = ngx_array_push(uscf->servers);
214+
if (us == NULL) {
215+
lua_pushnil(L);
216+
lua_pushliteral(L, "could not append server to upstream\n");
217+
return 2;
218+
}
219+
220+
ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
221+
222+
us->name = u.url;
223+
us->addrs = u.addrs;
224+
us->naddrs = u.naddrs;
225+
us->weight = weight;
226+
us->max_fails = max_fails;
227+
us->fail_timeout = fail_timeout;
228+
us->backup = backup;
229+
}
230+
231+
lua_pushboolean(L, 1);
232+
return 1;
233+
}
144234

145235
static int
146236
ngx_http_lua_upstream_get_servers(lua_State * L)
@@ -551,6 +641,32 @@ ngx_http_lua_upstream_find_upstream(lua_State *L, ngx_str_t *host)
551641
return NULL;
552642
}
553643

644+
static ngx_http_upstream_server_t*
645+
ngx_http_lua_upstream_find_server(ngx_http_upstream_srv_conf_t * us, ngx_url_t u)
646+
{
647+
ngx_uint_t i, j;
648+
size_t len;
649+
ngx_http_upstream_server_t *server = NULL;
650+
651+
if (us->servers == NULL || us->servers->nelts == 0) {
652+
return NULL;
653+
}
654+
655+
server = us->servers->elts;
656+
657+
for (i = 0; i < us->servers->nelts; ++i) {
658+
for (j = 0; j < server[i].naddrs; ++j) {
659+
len = server[i].addrs[j].name.len;
660+
661+
if (len == u.url.len
662+
&& ngx_memcmp(u.url.data, server[i].addrs[j].name.data, u.url.len) == 0) {
663+
return &server[i];
664+
}
665+
}
666+
}
667+
668+
return NULL;
669+
}
554670

555671
static int
556672
ngx_http_lua_upstream_current_upstream_name(lua_State *L)

t/sanity.t

+49
Original file line numberDiff line numberDiff line change
@@ -648,3 +648,52 @@ nil
648648
--- no_error_log
649649
[error]
650650
651+
652+
=== TEST 19: add server to pre-defined upstream
653+
--- http_config
654+
upstream foo {
655+
}
656+
657+
--- config
658+
location /t {
659+
content_by_lua '
660+
local upstream = require "ngx.upstream"
661+
local err = upstream.add_server_to_upstream("foo", { name = "127.0.0.1:8080", addr = "127.0.0.1:8080" })
662+
if err then
663+
ngx.say(err)
664+
else
665+
local srvs, err = get_servers("foo")
666+
if not srvs then
667+
ngx.say("failed to get servers in upstream foo")
668+
else
669+
ngx.say("upstream foo:")
670+
for _, srv in ipairs(srvs) do
671+
local first = true
672+
for k, v in pairs(srv) do
673+
if first then
674+
first = false
675+
ngx.print(" ")
676+
else
677+
ngx.print(", ")
678+
end
679+
if type(v) == "table" then
680+
ngx.print(k, " = {", concat(v, ", "), "}")
681+
else
682+
ngx.print(k, " = ", v)
683+
end
684+
end
685+
ngx.print("\\n")
686+
end
687+
end
688+
ngs.say("done")
689+
end
690+
';
691+
}
692+
--- request
693+
GET /t
694+
--- response_body
695+
foo:
696+
addr = 127.0.0.1:8080, name = 127.0.0.1:8080
697+
done
698+
--- no_error_log
699+
[error]

0 commit comments

Comments
 (0)