nginxtra 1.2.1.3 → 1.2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/VERSION +1 -1
  2. data/bin/nginxtra +1 -1
  3. data/src/nginx/CHANGES +60 -0
  4. data/src/nginx/CHANGES.ru +57 -0
  5. data/src/nginx/auto/{endianess → endianness} +5 -5
  6. data/src/nginx/auto/lib/google-perftools/conf +16 -0
  7. data/src/nginx/auto/modules +10 -0
  8. data/src/nginx/auto/options +3 -0
  9. data/src/nginx/auto/os/conf +2 -0
  10. data/src/nginx/auto/sources +5 -0
  11. data/src/nginx/auto/unix +1 -1
  12. data/src/nginx/src/core/nginx.h +2 -2
  13. data/src/nginx/src/core/ngx_hash.c +13 -11
  14. data/src/nginx/src/core/ngx_inet.c +32 -31
  15. data/src/nginx/src/core/ngx_regex.c +3 -3
  16. data/src/nginx/src/core/ngx_regex.h +2 -2
  17. data/src/nginx/src/core/ngx_resolver.c +22 -16
  18. data/src/nginx/src/event/ngx_event_openssl.c +18 -1
  19. data/src/nginx/src/http/modules/ngx_http_geo_module.c +1 -1
  20. data/src/nginx/src/http/modules/ngx_http_geoip_module.c +15 -4
  21. data/src/nginx/src/http/modules/ngx_http_log_module.c +3 -6
  22. data/src/nginx/src/http/modules/ngx_http_mp4_module.c +18 -1
  23. data/src/nginx/src/http/modules/ngx_http_rewrite_module.c +6 -0
  24. data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +7 -0
  25. data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +44 -17
  26. data/src/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +4 -29
  27. data/src/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +402 -0
  28. data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +2 -2
  29. data/src/nginx/src/http/modules/perl/nginx.pm +1 -1
  30. data/src/nginx/src/http/modules/perl/nginx.xs +1 -1
  31. data/src/nginx/src/http/ngx_http_core_module.c +1 -1
  32. data/src/nginx/src/http/ngx_http_header_filter_module.c +2 -2
  33. data/src/nginx/src/http/ngx_http_request.c +1 -1
  34. data/src/nginx/src/http/ngx_http_request.h +8 -1
  35. data/src/nginx/src/http/ngx_http_upstream.c +15 -1
  36. data/src/nginx/src/http/ngx_http_upstream_round_robin.c +11 -1
  37. data/src/nginx/src/http/ngx_http_upstream_round_robin.h +5 -1
  38. data/src/nginx/src/http/ngx_http_variables.c +49 -3
  39. data/src/nginx/src/os/unix/ngx_errno.c +1 -1
  40. data/src/nginx/src/os/unix/ngx_errno.h +1 -1
  41. data/src/nginx/src/os/unix/ngx_freebsd_init.c +2 -2
  42. data/src/nginx/src/os/unix/ngx_posix_config.h +1 -0
  43. data/src/nginx/src/os/unix/ngx_process_cycle.c +4 -0
  44. metadata +5 -4
@@ -0,0 +1,402 @@
1
+
2
+ /*
3
+ * Copyright (C) Maxim Dounin
4
+ * Copyright (C) Nginx, Inc.
5
+ */
6
+
7
+
8
+ #include <ngx_config.h>
9
+ #include <ngx_core.h>
10
+ #include <ngx_http.h>
11
+
12
+
13
+ typedef struct {
14
+ ngx_uint_t *conns;
15
+ } ngx_http_upstream_least_conn_conf_t;
16
+
17
+
18
+ typedef struct {
19
+ /* the round robin data must be first */
20
+ ngx_http_upstream_rr_peer_data_t rrp;
21
+
22
+ ngx_uint_t *conns;
23
+
24
+ ngx_event_get_peer_pt get_rr_peer;
25
+ ngx_event_free_peer_pt free_rr_peer;
26
+ } ngx_http_upstream_lc_peer_data_t;
27
+
28
+
29
+ static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r,
30
+ ngx_http_upstream_srv_conf_t *us);
31
+ static ngx_int_t ngx_http_upstream_get_least_conn_peer(
32
+ ngx_peer_connection_t *pc, void *data);
33
+ static void ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
34
+ void *data, ngx_uint_t state);
35
+ static void *ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf);
36
+ static char *ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd,
37
+ void *conf);
38
+
39
+
40
+ static ngx_command_t ngx_http_upstream_least_conn_commands[] = {
41
+
42
+ { ngx_string("least_conn"),
43
+ NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
44
+ ngx_http_upstream_least_conn,
45
+ 0,
46
+ 0,
47
+ NULL },
48
+
49
+ ngx_null_command
50
+ };
51
+
52
+
53
+ static ngx_http_module_t ngx_http_upstream_least_conn_module_ctx = {
54
+ NULL, /* preconfiguration */
55
+ NULL, /* postconfiguration */
56
+
57
+ NULL, /* create main configuration */
58
+ NULL, /* init main configuration */
59
+
60
+ ngx_http_upstream_least_conn_create_conf, /* create server configuration */
61
+ NULL, /* merge server configuration */
62
+
63
+ NULL, /* create location configuration */
64
+ NULL /* merge location configuration */
65
+ };
66
+
67
+
68
+ ngx_module_t ngx_http_upstream_least_conn_module = {
69
+ NGX_MODULE_V1,
70
+ &ngx_http_upstream_least_conn_module_ctx, /* module context */
71
+ ngx_http_upstream_least_conn_commands, /* module directives */
72
+ NGX_HTTP_MODULE, /* module type */
73
+ NULL, /* init master */
74
+ NULL, /* init module */
75
+ NULL, /* init process */
76
+ NULL, /* init thread */
77
+ NULL, /* exit thread */
78
+ NULL, /* exit process */
79
+ NULL, /* exit master */
80
+ NGX_MODULE_V1_PADDING
81
+ };
82
+
83
+
84
+ ngx_int_t
85
+ ngx_http_upstream_init_least_conn(ngx_conf_t *cf,
86
+ ngx_http_upstream_srv_conf_t *us)
87
+ {
88
+ ngx_uint_t n;
89
+ ngx_http_upstream_rr_peers_t *peers;
90
+ ngx_http_upstream_least_conn_conf_t *lcf;
91
+
92
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
93
+ "init least conn");
94
+
95
+ if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
96
+ return NGX_ERROR;
97
+ }
98
+
99
+ peers = us->peer.data;
100
+
101
+ n = peers->number;
102
+
103
+ if (peers->next) {
104
+ n += peers->next->number;
105
+ }
106
+
107
+ lcf = ngx_http_conf_upstream_srv_conf(us,
108
+ ngx_http_upstream_least_conn_module);
109
+
110
+ lcf->conns = ngx_pcalloc(cf->pool, sizeof(ngx_uint_t) * n);
111
+ if (lcf->conns == NULL) {
112
+ return NGX_ERROR;
113
+ }
114
+
115
+ us->peer.init = ngx_http_upstream_init_least_conn_peer;
116
+
117
+ return NGX_OK;
118
+ }
119
+
120
+
121
+ static ngx_int_t
122
+ ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r,
123
+ ngx_http_upstream_srv_conf_t *us)
124
+ {
125
+ ngx_http_upstream_lc_peer_data_t *lcp;
126
+ ngx_http_upstream_least_conn_conf_t *lcf;
127
+
128
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
129
+ "init least conn peer");
130
+
131
+ lcf = ngx_http_conf_upstream_srv_conf(us,
132
+ ngx_http_upstream_least_conn_module);
133
+
134
+ lcp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_lc_peer_data_t));
135
+ if (lcp == NULL) {
136
+ return NGX_ERROR;
137
+ }
138
+
139
+ lcp->conns = lcf->conns;
140
+
141
+ r->upstream->peer.data = &lcp->rrp;
142
+
143
+ if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
144
+ return NGX_ERROR;
145
+ }
146
+
147
+ r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer;
148
+ r->upstream->peer.free = ngx_http_upstream_free_least_conn_peer;
149
+
150
+ lcp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
151
+ lcp->free_rr_peer = ngx_http_upstream_free_round_robin_peer;
152
+
153
+ return NGX_OK;
154
+ }
155
+
156
+
157
+ static ngx_int_t
158
+ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
159
+ {
160
+ ngx_http_upstream_lc_peer_data_t *lcp = data;
161
+
162
+ time_t now;
163
+ uintptr_t m;
164
+ ngx_int_t rc, total;
165
+ ngx_uint_t i, n, p, many;
166
+ ngx_http_upstream_rr_peer_t *peer, *best;
167
+ ngx_http_upstream_rr_peers_t *peers;
168
+
169
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
170
+ "get least conn peer, try: %ui", pc->tries);
171
+
172
+ if (lcp->rrp.peers->single) {
173
+ return lcp->get_rr_peer(pc, &lcp->rrp);
174
+ }
175
+
176
+ pc->cached = 0;
177
+ pc->connection = NULL;
178
+
179
+ now = ngx_time();
180
+
181
+ peers = lcp->rrp.peers;
182
+
183
+ best = NULL;
184
+ total = 0;
185
+
186
+ #if (NGX_SUPPRESS_WARN)
187
+ many = 0;
188
+ p = 0;
189
+ #endif
190
+
191
+ for (i = 0; i < peers->number; i++) {
192
+
193
+ n = i / (8 * sizeof(uintptr_t));
194
+ m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
195
+
196
+ if (lcp->rrp.tried[n] & m) {
197
+ continue;
198
+ }
199
+
200
+ peer = &peers->peer[i];
201
+
202
+ if (peer->down) {
203
+ continue;
204
+ }
205
+
206
+ if (peer->max_fails
207
+ && peer->fails >= peer->max_fails
208
+ && now - peer->checked <= peer->fail_timeout)
209
+ {
210
+ continue;
211
+ }
212
+
213
+ /*
214
+ * select peer with least number of connections; if there are
215
+ * multiple peers with the same number of connections, select
216
+ * based on round-robin
217
+ */
218
+
219
+ if (best == NULL
220
+ || lcp->conns[i] * best->weight < lcp->conns[p] * peer->weight)
221
+ {
222
+ best = peer;
223
+ many = 0;
224
+ p = i;
225
+
226
+ } else if (lcp->conns[i] * best->weight
227
+ == lcp->conns[p] * peer->weight)
228
+ {
229
+ many = 1;
230
+ }
231
+ }
232
+
233
+ if (best == NULL) {
234
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
235
+ "get least conn peer, no peer found");
236
+
237
+ goto failed;
238
+ }
239
+
240
+ if (many) {
241
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
242
+ "get least conn peer, many");
243
+
244
+ for (i = p; i < peers->number; i++) {
245
+
246
+ n = i / (8 * sizeof(uintptr_t));
247
+ m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
248
+
249
+ if (lcp->rrp.tried[n] & m) {
250
+ continue;
251
+ }
252
+
253
+ peer = &peers->peer[i];
254
+
255
+ if (peer->down) {
256
+ continue;
257
+ }
258
+
259
+ if (lcp->conns[i] * best->weight != lcp->conns[p] * peer->weight) {
260
+ continue;
261
+ }
262
+
263
+ if (peer->max_fails
264
+ && peer->fails >= peer->max_fails
265
+ && now - peer->checked <= peer->fail_timeout)
266
+ {
267
+ continue;
268
+ }
269
+
270
+ peer->current_weight += peer->effective_weight;
271
+ total += peer->effective_weight;
272
+
273
+ if (peer->effective_weight < peer->weight) {
274
+ peer->effective_weight++;
275
+ }
276
+
277
+ if (peer->current_weight > best->current_weight) {
278
+ best = peer;
279
+ p = i;
280
+ }
281
+ }
282
+ }
283
+
284
+ best->current_weight -= total;
285
+ best->checked = now;
286
+
287
+ pc->sockaddr = best->sockaddr;
288
+ pc->socklen = best->socklen;
289
+ pc->name = &best->name;
290
+
291
+ lcp->rrp.current = p;
292
+
293
+ n = p / (8 * sizeof(uintptr_t));
294
+ m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
295
+
296
+ lcp->rrp.tried[n] |= m;
297
+ lcp->conns[p]++;
298
+
299
+ if (pc->tries == 1 && peers->next) {
300
+ pc->tries += peers->next->number;
301
+ }
302
+
303
+ return NGX_OK;
304
+
305
+ failed:
306
+
307
+ if (peers->next) {
308
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
309
+ "get least conn peer, backup servers");
310
+
311
+ lcp->conns += peers->number;
312
+
313
+ lcp->rrp.peers = peers->next;
314
+ pc->tries = lcp->rrp.peers->number;
315
+
316
+ n = lcp->rrp.peers->number / (8 * sizeof(uintptr_t)) + 1;
317
+ for (i = 0; i < n; i++) {
318
+ lcp->rrp.tried[i] = 0;
319
+ }
320
+
321
+ rc = ngx_http_upstream_get_least_conn_peer(pc, lcp);
322
+
323
+ if (rc != NGX_BUSY) {
324
+ return rc;
325
+ }
326
+ }
327
+
328
+ /* all peers failed, mark them as live for quick recovery */
329
+
330
+ for (i = 0; i < peers->number; i++) {
331
+ peers->peer[i].fails = 0;
332
+ }
333
+
334
+ pc->name = peers->name;
335
+
336
+ return NGX_BUSY;
337
+ }
338
+
339
+
340
+ static void
341
+ ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
342
+ void *data, ngx_uint_t state)
343
+ {
344
+ ngx_http_upstream_lc_peer_data_t *lcp = data;
345
+
346
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
347
+ "free least conn peer %ui %ui", pc->tries, state);
348
+
349
+ if (lcp->rrp.peers->single) {
350
+ lcp->free_rr_peer(pc, &lcp->rrp, state);
351
+ return;
352
+ }
353
+
354
+ if (state == 0 && pc->tries == 0) {
355
+ return;
356
+ }
357
+
358
+ lcp->conns[lcp->rrp.current]--;
359
+
360
+ lcp->free_rr_peer(pc, &lcp->rrp, state);
361
+ }
362
+
363
+
364
+ static void *
365
+ ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf)
366
+ {
367
+ ngx_http_upstream_least_conn_conf_t *conf;
368
+
369
+ conf = ngx_pcalloc(cf->pool,
370
+ sizeof(ngx_http_upstream_least_conn_conf_t));
371
+ if (conf == NULL) {
372
+ return NULL;
373
+ }
374
+
375
+ /*
376
+ * set by ngx_pcalloc():
377
+ *
378
+ * conf->conns = NULL;
379
+ */
380
+
381
+ return conf;
382
+ }
383
+
384
+
385
+ static char *
386
+ ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
387
+ {
388
+ ngx_http_upstream_srv_conf_t *uscf;
389
+
390
+ uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
391
+
392
+ uscf->peer.init_upstream = ngx_http_upstream_init_least_conn;
393
+
394
+ uscf->flags = NGX_HTTP_UPSTREAM_CREATE
395
+ |NGX_HTTP_UPSTREAM_WEIGHT
396
+ |NGX_HTTP_UPSTREAM_MAX_FAILS
397
+ |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
398
+ |NGX_HTTP_UPSTREAM_DOWN
399
+ |NGX_HTTP_UPSTREAM_BACKUP;
400
+
401
+ return NGX_CONF_OK;
402
+ }
@@ -810,7 +810,7 @@ ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
810
810
 
811
811
  file = xmcf->dtd_files.elts;
812
812
  for (i = 0; i < xmcf->dtd_files.nelts; i++) {
813
- if (ngx_strcmp(file[i].name, &value[1].data) == 0) {
813
+ if (ngx_strcmp(file[i].name, value[1].data) == 0) {
814
814
  xlcf->dtd = file[i].data;
815
815
  return NGX_CONF_OK;
816
816
  }
@@ -884,7 +884,7 @@ ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
884
884
 
885
885
  file = xmcf->sheet_files.elts;
886
886
  for (i = 0; i < xmcf->sheet_files.nelts; i++) {
887
- if (ngx_strcmp(file[i].name, &value[1].data) == 0) {
887
+ if (ngx_strcmp(file[i].name, value[1].data) == 0) {
888
888
  sheet->stylesheet = file[i].data;
889
889
  goto found;
890
890
  }
@@ -50,7 +50,7 @@ our @EXPORT = qw(
50
50
  HTTP_INSUFFICIENT_STORAGE
51
51
  );
52
52
 
53
- our $VERSION = '1.2.1';
53
+ our $VERSION = '1.2.2';
54
54
 
55
55
  require XSLoader;
56
56
  XSLoader::load('nginx', $VERSION);
@@ -476,7 +476,7 @@ header_out(r, key, value)
476
476
  }
477
477
 
478
478
  if (header->key.len == sizeof("Content-Encoding") - 1
479
- && ngx_strncasecmp(header->key.data, "Content-Encoding",
479
+ && ngx_strncasecmp(header->key.data, (u_char *) "Content-Encoding",
480
480
  sizeof("Content-Encoding") - 1) == 0)
481
481
  {
482
482
  r->headers_out.content_encoding = header;
@@ -4662,7 +4662,7 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4662
4662
 
4663
4663
  code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2);
4664
4664
 
4665
- if (code == NGX_ERROR) {
4665
+ if (code == NGX_ERROR || code > 999) {
4666
4666
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4667
4667
  "invalid code \"%*s\"",
4668
4668
  tf[i - 1].name.len - 1, tf[i - 1].name.data);
@@ -395,7 +395,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
395
395
  }
396
396
 
397
397
  } else {
398
- len += sizeof("Connection: closed" CRLF) - 1;
398
+ len += sizeof("Connection: close" CRLF) - 1;
399
399
  }
400
400
 
401
401
  #if (NGX_HTTP_GZIP)
@@ -445,7 +445,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
445
445
  b->last = ngx_copy(b->last, status_line->data, status_line->len);
446
446
 
447
447
  } else {
448
- b->last = ngx_sprintf(b->last, "%ui", status);
448
+ b->last = ngx_sprintf(b->last, "%03ui", status);
449
449
  }
450
450
  *b->last++ = CR; *b->last++ = LF;
451
451
 
@@ -138,7 +138,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
138
138
  { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
139
139
  ngx_http_process_header_line },
140
140
 
141
- #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
141
+ #if (NGX_HTTP_X_FORWARDED_FOR)
142
142
  { ngx_string("X-Forwarded-For"),
143
143
  offsetof(ngx_http_headers_in_t, x_forwarded_for),
144
144
  ngx_http_process_header_line },
@@ -137,6 +137,13 @@
137
137
  #define NGX_HTTP_COPY_BUFFERED 0x04
138
138
 
139
139
 
140
+ #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
141
+ #ifndef NGX_HTTP_X_FORWARDED_FOR
142
+ #define NGX_HTTP_X_FORWARDED_FOR 1
143
+ #endif
144
+ #endif
145
+
146
+
140
147
  typedef enum {
141
148
  NGX_HTTP_INITING_REQUEST_STATE = 0,
142
149
  NGX_HTTP_READING_REQUEST_STATE,
@@ -192,7 +199,7 @@ typedef struct {
192
199
 
193
200
  ngx_table_elt_t *keep_alive;
194
201
 
195
- #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
202
+ #if (NGX_HTTP_X_FORWARDED_FOR)
196
203
  ngx_table_elt_t *x_forwarded_for;
197
204
  #endif
198
205
 
@@ -3677,6 +3677,7 @@ static ngx_int_t
3677
3677
  ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
3678
3678
  ngx_uint_t offset)
3679
3679
  {
3680
+ ngx_int_t rc;
3680
3681
  ngx_table_elt_t *ho;
3681
3682
 
3682
3683
  ho = ngx_list_push(&r->headers_out.headers);
@@ -3687,7 +3688,20 @@ ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
3687
3688
  *ho = *h;
3688
3689
 
3689
3690
  if (r->upstream->rewrite_cookie) {
3690
- return r->upstream->rewrite_cookie(r, ho);
3691
+ rc = r->upstream->rewrite_cookie(r, ho);
3692
+
3693
+ if (rc == NGX_DECLINED) {
3694
+ return NGX_OK;
3695
+ }
3696
+
3697
+ #if (NGX_DEBUG)
3698
+ if (rc == NGX_OK) {
3699
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3700
+ "rewritten cookie: \"%V\"", &ho->value);
3701
+ }
3702
+ #endif
3703
+
3704
+ return rc;
3691
3705
  }
3692
3706
 
3693
3707
  return NGX_OK;
@@ -30,7 +30,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
30
30
  ngx_http_upstream_srv_conf_t *us)
31
31
  {
32
32
  ngx_url_t u;
33
- ngx_uint_t i, j, n;
33
+ ngx_uint_t i, j, n, w;
34
34
  ngx_http_upstream_server_t *server;
35
35
  ngx_http_upstream_rr_peers_t *peers, *backup;
36
36
 
@@ -40,6 +40,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
40
40
  server = us->servers->elts;
41
41
 
42
42
  n = 0;
43
+ w = 0;
43
44
 
44
45
  for (i = 0; i < us->servers->nelts; i++) {
45
46
  if (server[i].backup) {
@@ -47,6 +48,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
47
48
  }
48
49
 
49
50
  n += server[i].naddrs;
51
+ w += server[i].naddrs * server[i].weight;
50
52
  }
51
53
 
52
54
  if (n == 0) {
@@ -64,6 +66,8 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
64
66
 
65
67
  peers->single = (n == 1);
66
68
  peers->number = n;
69
+ peers->weighted = (w != n);
70
+ peers->total_weight = w;
67
71
  peers->name = &us->host;
68
72
 
69
73
  n = 0;
@@ -96,6 +100,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
96
100
  /* backup servers */
97
101
 
98
102
  n = 0;
103
+ w = 0;
99
104
 
100
105
  for (i = 0; i < us->servers->nelts; i++) {
101
106
  if (!server[i].backup) {
@@ -103,6 +108,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
103
108
  }
104
109
 
105
110
  n += server[i].naddrs;
111
+ w += server[i].naddrs * server[i].weight;
106
112
  }
107
113
 
108
114
  if (n == 0) {
@@ -118,6 +124,8 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
118
124
  peers->single = 0;
119
125
  backup->single = 0;
120
126
  backup->number = n;
127
+ backup->weighted = (w != n);
128
+ backup->total_weight = w;
121
129
  backup->name = &us->host;
122
130
 
123
131
  n = 0;
@@ -185,6 +193,8 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
185
193
 
186
194
  peers->single = (n == 1);
187
195
  peers->number = n;
196
+ peers->weighted = 0;
197
+ peers->total_weight = n;
188
198
  peers->name = &us->host;
189
199
 
190
200
  for (i = 0; i < u.naddrs; i++) {
@@ -41,13 +41,17 @@ typedef struct {
41
41
  typedef struct ngx_http_upstream_rr_peers_s ngx_http_upstream_rr_peers_t;
42
42
 
43
43
  struct ngx_http_upstream_rr_peers_s {
44
- ngx_uint_t single; /* unsigned single:1; */
45
44
  ngx_uint_t number;
46
45
  ngx_uint_t last_cached;
47
46
 
48
47
  /* ngx_mutex_t *mutex; */
49
48
  ngx_connection_t **cached;
50
49
 
50
+ ngx_uint_t total_weight;
51
+
52
+ unsigned single:1;
53
+ unsigned weighted:1;
54
+
51
55
  ngx_str_t *name;
52
56
 
53
57
  ngx_http_upstream_rr_peers_t *next;