/src/unit/src/nxt_upstream.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
20 | 0 | size_t size; |
21 | 0 | uint32_t i, n, next; |
22 | 0 | nxt_mp_t *mp; |
23 | 0 | nxt_int_t ret; |
24 | 0 | nxt_str_t name, *string; |
25 | 0 | nxt_upstreams_t *upstreams; |
26 | 0 | nxt_conf_value_t *upstreams_conf, *upcf; |
27 | |
|
28 | 0 | static const nxt_str_t upstreams_name = nxt_string("upstreams"); |
29 | |
|
30 | 0 | upstreams_conf = nxt_conf_get_object_member(conf, &upstreams_name, NULL); |
31 | |
|
32 | 0 | if (upstreams_conf == NULL) { |
33 | 0 | return NXT_OK; |
34 | 0 | } |
35 | | |
36 | 0 | n = nxt_conf_object_members_count(upstreams_conf); |
37 | |
|
38 | 0 | if (n == 0) { |
39 | 0 | return NXT_OK; |
40 | 0 | } |
41 | | |
42 | 0 | mp = tmcf->router_conf->mem_pool; |
43 | 0 | size = sizeof(nxt_upstreams_t) + n * sizeof(nxt_upstream_t); |
44 | |
|
45 | 0 | upstreams = nxt_mp_zalloc(mp, size); |
46 | 0 | if (nxt_slow_path(upstreams == NULL)) { |
47 | 0 | return NXT_ERROR; |
48 | 0 | } |
49 | | |
50 | 0 | upstreams->items = n; |
51 | 0 | next = 0; |
52 | |
|
53 | 0 | for (i = 0; i < n; i++) { |
54 | 0 | upcf = nxt_conf_next_object_member(upstreams_conf, &name, &next); |
55 | |
|
56 | 0 | string = nxt_str_dup(mp, &upstreams->upstream[i].name, &name); |
57 | 0 | if (nxt_slow_path(string == NULL)) { |
58 | 0 | return NXT_ERROR; |
59 | 0 | } |
60 | | |
61 | 0 | ret = nxt_upstream_round_robin_create(task, tmcf, upcf, |
62 | 0 | &upstreams->upstream[i]); |
63 | 0 | if (nxt_slow_path(ret != NXT_OK)) { |
64 | 0 | return NXT_ERROR; |
65 | 0 | } |
66 | 0 | } |
67 | | |
68 | 0 | tmcf->router_conf->upstreams = upstreams; |
69 | |
|
70 | 0 | return NXT_OK; |
71 | 0 | } |
72 | | |
73 | | |
74 | | nxt_int_t |
75 | | nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, |
76 | | nxt_http_action_t *action) |
77 | 0 | { |
78 | 0 | uint32_t i, n; |
79 | 0 | nxt_upstream_t *upstream; |
80 | |
|
81 | 0 | if (upstreams == NULL) { |
82 | 0 | return NXT_DECLINED; |
83 | 0 | } |
84 | | |
85 | 0 | upstream = &upstreams->upstream[0]; |
86 | 0 | n = upstreams->items; |
87 | |
|
88 | 0 | for (i = 0; i < n; i++) { |
89 | 0 | if (nxt_strstr_eq(&upstream[i].name, name)) { |
90 | 0 | action->u.upstream_number = i; |
91 | 0 | action->handler = nxt_upstream_handler; |
92 | |
|
93 | 0 | return NXT_OK; |
94 | 0 | } |
95 | 0 | } |
96 | | |
97 | 0 | return NXT_DECLINED; |
98 | 0 | } |
99 | | |
100 | | |
101 | | nxt_int_t |
102 | | nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf, |
103 | | nxt_upstream_t ***upstream_joint) |
104 | 0 | { |
105 | 0 | uint32_t i, n; |
106 | 0 | nxt_upstream_t *u, **up; |
107 | 0 | nxt_upstreams_t *upstreams; |
108 | 0 | nxt_router_conf_t *router_conf; |
109 | |
|
110 | 0 | router_conf = tmcf->router_conf; |
111 | 0 | upstreams = router_conf->upstreams; |
112 | |
|
113 | 0 | if (upstreams == NULL) { |
114 | 0 | *upstream_joint = NULL; |
115 | 0 | return NXT_OK; |
116 | 0 | } |
117 | | |
118 | 0 | n = upstreams->items; |
119 | |
|
120 | 0 | up = nxt_mp_zalloc(router_conf->mem_pool, n * sizeof(nxt_upstream_t *)); |
121 | 0 | if (nxt_slow_path(up == NULL)) { |
122 | 0 | return NXT_ERROR; |
123 | 0 | } |
124 | | |
125 | 0 | u = &upstreams->upstream[0]; |
126 | |
|
127 | 0 | for (i = 0; i < n; i++) { |
128 | 0 | up[i] = u[i].proto->joint_create(tmcf, &u[i]); |
129 | 0 | if (nxt_slow_path(up[i] == NULL)) { |
130 | 0 | return NXT_ERROR; |
131 | 0 | } |
132 | 0 | } |
133 | | |
134 | 0 | *upstream_joint = up; |
135 | |
|
136 | 0 | return NXT_OK; |
137 | 0 | } |
138 | | |
139 | | |
140 | | static nxt_http_action_t * |
141 | | nxt_upstream_handler(nxt_task_t *task, nxt_http_request_t *r, |
142 | | nxt_http_action_t *action) |
143 | 0 | { |
144 | 0 | nxt_upstream_t *u; |
145 | |
|
146 | 0 | u = r->conf->upstreams[action->u.upstream_number]; |
147 | |
|
148 | 0 | nxt_debug(task, "upstream handler: \"%V\"", &u->name); |
149 | |
|
150 | 0 | return nxt_upstream_proxy_handler(task, r, u); |
151 | 0 | } |