diff src/http/v2/ngx_http_v2_filter_module.c @ 6432:cf3e75cfa951

Added variables support to server_tokens. It can now be set to "off" conditionally, e.g. using the map directive. An empty value will disable the emission of the Server: header and the signature in error messages generated by nginx. Any other value is treated as "on", meaning that full nginx version is emitted in the Server: header and error messages generated by nginx.
author Ruslan Ermilov <ru@nginx.com>
date Tue, 15 Mar 2016 13:36:19 +0300
parents 4ba91a4c66a3
children 602dc42035fe
line wrap: on
line diff
--- a/src/http/v2/ngx_http_v2_filter_module.c
+++ b/src/http/v2/ngx_http_v2_filter_module.c
@@ -128,8 +128,8 @@ ngx_http_v2_header_filter(ngx_http_reque
 {
     u_char                     status, *pos, *start, *p, *tmp;
     size_t                     len, tmp_len;
-    ngx_str_t                  host, location;
-    ngx_uint_t                 i, port;
+    ngx_str_t                  host, location, tokens;
+    ngx_uint_t                 i, port, server_tokens;
     ngx_list_part_t           *part;
     ngx_table_elt_t           *header;
     ngx_connection_t          *fc;
@@ -229,8 +229,38 @@ ngx_http_v2_header_filter(ngx_http_reque
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
+    server_tokens = clcf->server_tokens;
+
     if (r->headers_out.server == NULL) {
-        len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx));
+
+        if (server_tokens == 0) {
+            len += 1 + sizeof(nginx);
+            ngx_str_set(&tokens, "nginx");
+
+        } else if (server_tokens == 1) {
+            len += 1 + nginx_ver_len;
+            ngx_str_set(&tokens, NGINX_VER);
+
+        } else {
+            if (ngx_http_complex_value(r, &clcf->server_tokens_value, &tokens)
+                != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
+            if (tokens.len == 3
+                && ngx_strncmp(tokens.data, "off", 3) == 0)
+            {
+                server_tokens = 0;
+                len += 1 + sizeof(nginx);
+                ngx_str_set(&tokens, "nginx");
+
+            } else if (tokens.len) {
+                server_tokens = 1;
+                len += 1 + nginx_ver_len;
+                ngx_str_set(&tokens, NGINX_VER);
+            }
+        }
     }
 
     if (r->headers_out.date == NULL) {
@@ -434,14 +464,17 @@ ngx_http_v2_header_filter(ngx_http_reque
         pos = ngx_sprintf(pos, "%03ui", r->headers_out.status);
     }
 
-    if (r->headers_out.server == NULL) {
+    if (r->headers_out.server == NULL && tokens.len) {
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
-                       "http2 output header: \"server: %s\"",
-                       clcf->server_tokens ? NGINX_VER : "nginx");
+                       "http2 output header: \"server: %V\"",
+                       &tokens);
 
         *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX);
 
-        if (clcf->server_tokens) {
+        if (server_tokens == 0) {
+            pos = ngx_cpymem(pos, nginx, sizeof(nginx));
+
+        } else {
             if (nginx_ver[0] == '\0') {
                 p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER,
                                             sizeof(NGINX_VER) - 1, tmp);
@@ -449,9 +482,6 @@ ngx_http_v2_header_filter(ngx_http_reque
             }
 
             pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len);
-
-        } else {
-            pos = ngx_cpymem(pos, nginx, sizeof(nginx));
         }
     }