nginxtra 1.4.7.9 → 1.6.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +286 -19
  6. data/vendor/nginx/CHANGES.ru +296 -22
  7. data/vendor/nginx/auto/cc/clang +4 -3
  8. data/vendor/nginx/auto/cc/conf +23 -0
  9. data/vendor/nginx/auto/cc/msvc +1 -0
  10. data/vendor/nginx/auto/cc/name +1 -1
  11. data/vendor/nginx/auto/cc/owc +4 -4
  12. data/vendor/nginx/auto/cc/sunc +1 -1
  13. data/vendor/nginx/auto/endianness +2 -2
  14. data/vendor/nginx/auto/feature +1 -1
  15. data/vendor/nginx/auto/include +1 -1
  16. data/vendor/nginx/auto/lib/libatomic/make +3 -1
  17. data/vendor/nginx/auto/lib/openssl/conf +4 -0
  18. data/vendor/nginx/auto/lib/openssl/make +1 -1
  19. data/vendor/nginx/auto/lib/pcre/conf +5 -0
  20. data/vendor/nginx/auto/lib/pcre/make +11 -11
  21. data/vendor/nginx/auto/lib/pcre/makefile.bcc +4 -3
  22. data/vendor/nginx/auto/lib/pcre/makefile.msvc +2 -1
  23. data/vendor/nginx/auto/lib/pcre/makefile.owc +2 -1
  24. data/vendor/nginx/auto/lib/perl/make +1 -0
  25. data/vendor/nginx/auto/lib/test +1 -1
  26. data/vendor/nginx/auto/lib/zlib/make +22 -1
  27. data/vendor/nginx/auto/modules +8 -0
  28. data/vendor/nginx/auto/options +3 -0
  29. data/vendor/nginx/auto/os/darwin +1 -1
  30. data/vendor/nginx/auto/os/linux +32 -0
  31. data/vendor/nginx/auto/os/win32 +12 -1
  32. data/vendor/nginx/auto/sources +8 -2
  33. data/vendor/nginx/auto/types/sizeof +1 -1
  34. data/vendor/nginx/auto/types/typedef +1 -1
  35. data/vendor/nginx/auto/types/uintptr_t +1 -1
  36. data/vendor/nginx/auto/unix +13 -1
  37. data/vendor/nginx/conf/mime.types +11 -2
  38. data/vendor/nginx/conf/nginx.conf +3 -4
  39. data/vendor/nginx/contrib/README +6 -0
  40. data/vendor/nginx/contrib/vim/ftdetect/nginx.vim +4 -0
  41. data/vendor/nginx/contrib/vim/indent/nginx.vim +11 -0
  42. data/vendor/nginx/contrib/vim/syntax/nginx.vim +703 -0
  43. data/vendor/nginx/src/core/nginx.c +2 -7
  44. data/vendor/nginx/src/core/nginx.h +2 -2
  45. data/vendor/nginx/src/core/ngx_conf_file.c +8 -88
  46. data/vendor/nginx/src/core/ngx_conf_file.h +3 -3
  47. data/vendor/nginx/src/core/ngx_config.h +2 -2
  48. data/vendor/nginx/src/core/ngx_connection.c +100 -29
  49. data/vendor/nginx/src/core/ngx_connection.h +11 -0
  50. data/vendor/nginx/src/core/ngx_core.h +1 -0
  51. data/vendor/nginx/src/core/ngx_cycle.c +23 -99
  52. data/vendor/nginx/src/core/ngx_cycle.h +2 -0
  53. data/vendor/nginx/src/core/ngx_file.c +100 -8
  54. data/vendor/nginx/src/core/ngx_file.h +3 -0
  55. data/vendor/nginx/src/core/ngx_hash.c +6 -9
  56. data/vendor/nginx/src/core/ngx_inet.c +93 -5
  57. data/vendor/nginx/src/core/ngx_inet.h +4 -2
  58. data/vendor/nginx/src/core/ngx_list.c +1 -9
  59. data/vendor/nginx/src/core/ngx_log.c +132 -30
  60. data/vendor/nginx/src/core/ngx_log.h +5 -2
  61. data/vendor/nginx/src/core/ngx_open_file_cache.c +67 -1
  62. data/vendor/nginx/src/core/ngx_palloc.c +5 -2
  63. data/vendor/nginx/src/core/ngx_proxy_protocol.c +91 -0
  64. data/vendor/nginx/src/core/ngx_proxy_protocol.h +23 -0
  65. data/vendor/nginx/src/core/ngx_resolver.c +1080 -285
  66. data/vendor/nginx/src/core/ngx_resolver.h +33 -3
  67. data/vendor/nginx/src/core/ngx_slab.c +7 -2
  68. data/vendor/nginx/src/core/ngx_slab.h +2 -0
  69. data/vendor/nginx/src/core/ngx_string.c +78 -13
  70. data/vendor/nginx/src/core/ngx_string.h +2 -0
  71. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +2 -2
  72. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +13 -5
  73. data/vendor/nginx/src/event/modules/ngx_select_module.c +1 -1
  74. data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +2 -2
  75. data/vendor/nginx/src/event/ngx_event.c +0 -1
  76. data/vendor/nginx/src/event/ngx_event.h +7 -6
  77. data/vendor/nginx/src/event/ngx_event_accept.c +6 -4
  78. data/vendor/nginx/src/event/ngx_event_connect.c +2 -2
  79. data/vendor/nginx/src/event/ngx_event_openssl.c +304 -13
  80. data/vendor/nginx/src/event/ngx_event_openssl.h +20 -1
  81. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +35 -23
  82. data/vendor/nginx/src/event/ngx_event_pipe.c +15 -30
  83. data/vendor/nginx/src/http/modules/ngx_http_access_module.c +115 -35
  84. data/vendor/nginx/src/http/modules/ngx_http_auth_basic_module.c +1 -1
  85. data/vendor/nginx/src/http/modules/ngx_http_auth_request_module.c +444 -0
  86. data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +2 -1
  87. data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +1 -1
  88. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +1 -3
  89. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +251 -36
  90. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -5
  91. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +5 -3
  92. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +1 -1
  93. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +4 -0
  94. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +8 -2
  95. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +5 -1
  96. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +3 -3
  97. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +21 -10
  98. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +669 -197
  99. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +93 -60
  100. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +13 -6
  101. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +20 -1
  102. data/vendor/nginx/src/http/modules/ngx_http_referer_module.c +132 -74
  103. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +18 -12
  104. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +22 -20
  105. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +121 -3
  106. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +5 -0
  107. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +3 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +123 -91
  109. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +29 -19
  110. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +2 -5
  111. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +215 -19
  112. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +32 -6
  113. data/vendor/nginx/src/http/modules/perl/nginx.xs +4 -7
  114. data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -2
  115. data/vendor/nginx/src/http/ngx_http.c +17 -7
  116. data/vendor/nginx/src/http/ngx_http_cache.h +4 -2
  117. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +4 -2
  118. data/vendor/nginx/src/http/ngx_http_core_module.c +63 -50
  119. data/vendor/nginx/src/http/ngx_http_core_module.h +5 -0
  120. data/vendor/nginx/src/http/ngx_http_file_cache.c +115 -3
  121. data/vendor/nginx/src/http/ngx_http_header_filter_module.c +9 -6
  122. data/vendor/nginx/src/http/ngx_http_parse.c +88 -10
  123. data/vendor/nginx/src/http/ngx_http_postpone_filter_module.c +2 -4
  124. data/vendor/nginx/src/http/ngx_http_request.c +116 -8
  125. data/vendor/nginx/src/http/ngx_http_request.h +5 -1
  126. data/vendor/nginx/src/http/ngx_http_request_body.c +7 -7
  127. data/vendor/nginx/src/http/ngx_http_script.c +6 -5
  128. data/vendor/nginx/src/http/ngx_http_spdy.c +889 -271
  129. data/vendor/nginx/src/http/ngx_http_spdy.h +51 -28
  130. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +382 -167
  131. data/vendor/nginx/src/http/ngx_http_spdy_module.c +65 -8
  132. data/vendor/nginx/src/http/ngx_http_spdy_module.h +5 -0
  133. data/vendor/nginx/src/http/ngx_http_special_response.c +1 -1
  134. data/vendor/nginx/src/http/ngx_http_upstream.c +290 -114
  135. data/vendor/nginx/src/http/ngx_http_upstream.h +9 -5
  136. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +32 -24
  137. data/vendor/nginx/src/http/ngx_http_variables.c +40 -6
  138. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +12 -5
  139. data/vendor/nginx/src/mail/ngx_mail.c +4 -2
  140. data/vendor/nginx/src/mail/ngx_mail.h +2 -0
  141. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +0 -1
  142. data/vendor/nginx/src/mail/ngx_mail_core_module.c +2 -1
  143. data/vendor/nginx/src/mail/ngx_mail_handler.c +17 -4
  144. data/vendor/nginx/src/mail/ngx_mail_parse.c +32 -2
  145. data/vendor/nginx/src/mail/ngx_mail_proxy_module.c +54 -7
  146. data/vendor/nginx/src/mail/ngx_mail_smtp_handler.c +50 -78
  147. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +48 -11
  148. data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +3 -0
  149. data/vendor/nginx/src/os/unix/ngx_channel.c +3 -1
  150. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +1 -0
  151. data/vendor/nginx/src/os/unix/ngx_darwin_init.c +1 -1
  152. data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +14 -16
  153. data/vendor/nginx/src/os/unix/ngx_errno.h +3 -0
  154. data/vendor/nginx/src/os/unix/ngx_files.h +10 -16
  155. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +6 -0
  156. data/vendor/nginx/src/os/unix/ngx_freebsd_init.c +1 -1
  157. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +1 -1
  158. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +2 -2
  159. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +17 -19
  160. data/vendor/nginx/src/os/unix/ngx_linux_config.h +8 -2
  161. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +20 -22
  162. data/vendor/nginx/src/os/unix/ngx_posix_config.h +1 -0
  163. data/vendor/nginx/src/os/unix/ngx_process.c +5 -0
  164. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +15 -3
  165. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +2 -1
  166. data/vendor/nginx/src/os/unix/ngx_recv.c +4 -1
  167. data/vendor/nginx/src/os/unix/ngx_solaris_config.h +1 -0
  168. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +14 -16
  169. metadata +8 -2
@@ -174,7 +174,8 @@ ngx_inet6_addr(u_char *p, size_t len, u_char *addr)
174
174
 
175
175
 
176
176
  size_t
177
- ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
177
+ ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, size_t len,
178
+ ngx_uint_t port)
178
179
  {
179
180
  u_char *p;
180
181
  struct sockaddr_in *sin;
@@ -230,9 +231,18 @@ ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
230
231
  case AF_UNIX:
231
232
  saun = (struct sockaddr_un *) sa;
232
233
 
234
+ /* on Linux sockaddr might not include sun_path at all */
235
+
236
+ if (socklen <= (socklen_t) offsetof(struct sockaddr_un, sun_path)) {
237
+ p = ngx_snprintf(text, len, "unix:%Z");
238
+
239
+ } else {
240
+ p = ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path);
241
+ }
242
+
233
243
  /* we do not include trailing zero in address length */
234
244
 
235
- return ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path) - text - 1;
245
+ return (p - text - 1);
236
246
 
237
247
  #endif
238
248
 
@@ -953,6 +963,9 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
953
963
  ngx_memzero(&hints, sizeof(struct addrinfo));
954
964
  hints.ai_family = AF_UNSPEC;
955
965
  hints.ai_socktype = SOCK_STREAM;
966
+ #ifdef AI_ADDRCONFIG
967
+ hints.ai_flags = AI_ADDRCONFIG;
968
+ #endif
956
969
 
957
970
  if (getaddrinfo((char *) host, NULL, &hints, &res) != 0) {
958
971
  u->err = "host not found";
@@ -1020,7 +1033,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
1020
1033
  goto failed;
1021
1034
  }
1022
1035
 
1023
- len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
1036
+ len = ngx_sock_ntop((struct sockaddr *) sin, rp->ai_addrlen, p, len, 1);
1024
1037
 
1025
1038
  u->addrs[i].name.len = len;
1026
1039
  u->addrs[i].name.data = p;
@@ -1053,7 +1066,8 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
1053
1066
  goto failed;
1054
1067
  }
1055
1068
 
1056
- len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1);
1069
+ len = ngx_sock_ntop((struct sockaddr *) sin6, rp->ai_addrlen, p,
1070
+ len, 1);
1057
1071
 
1058
1072
  u->addrs[i].name.len = len;
1059
1073
  u->addrs[i].name.data = p;
@@ -1138,7 +1152,8 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
1138
1152
  return NGX_ERROR;
1139
1153
  }
1140
1154
 
1141
- len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
1155
+ len = ngx_sock_ntop((struct sockaddr *) sin,
1156
+ sizeof(struct sockaddr_in), p, len, 1);
1142
1157
 
1143
1158
  u->addrs[i].name.len = len;
1144
1159
  u->addrs[i].name.data = p;
@@ -1181,3 +1196,76 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
1181
1196
  }
1182
1197
 
1183
1198
  #endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
1199
+
1200
+
1201
+ ngx_int_t
1202
+ ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
1203
+ struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port)
1204
+ {
1205
+ struct sockaddr_in *sin1, *sin2;
1206
+ #if (NGX_HAVE_INET6)
1207
+ struct sockaddr_in6 *sin61, *sin62;
1208
+ #endif
1209
+ #if (NGX_HAVE_UNIX_DOMAIN)
1210
+ struct sockaddr_un *saun1, *saun2;
1211
+ #endif
1212
+
1213
+ if (sa1->sa_family != sa2->sa_family) {
1214
+ return NGX_DECLINED;
1215
+ }
1216
+
1217
+ switch (sa1->sa_family) {
1218
+
1219
+ #if (NGX_HAVE_INET6)
1220
+ case AF_INET6:
1221
+
1222
+ sin61 = (struct sockaddr_in6 *) sa1;
1223
+ sin62 = (struct sockaddr_in6 *) sa2;
1224
+
1225
+ if (cmp_port && sin61->sin6_port != sin62->sin6_port) {
1226
+ return NGX_DECLINED;
1227
+ }
1228
+
1229
+ if (ngx_memcmp(&sin61->sin6_addr, &sin62->sin6_addr, 16) != 0) {
1230
+ return NGX_DECLINED;
1231
+ }
1232
+
1233
+ break;
1234
+ #endif
1235
+
1236
+ #if (NGX_HAVE_UNIX_DOMAIN)
1237
+ case AF_UNIX:
1238
+
1239
+ /* TODO length */
1240
+
1241
+ saun1 = (struct sockaddr_un *) sa1;
1242
+ saun2 = (struct sockaddr_un *) sa2;
1243
+
1244
+ if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path,
1245
+ sizeof(saun1->sun_path))
1246
+ != 0)
1247
+ {
1248
+ return NGX_DECLINED;
1249
+ }
1250
+
1251
+ break;
1252
+ #endif
1253
+
1254
+ default: /* AF_INET */
1255
+
1256
+ sin1 = (struct sockaddr_in *) sa1;
1257
+ sin2 = (struct sockaddr_in *) sa2;
1258
+
1259
+ if (cmp_port && sin1->sin_port != sin2->sin_port) {
1260
+ return NGX_DECLINED;
1261
+ }
1262
+
1263
+ if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
1264
+ return NGX_DECLINED;
1265
+ }
1266
+
1267
+ break;
1268
+ }
1269
+
1270
+ return NGX_OK;
1271
+ }
@@ -107,14 +107,16 @@ in_addr_t ngx_inet_addr(u_char *text, size_t len);
107
107
  ngx_int_t ngx_inet6_addr(u_char *p, size_t len, u_char *addr);
108
108
  size_t ngx_inet6_ntop(u_char *p, u_char *text, size_t len);
109
109
  #endif
110
- size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,
111
- ngx_uint_t port);
110
+ size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text,
111
+ size_t len, ngx_uint_t port);
112
112
  size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
113
113
  ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
114
114
  ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
115
115
  size_t len);
116
116
  ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
117
117
  ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
118
+ ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
119
+ struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port);
118
120
 
119
121
 
120
122
  #endif /* _NGX_INET_H_INCLUDED_ */
@@ -19,18 +19,10 @@ ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
19
19
  return NULL;
20
20
  }
21
21
 
22
- list->part.elts = ngx_palloc(pool, n * size);
23
- if (list->part.elts == NULL) {
22
+ if (ngx_list_init(list, pool, n, size) != NGX_OK) {
24
23
  return NULL;
25
24
  }
26
25
 
27
- list->part.nelts = 0;
28
- list->part.next = NULL;
29
- list->last = &list->part;
30
- list->size = size;
31
- list->nalloc = n;
32
- list->pool = pool;
33
-
34
26
  return list;
35
27
  }
36
28
 
@@ -10,6 +10,8 @@
10
10
 
11
11
 
12
12
  static char *ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
13
+ static char *ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log);
14
+ static void ngx_log_insert(ngx_log_t *log, ngx_log_t *new_log);
13
15
 
14
16
 
15
17
  static ngx_command_t ngx_errlog_commands[] = {
@@ -86,14 +88,11 @@ ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
86
88
  #endif
87
89
  {
88
90
  #if (NGX_HAVE_VARIADIC_MACROS)
89
- va_list args;
91
+ va_list args;
90
92
  #endif
91
- u_char *p, *last, *msg;
92
- u_char errstr[NGX_MAX_ERROR_STR];
93
-
94
- if (log->file->fd == NGX_INVALID_FILE) {
95
- return;
96
- }
93
+ u_char *p, *last, *msg;
94
+ u_char errstr[NGX_MAX_ERROR_STR];
95
+ ngx_uint_t wrote_stderr, debug_connection;
97
96
 
98
97
  last = errstr + NGX_MAX_ERROR_STR;
99
98
 
@@ -140,11 +139,27 @@ ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
140
139
 
141
140
  ngx_linefeed(p);
142
141
 
143
- (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
142
+ wrote_stderr = 0;
143
+ debug_connection = (log->log_level & NGX_LOG_DEBUG_CONNECTION) != 0;
144
+
145
+ while (log) {
146
+
147
+ if (log->log_level < level && !debug_connection) {
148
+ break;
149
+ }
150
+
151
+ (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
152
+
153
+ if (log->file->fd == ngx_stderr) {
154
+ wrote_stderr = 1;
155
+ }
156
+
157
+ log = log->next;
158
+ }
144
159
 
145
160
  if (!ngx_use_stderr
146
161
  || level > NGX_LOG_WARN
147
- || log->file->fd == ngx_stderr)
162
+ || wrote_stderr)
148
163
  {
149
164
  return;
150
165
  }
@@ -348,31 +363,59 @@ ngx_log_init(u_char *prefix)
348
363
  }
349
364
 
350
365
 
351
- ngx_log_t *
352
- ngx_log_create(ngx_cycle_t *cycle, ngx_str_t *name)
366
+ ngx_int_t
367
+ ngx_log_open_default(ngx_cycle_t *cycle)
368
+ {
369
+ static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH);
370
+
371
+ if (cycle->new_log.file == NULL) {
372
+ cycle->new_log.file = ngx_conf_open_file(cycle, &error_log);
373
+ if (cycle->new_log.file == NULL) {
374
+ return NGX_ERROR;
375
+ }
376
+
377
+ cycle->new_log.log_level = NGX_LOG_ERR;
378
+ }
379
+
380
+ return NGX_OK;
381
+ }
382
+
383
+
384
+ ngx_int_t
385
+ ngx_log_redirect_stderr(ngx_cycle_t *cycle)
353
386
  {
354
- ngx_log_t *log;
387
+ ngx_fd_t fd;
355
388
 
356
- log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
357
- if (log == NULL) {
358
- return NULL;
389
+ if (cycle->log_use_stderr) {
390
+ return NGX_OK;
359
391
  }
360
392
 
361
- log->file = ngx_conf_open_file(cycle, name);
362
- if (log->file == NULL) {
363
- return NULL;
393
+ fd = cycle->log->file->fd;
394
+
395
+ if (fd != ngx_stderr) {
396
+ if (ngx_set_stderr(fd) == NGX_FILE_ERROR) {
397
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
398
+ ngx_set_stderr_n " failed");
399
+
400
+ return NGX_ERROR;
401
+ }
364
402
  }
365
403
 
366
- return log;
404
+ return NGX_OK;
367
405
  }
368
406
 
369
407
 
370
- char *
408
+ static char *
371
409
  ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
372
410
  {
373
411
  ngx_uint_t i, n, d, found;
374
412
  ngx_str_t *value;
375
413
 
414
+ if (cf->args->nelts == 2) {
415
+ log->log_level = NGX_LOG_ERR;
416
+ return NGX_CONF_OK;
417
+ }
418
+
376
419
  value = cf->args->elts;
377
420
 
378
421
  for (i = 2; i < cf->args->nelts; i++) {
@@ -428,32 +471,91 @@ ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
428
471
  static char *
429
472
  ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
430
473
  {
474
+ ngx_log_t *dummy;
475
+
476
+ dummy = &cf->cycle->new_log;
477
+
478
+ return ngx_log_set_log(cf, &dummy);
479
+ }
480
+
481
+
482
+ char *
483
+ ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head)
484
+ {
485
+ ngx_log_t *new_log;
431
486
  ngx_str_t *value, name;
432
487
 
433
- if (cf->cycle->new_log.file) {
434
- return "is duplicate";
488
+ if (*head != NULL && (*head)->log_level == 0) {
489
+ new_log = *head;
490
+
491
+ } else {
492
+
493
+ new_log = ngx_pcalloc(cf->pool, sizeof(ngx_log_t));
494
+ if (new_log == NULL) {
495
+ return NGX_CONF_ERROR;
496
+ }
497
+
498
+ if (*head == NULL) {
499
+ *head = new_log;
500
+ }
435
501
  }
436
502
 
437
503
  value = cf->args->elts;
438
504
 
439
505
  if (ngx_strcmp(value[1].data, "stderr") == 0) {
440
506
  ngx_str_null(&name);
507
+ cf->cycle->log_use_stderr = 1;
441
508
 
442
509
  } else {
443
510
  name = value[1];
444
511
  }
445
512
 
446
- cf->cycle->new_log.file = ngx_conf_open_file(cf->cycle, &name);
447
- if (cf->cycle->new_log.file == NULL) {
448
- return NULL;
513
+ new_log->file = ngx_conf_open_file(cf->cycle, &name);
514
+ if (new_log->file == NULL) {
515
+ return NGX_CONF_ERROR;
449
516
  }
450
517
 
451
- if (cf->args->nelts == 2) {
452
- cf->cycle->new_log.log_level = NGX_LOG_ERR;
453
- return NGX_CONF_OK;
518
+ if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) {
519
+ return NGX_CONF_ERROR;
520
+ }
521
+
522
+ if (*head != new_log) {
523
+ ngx_log_insert(*head, new_log);
524
+ }
525
+
526
+ return NGX_CONF_OK;
527
+ }
528
+
529
+
530
+ static void
531
+ ngx_log_insert(ngx_log_t *log, ngx_log_t *new_log)
532
+ {
533
+ ngx_log_t tmp;
534
+
535
+ if (new_log->log_level > log->log_level) {
536
+
537
+ /*
538
+ * list head address is permanent, insert new log after
539
+ * head and swap its contents with head
540
+ */
541
+
542
+ tmp = *log;
543
+ *log = *new_log;
544
+ *new_log = tmp;
545
+
546
+ log->next = new_log;
547
+ return;
454
548
  }
455
549
 
456
- cf->cycle->new_log.log_level = 0;
550
+ while (log->next) {
551
+ if (new_log->log_level > log->next->log_level) {
552
+ new_log->next = log->next;
553
+ log->next = new_log;
554
+ return;
555
+ }
556
+
557
+ log = log->next;
558
+ }
457
559
 
458
- return ngx_log_set_levels(cf, &cf->cycle->new_log);
560
+ log->next = new_log;
459
561
  }
@@ -61,6 +61,8 @@ struct ngx_log_s {
61
61
  */
62
62
 
63
63
  char *action;
64
+
65
+ ngx_log_t *next;
64
66
  };
65
67
 
66
68
 
@@ -220,11 +222,12 @@ void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err,
220
222
  /*********************************/
221
223
 
222
224
  ngx_log_t *ngx_log_init(u_char *prefix);
223
- ngx_log_t *ngx_log_create(ngx_cycle_t *cycle, ngx_str_t *name);
224
- char *ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log);
225
225
  void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...);
226
226
  void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
227
227
  u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err);
228
+ ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle);
229
+ ngx_int_t ngx_log_redirect_stderr(ngx_cycle_t *cycle);
230
+ char *ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head);
228
231
 
229
232
 
230
233
  /*
@@ -25,6 +25,10 @@ static void ngx_open_file_cache_cleanup(void *data);
25
25
  #if (NGX_HAVE_OPENAT)
26
26
  static ngx_fd_t ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
27
27
  ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log);
28
+ #if (NGX_HAVE_O_PATH)
29
+ static ngx_int_t ngx_file_o_path_info(ngx_fd_t fd, ngx_file_info_t *fi,
30
+ ngx_log_t *log);
31
+ #endif
28
32
  #endif
29
33
  static ngx_fd_t ngx_open_file_wrapper(ngx_str_t *name,
30
34
  ngx_open_file_info_t *of, ngx_int_t mode, ngx_int_t create,
@@ -124,7 +128,7 @@ ngx_open_file_cache_cleanup(void *data)
124
128
 
125
129
  if (cache->current) {
126
130
  ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
127
- "%d items still leave in open file cache",
131
+ "%ui items still leave in open file cache",
128
132
  cache->current);
129
133
  }
130
134
 
@@ -517,10 +521,17 @@ ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
517
521
  goto failed;
518
522
  }
519
523
 
524
+ #if (NGX_HAVE_O_PATH)
525
+ if (ngx_file_o_path_info(fd, &fi, log) == NGX_ERROR) {
526
+ err = ngx_errno;
527
+ goto failed;
528
+ }
529
+ #else
520
530
  if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
521
531
  err = ngx_errno;
522
532
  goto failed;
523
533
  }
534
+ #endif
524
535
 
525
536
  if (fi.st_uid != atfi.st_uid) {
526
537
  err = NGX_ELOOP;
@@ -541,8 +552,63 @@ failed:
541
552
  return NGX_INVALID_FILE;
542
553
  }
543
554
 
555
+
556
+ #if (NGX_HAVE_O_PATH)
557
+
558
+ static ngx_int_t
559
+ ngx_file_o_path_info(ngx_fd_t fd, ngx_file_info_t *fi, ngx_log_t *log)
560
+ {
561
+ static ngx_uint_t use_fstat = 1;
562
+
563
+ /*
564
+ * In Linux 2.6.39 the O_PATH flag was introduced that allows to obtain
565
+ * a descriptor without actually opening file or directory. It requires
566
+ * less permissions for path components, but till Linux 3.6 fstat() returns
567
+ * EBADF on such descriptors, and fstatat() with the AT_EMPTY_PATH flag
568
+ * should be used instead.
569
+ *
570
+ * Three scenarios are handled in this function:
571
+ *
572
+ * 1) The kernel is newer than 3.6 or fstat() with O_PATH support was
573
+ * backported by vendor. Then fstat() is used.
574
+ *
575
+ * 2) The kernel is newer than 2.6.39 but older than 3.6. In this case
576
+ * the first call of fstat() returns EBADF and we fallback to fstatat()
577
+ * with AT_EMPTY_PATH which was introduced at the same time as O_PATH.
578
+ *
579
+ * 3) The kernel is older than 2.6.39 but nginx was build with O_PATH
580
+ * support. Since descriptors are opened with O_PATH|O_RDONLY flags
581
+ * and O_PATH is ignored by the kernel then the O_RDONLY flag is
582
+ * actually used. In this case fstat() just works.
583
+ */
584
+
585
+ if (use_fstat) {
586
+ if (ngx_fd_info(fd, fi) != NGX_FILE_ERROR) {
587
+ return NGX_OK;
588
+ }
589
+
590
+ if (ngx_errno != NGX_EBADF) {
591
+ return NGX_ERROR;
592
+ }
593
+
594
+ ngx_log_error(NGX_LOG_NOTICE, log, 0,
595
+ "fstat(O_PATH) failed with EBADF, "
596
+ "switching to fstatat(AT_EMPTY_PATH)");
597
+
598
+ use_fstat = 0;
599
+ }
600
+
601
+ if (ngx_file_at_info(fd, "", fi, AT_EMPTY_PATH) != NGX_FILE_ERROR) {
602
+ return NGX_OK;
603
+ }
604
+
605
+ return NGX_ERROR;
606
+ }
607
+
544
608
  #endif
545
609
 
610
+ #endif /* NGX_HAVE_OPENAT */
611
+
546
612
 
547
613
  static ngx_fd_t
548
614
  ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,