10Sigor@sysoev.ru
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru */
60Sigor@sysoev.ru
71394Sigor@sysoev.ru #include <nxt_router.h>
81394Sigor@sysoev.ru #include <nxt_http.h>
91394Sigor@sysoev.ru #include <nxt_upstream.h>
101394Sigor@sysoev.ru
111394Sigor@sysoev.ru
121394Sigor@sysoev.ru static nxt_http_action_t *nxt_upstream_handler(nxt_task_t *task,
131394Sigor@sysoev.ru nxt_http_request_t *r, nxt_http_action_t *action);
141394Sigor@sysoev.ru
151394Sigor@sysoev.ru
161394Sigor@sysoev.ru nxt_int_t
nxt_upstreams_create(nxt_task_t * task,nxt_router_temp_conf_t * tmcf,nxt_conf_value_t * conf)171394Sigor@sysoev.ru nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
181394Sigor@sysoev.ru nxt_conf_value_t *conf)
191394Sigor@sysoev.ru {
201394Sigor@sysoev.ru size_t size;
211394Sigor@sysoev.ru uint32_t i, n, next;
221394Sigor@sysoev.ru nxt_mp_t *mp;
231394Sigor@sysoev.ru nxt_int_t ret;
241394Sigor@sysoev.ru nxt_str_t name, *string;
251394Sigor@sysoev.ru nxt_upstreams_t *upstreams;
261394Sigor@sysoev.ru nxt_conf_value_t *upstreams_conf, *upcf;
271394Sigor@sysoev.ru
281394Sigor@sysoev.ru static nxt_str_t upstreams_name = nxt_string("upstreams");
291394Sigor@sysoev.ru
301394Sigor@sysoev.ru upstreams_conf = nxt_conf_get_object_member(conf, &upstreams_name, NULL);
311394Sigor@sysoev.ru
321394Sigor@sysoev.ru if (upstreams_conf == NULL) {
331394Sigor@sysoev.ru return NXT_OK;
341394Sigor@sysoev.ru }
351394Sigor@sysoev.ru
361394Sigor@sysoev.ru n = nxt_conf_object_members_count(upstreams_conf);
371394Sigor@sysoev.ru
381394Sigor@sysoev.ru if (n == 0) {
391394Sigor@sysoev.ru return NXT_OK;
401394Sigor@sysoev.ru }
411394Sigor@sysoev.ru
421394Sigor@sysoev.ru mp = tmcf->router_conf->mem_pool;
431394Sigor@sysoev.ru size = sizeof(nxt_upstreams_t) + n * sizeof(nxt_upstream_t);
441394Sigor@sysoev.ru
451394Sigor@sysoev.ru upstreams = nxt_mp_zalloc(mp, size);
461394Sigor@sysoev.ru if (nxt_slow_path(upstreams == NULL)) {
471394Sigor@sysoev.ru return NXT_ERROR;
481394Sigor@sysoev.ru }
491394Sigor@sysoev.ru
501394Sigor@sysoev.ru upstreams->items = n;
511394Sigor@sysoev.ru next = 0;
521394Sigor@sysoev.ru
531394Sigor@sysoev.ru for (i = 0; i < n; i++) {
541394Sigor@sysoev.ru upcf = nxt_conf_next_object_member(upstreams_conf, &name, &next);
551394Sigor@sysoev.ru
561394Sigor@sysoev.ru string = nxt_str_dup(mp, &upstreams->upstream[i].name, &name);
571394Sigor@sysoev.ru if (nxt_slow_path(string == NULL)) {
581394Sigor@sysoev.ru return NXT_ERROR;
591394Sigor@sysoev.ru }
601394Sigor@sysoev.ru
611394Sigor@sysoev.ru ret = nxt_upstream_round_robin_create(task, tmcf, upcf,
621394Sigor@sysoev.ru &upstreams->upstream[i]);
631394Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) {
641394Sigor@sysoev.ru return NXT_ERROR;
651394Sigor@sysoev.ru }
661394Sigor@sysoev.ru }
671394Sigor@sysoev.ru
681394Sigor@sysoev.ru tmcf->router_conf->upstreams = upstreams;
691394Sigor@sysoev.ru
701394Sigor@sysoev.ru return NXT_OK;
711394Sigor@sysoev.ru }
721394Sigor@sysoev.ru
731394Sigor@sysoev.ru
741563Svbart@nginx.com nxt_int_t
nxt_upstream_find(nxt_upstreams_t * upstreams,nxt_str_t * name,nxt_http_action_t * action)751394Sigor@sysoev.ru nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name,
761394Sigor@sysoev.ru nxt_http_action_t *action)
771394Sigor@sysoev.ru {
781394Sigor@sysoev.ru uint32_t i, n;
791394Sigor@sysoev.ru nxt_upstream_t *upstream;
801394Sigor@sysoev.ru
811928Sz.hong@f5.com if (upstreams == NULL) {
821928Sz.hong@f5.com return NXT_DECLINED;
831928Sz.hong@f5.com }
841928Sz.hong@f5.com
851394Sigor@sysoev.ru upstream = &upstreams->upstream[0];
861394Sigor@sysoev.ru n = upstreams->items;
871394Sigor@sysoev.ru
881394Sigor@sysoev.ru for (i = 0; i < n; i++) {
891394Sigor@sysoev.ru if (nxt_strstr_eq(&upstream[i].name, name)) {
901394Sigor@sysoev.ru action->u.upstream_number = i;
911394Sigor@sysoev.ru action->handler = nxt_upstream_handler;
921394Sigor@sysoev.ru
931597Shongzhidao@gmail.com return NXT_OK;
941394Sigor@sysoev.ru }
951394Sigor@sysoev.ru }
961563Svbart@nginx.com
971597Shongzhidao@gmail.com return NXT_DECLINED;
981394Sigor@sysoev.ru }
991394Sigor@sysoev.ru
1001394Sigor@sysoev.ru
1011394Sigor@sysoev.ru nxt_int_t
nxt_upstreams_joint_create(nxt_router_temp_conf_t * tmcf,nxt_upstream_t *** upstream_joint)1021394Sigor@sysoev.ru nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
1031394Sigor@sysoev.ru nxt_upstream_t ***upstream_joint)
1041394Sigor@sysoev.ru {
1051394Sigor@sysoev.ru uint32_t i, n;
1061394Sigor@sysoev.ru nxt_upstream_t *u, **up;
1071394Sigor@sysoev.ru nxt_upstreams_t *upstreams;
1081394Sigor@sysoev.ru nxt_router_conf_t *router_conf;
1091394Sigor@sysoev.ru
1101394Sigor@sysoev.ru router_conf = tmcf->router_conf;
1111394Sigor@sysoev.ru upstreams = router_conf->upstreams;
1121394Sigor@sysoev.ru
1131394Sigor@sysoev.ru if (upstreams == NULL) {
1141394Sigor@sysoev.ru *upstream_joint = NULL;
1151394Sigor@sysoev.ru return NXT_OK;
1161394Sigor@sysoev.ru }
1171394Sigor@sysoev.ru
1181394Sigor@sysoev.ru n = upstreams->items;
1191394Sigor@sysoev.ru
1201394Sigor@sysoev.ru up = nxt_mp_zalloc(router_conf->mem_pool, n * sizeof(nxt_upstream_t *));
1211394Sigor@sysoev.ru if (nxt_slow_path(up == NULL)) {
1221394Sigor@sysoev.ru return NXT_ERROR;
1231394Sigor@sysoev.ru }
1241394Sigor@sysoev.ru
1251394Sigor@sysoev.ru u = &upstreams->upstream[0];
1261394Sigor@sysoev.ru
1271394Sigor@sysoev.ru for (i = 0; i < n; i++) {
1281394Sigor@sysoev.ru up[i] = u[i].proto->joint_create(tmcf, &u[i]);
1291394Sigor@sysoev.ru if (nxt_slow_path(up[i] == NULL)) {
1301394Sigor@sysoev.ru return NXT_ERROR;
1311394Sigor@sysoev.ru }
1321394Sigor@sysoev.ru }
1331394Sigor@sysoev.ru
1341394Sigor@sysoev.ru *upstream_joint = up;
1351394Sigor@sysoev.ru
1361394Sigor@sysoev.ru return NXT_OK;
1371394Sigor@sysoev.ru }
1381394Sigor@sysoev.ru
1391394Sigor@sysoev.ru
1401394Sigor@sysoev.ru static nxt_http_action_t *
nxt_upstream_handler(nxt_task_t * task,nxt_http_request_t * r,nxt_http_action_t * action)1411394Sigor@sysoev.ru nxt_upstream_handler(nxt_task_t *task, nxt_http_request_t *r,
1421394Sigor@sysoev.ru nxt_http_action_t *action)
1431394Sigor@sysoev.ru {
144*1954Sz.hong@f5.com nxt_upstream_t *u;
145*1954Sz.hong@f5.com
146*1954Sz.hong@f5.com u = r->conf->upstreams[action->u.upstream_number];
147*1954Sz.hong@f5.com
148*1954Sz.hong@f5.com nxt_debug(task, "upstream handler: \"%V\"", &u->name);
149*1954Sz.hong@f5.com
150*1954Sz.hong@f5.com return nxt_upstream_proxy_handler(task, r, u);
1511394Sigor@sysoev.ru }
152