From b21c20b5ff5bdeb17946504db9174bd196831237 Mon Sep 17 00:00:00 2001
From: Andy Green <andy@warmcat.com>
Date: Fri, 15 Apr 2016 13:33:52 +0800
Subject: [PATCH] context settable server string

Signed-off-by: Andy Green <andy@warmcat.com>
---
 README.lwsws.md             |  2 ++
 lib/context.c               |  8 ++++++++
 lib/header.c                | 33 ++++++++++++++++++++-------------
 lib/libwebsockets.h         |  1 +
 lib/private-libwebsockets.h |  2 ++
 lwsws/conf.c                |  5 +++++
 6 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/README.lwsws.md b/README.lwsws.md
index aaa451e1..6b821271 100644
--- a/README.lwsws.md
+++ b/README.lwsws.md
@@ -31,6 +31,7 @@ There is a single file intended for global settings
    "uid": "48",  # apache user
    "gid": "48",  # apache user
    "count-threads": "1",
+   "server-string": "myserver v1", # returned in http headers
    "init-ssl": "yes"
  }
 }
@@ -169,6 +170,7 @@ Other vhost options
 
  - "`access-log`": "filepath"   sets where apache-compatible access logs will be written
 
+
 Mounts
 ------
 
diff --git a/lib/context.c b/lib/context.c
index 33d661a9..82389645 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -605,6 +605,14 @@ lws_create_context(struct lws_context_creation_info *info)
 	}
 	lwsl_info(" mem: pollfd map:      %5u\n", n);
 
+	if (info->server_string) {
+		context->server_string = info->server_string;
+		context->server_string_len = strlen(context->server_string);
+	} else {
+		context->server_string = "libwebsockets";
+		context->server_string_len = 13;
+	}
+
 #if LWS_MAX_SMP > 1
 	/* each thread serves his own chunk of fds */
 	for (n = 1; n < (int)info->count_threads; n++)
diff --git a/lib/header.c b/lib/header.c
index 55700d19..457f544a 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -178,8 +178,25 @@ lws_add_http_header_status(struct lws *wsi, unsigned int code,
 	n = sprintf((char *)code_and_desc, "%s %u %s",
 		    p1, code, description);
 
-	return lws_add_http_header_by_name(wsi, NULL, code_and_desc,
-					   n, p, end);
+	if (lws_add_http_header_by_name(wsi, NULL, code_and_desc,
+					   n, p, end))
+		return 1;
+
+	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER,
+					 (unsigned char *)
+					 	 wsi->context->server_string,
+					 wsi->context->server_string_len,
+					 p, end))
+		return 1;
+
+	if (wsi->vhost->options & LWS_SERVER_OPTION_STS)
+		if (lws_add_http_header_by_name(wsi, (unsigned char *)
+				"Strict-Transport-Security:",
+				(unsigned char *)"max-age=15768000 ; "
+				"includeSubDomains", 36, p, end))
+			return 1;
+
+	return 0;
 }
 
 /**
@@ -211,10 +228,7 @@ lws_return_http_status(struct lws *wsi, unsigned int code,
 
 	if (lws_add_http_header_status(wsi, code, &p, end))
 		return 1;
-	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER,
-					 (unsigned char *)"libwebsockets", 13,
-					 &p, end))
-		return 1;
+
 	if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
 					 (unsigned char *)"text/html", 9,
 					 &p, end))
@@ -225,13 +239,6 @@ lws_return_http_status(struct lws *wsi, unsigned int code,
 					 &p, end))
 		return 1;
 
-	if (wsi->vhost->options & LWS_SERVER_OPTION_STS)
-		if (lws_add_http_header_by_name(wsi, (unsigned char *)
-				"Strict-Transport-Security:",
-				(unsigned char *)"max-age=15768000 ; "
-				"includeSubDomains", 36, &p, end))
-			return 1;
-
 	if (lws_finalize_http_header(wsi, &p, end))
 		return 1;
 
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 5fd56c8c..0d90c55a 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -1477,6 +1477,7 @@ struct lws_context_creation_info {
 	struct lws_protocol_vhost_options *pvo;		/* VH */
 	int keepalive_timeout;				/* VH */
 	const char *log_filepath;			/* VH */
+	const char *server_string;			/* context */
 
 	/* Add new things just above here ---^
 	 * This is part of the ABI, don't needlessly break compatibility
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 5f1514c1..f00fb466 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -709,6 +709,7 @@ struct lws_context {
 	struct lws_plugin *plugin_list;
 	const struct lws_token_limits *token_limits;
 	void *user_space;
+	const char *server_string;
 
 #if defined(LWS_USE_LIBEV)
 	lws_ev_signal_cb_t * lws_ev_sigint_cb;
@@ -760,6 +761,7 @@ struct lws_context {
 	short count_threads;
 	short plugin_protocol_count;
 	short plugin_extension_count;
+	short server_string_len;
 
 	unsigned int being_destroyed:1;
 	unsigned int requested_kill:1;
diff --git a/lwsws/conf.c b/lwsws/conf.c
index 57324dc9..6a391951 100644
--- a/lwsws/conf.c
+++ b/lwsws/conf.c
@@ -26,6 +26,7 @@ static const char * const paths_global[] = {
 	"global.gid",
 	"global.count-threads",
 	"global.init-ssl",
+	"global.server-string",
 };
 
 enum lejp_global_paths {
@@ -33,6 +34,7 @@ enum lejp_global_paths {
 	LEJPGP_GID,
 	LEJPGP_COUNT_THREADS,
 	LWJPGP_INIT_SSL,
+	LEJPGP_SERVER_STRING,
 };
 
 static const char * const paths_vhosts[] = {
@@ -142,6 +144,9 @@ lejp_globals_cb(struct lejp_ctx *ctx, char reason)
 		if (arg_to_bool(ctx->buf))
 			a->info->options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
 		return 0;
+	case LEJPGP_SERVER_STRING:
+		a->info->server_string = a->p;
+		break;
 
 	default:
 		return 0;