nginxtra 1.2.1.3 → 1.2.2.3

Sign up to get free protection for your applications and to get access to all the features.
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;