xref: /unit/src/nxt_upstream.c (revision 1954:8f18a05d4c58)
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