1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_router.h> 8 #include <nxt_http.h> 9 #include <nxt_upstream.h> 10 11 12 static nxt_http_action_t *nxt_upstream_handler(nxt_task_t *task, 13 nxt_http_request_t *r, nxt_http_action_t *action); 14 15 16 nxt_int_t 17 nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, 18 nxt_conf_value_t *conf) 19 { 20 size_t size; 21 uint32_t i, n, next; 22 nxt_mp_t *mp; 23 nxt_int_t ret; 24 nxt_str_t name, *string; 25 nxt_upstreams_t *upstreams; 26 nxt_conf_value_t *upstreams_conf, *upcf; 27 28 static nxt_str_t upstreams_name = nxt_string("upstreams"); 29 30 upstreams_conf = nxt_conf_get_object_member(conf, &upstreams_name, NULL); 31 32 if (upstreams_conf == NULL) { 33 return NXT_OK; 34 } 35 36 n = nxt_conf_object_members_count(upstreams_conf); 37 38 if (n == 0) { 39 return NXT_OK; 40 } 41 42 mp = tmcf->router_conf->mem_pool; 43 size = sizeof(nxt_upstreams_t) + n * sizeof(nxt_upstream_t); 44 45 upstreams = nxt_mp_zalloc(mp, size); 46 if (nxt_slow_path(upstreams == NULL)) { 47 return NXT_ERROR; 48 } 49 50 upstreams->items = n; 51 next = 0; 52 53 for (i = 0; i < n; i++) { 54 upcf = nxt_conf_next_object_member(upstreams_conf, &name, &next); 55 56 string = nxt_str_dup(mp, &upstreams->upstream[i].name, &name); 57 if (nxt_slow_path(string == NULL)) { 58 return NXT_ERROR; 59 } 60 61 ret = nxt_upstream_round_robin_create(task, tmcf, upcf, 62 &upstreams->upstream[i]); 63 if (nxt_slow_path(ret != NXT_OK)) { 64 return NXT_ERROR; 65 } 66 } 67 68 tmcf->router_conf->upstreams = upstreams; 69 70 return NXT_OK; 71 } 72 73 74 void 75 nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, 76 nxt_http_action_t *action) 77 { 78 uint32_t i, n; 79 nxt_upstream_t *upstream; 80 81 upstream = &upstreams->upstream[0]; 82 n = upstreams->items; 83 84 for (i = 0; i < n; i++) { 85 if (nxt_strstr_eq(&upstream[i].name, name)) { 86 action->u.upstream_number = i; 87 action->handler = nxt_upstream_handler; 88 89 return; 90 } 91 } 92 } 93 94 95 nxt_int_t 96 nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf, 97 nxt_upstream_t ***upstream_joint) 98 { 99 uint32_t i, n; 100 nxt_upstream_t *u, **up; 101 nxt_upstreams_t *upstreams; 102 nxt_router_conf_t *router_conf; 103 104 router_conf = tmcf->router_conf; 105 upstreams = router_conf->upstreams; 106 107 if (upstreams == NULL) { 108 *upstream_joint = NULL; 109 return NXT_OK; 110 } 111 112 n = upstreams->items; 113 114 up = nxt_mp_zalloc(router_conf->mem_pool, n * sizeof(nxt_upstream_t *)); 115 if (nxt_slow_path(up == NULL)) { 116 return NXT_ERROR; 117 } 118 119 u = &upstreams->upstream[0]; 120 121 for (i = 0; i < n; i++) { 122 up[i] = u[i].proto->joint_create(tmcf, &u[i]); 123 if (nxt_slow_path(up[i] == NULL)) { 124 return NXT_ERROR; 125 } 126 } 127 128 *upstream_joint = up; 129 130 return NXT_OK; 131 } 132 133 134 static nxt_http_action_t * 135 nxt_upstream_handler(nxt_task_t *task, nxt_http_request_t *r, 136 nxt_http_action_t *action) 137 { 138 return nxt_upstream_proxy_handler(task, r, 139 r->conf->upstreams[action->u.upstream_number]); 140 } 141