diff --git a/changelog b/changelog
index 0ea7bba86d6241fc5b0261891a036d6b7b88e619..a7eac226248572278187829785fe0b94895f4bf0 100644
--- a/changelog
+++ b/changelog
@@ -1,6 +1,41 @@
 Changelog
 ---------
 
+User api additions
+------------------
+
+The info struct gained two new members
+
+ - max_http_header_data: 0 for default (1024) or set the maximum amount of known
+    http header payload that lws can deal with.  Payload in unknown http
+    headers is dropped silently.  If for some reason you need to send huge
+    cookies or other HTTP-level headers, you can now increase this at context-
+    creation time.
+
+ - max_http_header_pool: 0 for default (16) or set the maximum amount of http
+     headers that can be tracked by lws in this context.  For the server, if
+     the header pool is completely in use then accepts on the listen socket
+     are disabled until one becomes free.  For the client, if you simultaneously
+     have pending connects for more than this number of client connections,
+     additional connects will fail until some of the pending connections timeout
+     or complete.
+
+HTTP header processing in lws only exists until just after the first main
+callback after the HTTP handshake... for ws connections that is ESTABLISHED and
+for HTTP connections the HTTP callback.
+
+So these settings are not related to the maximum number of simultaneous
+connections but the number of HTTP handshakes that may be expected or ongoing,
+or have just completed, at one time.  The reason it's useful is it changes the
+memory allocation for header processing to be one-time at context creation
+instead of every time there is a new connection, and gives you control over
+the peak allocation.
+
+Setting max_http_header_pool to 1 is fine it will just queue incoming
+connections before the accept as necessary, you can still have as many
+simultaneous post-header connections as you like.
+
+
 v1.6.0-chrome48-firefox42
 =======================
 
diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index 435804604fdc269e7a148314b4368a5d9f33731b..77915ce5805562913ab96ca033dfa458ed8d74f9 100644
--- a/lib/client-handshake.c
+++ b/lib/client-handshake.c
@@ -303,7 +303,7 @@ lws_client_connect_2(struct lws *wsi)
 	return wsi;
 
 oom4:
-	lws_free(wsi->u.hdr.ah);
+	lws_free_header_table(wsi);
 	lws_free(wsi);
 
 	return NULL;
@@ -423,10 +423,10 @@ lws_client_connect(struct lws_context *context, const char *address,
 	}
 	lwsl_client("lws_client_connect: direct conn\n");
 
-       return lws_client_connect_2(wsi);
+	return lws_client_connect_2(wsi);
 
 bail1:
-	lws_free(wsi->u.hdr.ah);
+	lws_free_header_table(wsi);
 bail:
 	lws_free(wsi);
 
diff --git a/lib/client.c b/lib/client.c
index d9a1af378753670177c0b0401689462758d2bc26..86ce7223ab59169078f604cbe10dd27a7c658bfe 100644
--- a/lib/client.c
+++ b/lib/client.c
@@ -724,12 +724,10 @@ check_accept:
 		goto bail2;
 
 	/* clear his proxy connection timeout */
-
 	lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
 
 	/* free up his parsing allocations */
-
-	lws_free(wsi->u.hdr.ah);
+	lws_free_header_table(wsi);
 
 	lws_union_transition(wsi, LWSCM_WS_CLIENT);
 	wsi->state = LWSS_ESTABLISHED;
@@ -809,7 +807,7 @@ bail2:
 	lwsl_info("closing connection due to bail2 connection error\n");
 
 	/* free up his parsing allocations */
-	lws_free_set_NULL(wsi->u.hdr.ah);
+	lws_free_header_table(wsi);
 	lws_close_free_wsi(wsi, close_reason);
 
 	return 1;
diff --git a/lib/context.c b/lib/context.c
index 757fdd34637d0dd6528ace999591ceaddfcc260c..436216a7dd949ffc3dbb9cd4e59017e62c3a7720 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -80,6 +80,7 @@ lws_create_context(struct lws_context_creation_info *info)
 	int pid_daemon = get_daemonize_pid();
 #endif
 	char *p;
+	int n;
 
 	lwsl_notice("Initial logging level %d\n", log_level);
 
@@ -150,11 +151,42 @@ lws_create_context(struct lws_context_creation_info *info)
 	context->lws_ev_sigint_cb = &lws_sigint_cb;
 #endif /* LWS_USE_LIBEV */
 
-	/* to reduce this allocation, */
+	lwsl_info(" mem: context:         %5u bytes\n", sizeof(struct lws_context));
+
+	/*
+	 * allocate and initialize the pool of
+	 * allocated_header structs + data
+	 */
+	if (info->max_http_header_data)
+		context->max_http_header_data = info->max_http_header_data;
+	else
+		context->max_http_header_data = LWS_MAX_HEADER_LEN;
+	if (info->max_http_header_pool)
+		context->max_http_header_pool = info->max_http_header_pool;
+	else
+		context->max_http_header_pool = LWS_MAX_HEADER_POOL;
+
+	context->http_header_data = lws_malloc(context->max_http_header_data *
+					       context->max_http_header_pool);
+	if (!context->http_header_data)
+		goto bail;
+	context->ah_pool = lws_zalloc(sizeof(struct allocated_headers) *
+				      context->max_http_header_pool);
+	if (!context->ah_pool)
+		goto bail;
+
+	for (n = 0; n < context->max_http_header_pool; n++)
+		context->ah_pool[n].data = (char *)context->http_header_data +
+			(n * context->max_http_header_data);
+
+	/* this is per context */
+	lwsl_info(" mem: http hdr rsvd:   %5u bytes ((%u + %u) x %u)\n",
+		    (context->max_http_header_data + sizeof(struct allocated_headers)) *
+		    context->max_http_header_pool,
+		    context->max_http_header_data, sizeof(struct allocated_headers),
+		    context->max_http_header_pool);
+
 	context->max_fds = getdtablesize();
-	lwsl_notice(" ctx mem: %u bytes\n", sizeof(struct lws_context) +
-		    ((sizeof(struct lws_pollfd) + sizeof(struct lws *)) *
-		    context->max_fds));
 
 	context->fds = lws_zalloc(sizeof(struct lws_pollfd) * context->max_fds);
 	if (context->fds == NULL) {
@@ -162,6 +194,9 @@ lws_create_context(struct lws_context_creation_info *info)
 		goto bail;
 	}
 
+	lwsl_info(" mem: pollfd map:      %5u\n",
+		    sizeof(struct lws_pollfd) * context->max_fds);
+
 	if (lws_plat_init(context, info))
 		goto bail;
 
@@ -169,8 +204,10 @@ lws_create_context(struct lws_context_creation_info *info)
 
 	context->user_space = info->user;
 
-	strcpy(context->canonical_hostname, "unknown");
+	lwsl_notice(" mem: per-conn:        %5u bytes + protocol rx buf\n",
+		    sizeof(struct lws));
 
+	strcpy(context->canonical_hostname, "unknown");
 	lws_server_get_canonical_hostname(context, info);
 
 	/* either use proxy from info, or try get it from env var */
@@ -188,9 +225,6 @@ lws_create_context(struct lws_context_creation_info *info)
 #endif
 	}
 
-	lwsl_notice(" per-conn mem: %u + %u headers + protocol rx buf\n",
-		    sizeof(struct lws), sizeof(struct allocated_headers));
-
 	if (lws_context_init_server_ssl(info, context))
 		goto bail;
 
@@ -311,9 +345,12 @@ lws_context_destroy(struct lws_context *context)
 
 	lws_plat_context_early_destroy(context);
 	lws_ssl_context_destroy(context);
-
 	if (context->fds)
 		lws_free(context->fds);
+	if (context->ah_pool)
+		lws_free(context->ah_pool);
+	if (context->http_header_data)
+		lws_free(context->http_header_data);
 
 	lws_plat_context_late_destroy(context);
 
diff --git a/lib/hpack.c b/lib/hpack.c
index f311d700c9e6d8f31baac922d923dd7ca7633292..2c5b1d94f813ce0254584442600d01d0c22bf585 100644
--- a/lib/hpack.c
+++ b/lib/hpack.c
@@ -221,7 +221,7 @@ static int lws_frag_append(struct lws *wsi, unsigned char c)
 	ah->data[ah->pos++] = c;
 	ah->frags[ah->nfrag].len++;
 
-	return ah->pos >= sizeof(ah->data);
+	return ah->pos >= wsi->context->max_http_header_data;
 }
 
 static int lws_frag_end(struct lws *wsi)
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 6e63e8ec8c1e76ad3410c259f2aed6356ae687fd..58a5e204fd17028e8ccf616b95604715fbb2fc44 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -52,7 +52,19 @@ lws_free_wsi(struct lws *wsi)
 
 	lws_free_set_NULL(wsi->rxflow_buffer);
 	lws_free_set_NULL(wsi->trunc_alloc);
-	lws_free_header_table(wsi);
+	/*
+	 * These union members have an ah at the start
+	 *
+	 * 	struct _lws_http_mode_related http;
+	 *	struct _lws_http2_related http2;
+	 *	struct _lws_header_related hdr;
+	 *
+	 * basically ws-related union member does not
+	 */
+	if (wsi->mode != LWSCM_WS_CLIENT &&
+	    wsi->mode != LWSCM_WS_SERVING)
+		if (wsi->u.hdr.ah)
+			lws_free_header_table(wsi);
 	lws_free(wsi);
 }
 
@@ -222,7 +234,6 @@ just_kill_connection:
 	wsi->state = LWSS_DEAD_SOCKET;
 
 	lws_free_set_NULL(wsi->rxflow_buffer);
-	lws_free_header_table(wsi);
 
 	if (old_state == LWSS_ESTABLISHED ||
 	    wsi->mode == LWSCM_WS_SERVING ||
@@ -912,6 +923,7 @@ lws_get_peer_write_allowance(struct lws *wsi)
 LWS_VISIBLE void
 lws_union_transition(struct lws *wsi, enum connection_mode mode)
 {
+	lwsl_debug("%s: %p: mode %d\n", __func__, wsi, mode);
 	memset(&wsi->u, 0, sizeof(wsi->u));
 	wsi->mode = mode;
 }
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 4855cd91c0d9c989b54bac7323d0390805fb1a83..861fc2bcd0661cf515e03ad22553a775653f944b 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -1249,6 +1249,13 @@ struct lws_extension {
  *		implementation for the one provided by provided_ssl_ctx.
  *		Libwebsockets no longer is responsible for freeing the context
  *		if this option is selected.
+ * @max_http_header_data: The max amount of header payload that can be handled
+ *		in an http request (unrecognized header payload is dropped)
+ * @max_http_header_pool: The max number of connections with http headers that
+ *		can be processed simultaneously (the corresponding memory is
+ *		allocated for the lifetime of the context).  If the pool is
+ *		busy new incoming connections must wait for accept until one
+ *		becomes free.
  */
 
 struct lws_context_creation_info {
@@ -1274,9 +1281,12 @@ struct lws_context_creation_info {
 #ifdef LWS_OPENSSL_SUPPORT
 	SSL_CTX *provided_client_ssl_ctx;
 #else /* maintain structure layout either way */
-    	void *provided_client_ssl_ctx;
+	void *provided_client_ssl_ctx;
 #endif
 
+	short max_http_header_data;
+	short max_http_header_pool;
+
 	/* Add new things just above here ---^
 	 * This is part of the ABI, don't needlessly break compatibility
 	 *
@@ -1285,7 +1295,7 @@ struct lws_context_creation_info {
 	 * was not built against the newer headers.
 	 */
 
-	void *_unused[9];
+	void *_unused[8];
 };
 
 LWS_VISIBLE LWS_EXTERN void
diff --git a/lib/lws-plat-unix.c b/lib/lws-plat-unix.c
index 23c11b098b4e4ab8db0d7f62f8db0da2658f1dd3..d704c7af0c53d1374081beaf66a74ce2cde2a9c0 100644
--- a/lib/lws-plat-unix.c
+++ b/lib/lws-plat-unix.c
@@ -498,6 +498,9 @@ lws_plat_init(struct lws_context *context,
 		return 1;
 	}
 
+	lwsl_notice(" mem: platform fd map: %5u bytes\n",
+		    sizeof(struct lws *) * context->max_fds);
+
 	context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
 	if (context->fd_random < 0) {
 		lwsl_err("Unable to open random device %s %d\n",
diff --git a/lib/parsers.c b/lib/parsers.c
index e1de380480f7271d52e9f5c1f84c302ef0cd1b68..ae6c1db65bfa82ae8597355d90b293f88112c476 100644
--- a/lib/parsers.c
+++ b/lib/parsers.c
@@ -60,13 +60,47 @@ int lextable_decode(int pos, char c)
 
 int lws_allocate_header_table(struct lws *wsi)
 {
-	/* Be sure to free any existing header data to avoid mem leak: */
-	lws_free_header_table(wsi);
-	wsi->u.hdr.ah = lws_malloc(sizeof(*wsi->u.hdr.ah));
-	if (wsi->u.hdr.ah == NULL) {
-		lwsl_err("Out of memory\n");
+	struct lws_context *context = wsi->context;
+	int n;
+
+	lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi,
+		 (void *)wsi->u.hdr.ah);
+
+	/* if we are already bound to one, just clear it down */
+	if (wsi->u.hdr.ah)
+		goto reset;
+	/*
+	 * server should have suppressed the accept of a new wsi before this
+	 * became the case.  If initiating multiple client connects, make sure
+	 * the ah pool is big enough to cope, or be prepared to retry
+	 */
+	if (context->ah_count_in_use == context->max_http_header_pool) {
+		lwsl_err("No free ah\n");
 		return -1;
 	}
+
+	for (n = 0; n < context->max_http_header_pool; n++)
+		if (!context->ah_pool[n].in_use)
+			break;
+
+	/* if the count of in use said something free... */
+	assert(n != context->max_http_header_pool);
+
+	wsi->u.hdr.ah = &context->ah_pool[n];
+	wsi->u.hdr.ah->in_use = 1;
+
+	context->ah_count_in_use++;
+	/* if we used up all the ah, defeat accepting new server connections */
+	if (context->ah_count_in_use == context->max_http_header_pool)
+		if (_lws_server_listen_accept_flow_control(context, 0))
+			return 1;
+
+	lwsl_debug("%s: wsi %p: ah %p: count %d (on exit)\n",
+		 __func__, (void *)wsi, (void *)wsi->u.hdr.ah,
+		 context->ah_count_in_use);
+
+reset:
+	/* init the ah to reflect no headers or data have appeared yet */
 	memset(wsi->u.hdr.ah->frag_index, 0, sizeof(wsi->u.hdr.ah->frag_index));
 	wsi->u.hdr.ah->nfrag = 0;
 	wsi->u.hdr.ah->pos = 0;
@@ -76,10 +110,31 @@ int lws_allocate_header_table(struct lws *wsi)
 
 int lws_free_header_table(struct lws *wsi)
 {
-	lws_free_set_NULL(wsi->u.hdr.ah);
+	struct lws_context *context = wsi->context;
+
+	lwsl_debug("%s: wsi %p: ah %p (count = %d)\n", __func__, (void *)wsi,
+		 (void *)wsi->u.hdr.ah, context->ah_count_in_use);
+
+	assert(wsi->u.hdr.ah);
+	if (!wsi->u.hdr.ah)
+		return 0;
+
+	/* if we think we're freeing one, there should be one to free */
+	assert(context->ah_count_in_use > 0);
+
+	assert(wsi->u.hdr.ah->in_use);
+	wsi->u.hdr.ah->in_use = 0;
+
+	/* if we just freed up one ah, allow new server connection */
+	if (context->ah_count_in_use == context->max_http_header_pool)
+		if (_lws_server_listen_accept_flow_control(context, 1))
+			return 1;
+
+	context->ah_count_in_use--;
 	wsi->u.hdr.ah = NULL;
+
 	return 0;
-};
+}
 
 LWS_VISIBLE int
 lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx)
@@ -130,7 +185,7 @@ LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len,
 	if (wsi->u.hdr.ah->frags[f].len >= len)
 		return -1;
 
-	memcpy(dst, &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[f].offset],
+	memcpy(dst, wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[f].offset,
 	       wsi->u.hdr.ah->frags[f].len);
 	dst[wsi->u.hdr.ah->frags[f].len] = '\0';
 
@@ -167,7 +222,7 @@ char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h)
 	if (!n)
 		return NULL;
 
-	return &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset];
+	return wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[n].offset;
 }
 
 int lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h,
@@ -186,7 +241,7 @@ int lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h,
 	wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].nfrag = 0;
 
 	do {
-		if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
+		if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
 			lwsl_err("Ran out of header data space\n");
 			return -1;
 		}
@@ -216,7 +271,7 @@ static int issue_char(struct lws *wsi, unsigned char c)
 {
 	unsigned short frag_len;
 
-	if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
+	if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
 		lwsl_warn("excessive header content\n");
 		return -1;
 	}
@@ -236,8 +291,8 @@ static int issue_char(struct lws *wsi, unsigned char c)
 	/* Insert a null character when we *hit* the limit: */
 	if (frag_len == wsi->u.hdr.current_token_limit) {
 		wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
-		lwsl_warn("header %i exceeds limit\n",
-			  wsi->u.hdr.parser_state);
+		lwsl_warn("header %i exceeds limit %d\n",
+			  wsi->u.hdr.parser_state, wsi->u.hdr.current_token_limit);
 	}
 
 	return 1;
@@ -538,7 +593,8 @@ swallow:
 					context->token_limits->token_limit[
 						       wsi->u.hdr.parser_state];
 			else
-				wsi->u.hdr.current_token_limit = sizeof(ah->data);
+				wsi->u.hdr.current_token_limit =
+					wsi->context->max_http_header_data;
 
 			if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
 				goto set_parsing_complete;
@@ -569,7 +625,7 @@ excessive:
 				n = ah->frags[n].nfrag;
 		ah->frags[n].nfrag = ah->nfrag;
 
-		if (ah->pos == sizeof(ah->data)) {
+		if (ah->pos == wsi->context->max_http_header_data) {
 			lwsl_warn("excessive header content\n");
 			return -1;
 		}
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 57dd9f92c8ca457f569b92c8d0671095b2020b9f..5eaecd800b112cc15b238ecf46fb80ac31c9ddc8 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -283,6 +283,9 @@ extern "C" {
 #ifndef LWS_MAX_HEADER_LEN
 #define LWS_MAX_HEADER_LEN 1024
 #endif
+#ifndef LWS_MAX_HEADER_POOL
+#define LWS_MAX_HEADER_POOL 16
+#endif
 #ifndef LWS_MAX_PROTOCOLS
 #define LWS_MAX_PROTOCOLS 5
 #endif
@@ -451,6 +454,46 @@ struct lws_fd_hashtable {
 };
 #endif
 
+/*
+ * This is totally opaque to code using the library.  It's exported as a
+ * forward-reference pointer-only declaration; the user can use the pointer with
+ * other APIs to get information out of it.
+ */
+
+struct lws_fragments {
+	unsigned short offset;
+	unsigned short len;
+	unsigned char nfrag; /* which ah->frag[] continues this content, or 0 */
+};
+
+/*
+ * these are assigned from a pool held in the context.
+ * Both client and server mode uses them for http header analysis
+ */
+
+struct allocated_headers {
+	unsigned char in_use;
+	unsigned char nfrag;
+	unsigned short pos;
+	/*
+	 * for each recognized token, frag_index says which frag[] his data
+	 * starts in (0 means the token did not appear)
+	 * the actual header data gets dumped as it comes in, into data[]
+	 */
+	unsigned char frag_index[WSI_TOKEN_COUNT];
+	/*
+	 * the randomly ordered fragments, indexed by frag_index and
+	 * lws_fragments->nfrag for continuation.
+	 */
+	struct lws_fragments frags[WSI_TOKEN_COUNT * 2];
+	char *data; /* prepared by context init to point to dedicated storage */
+
+#ifndef LWS_NO_CLIENT
+	char initial_handshake_hash_base64[30];
+	unsigned short c_port;
+#endif
+};
+
 struct lws_context {
 #ifdef _WIN32
 	WSAEVENT *events;
@@ -539,6 +582,11 @@ struct lws_context {
 #ifndef LWS_NO_SERVER
 	struct lws *wsi_listening;
 #endif
+	short max_http_header_data;
+	short max_http_header_pool;
+	short ah_count_in_use;
+	void *http_header_data;
+	struct allocated_headers *ah_pool;
 };
 
 enum {
@@ -593,18 +641,6 @@ enum uri_esc_states {
 	URIES_SEEN_PERCENT_H1,
 };
 
-/*
- * This is totally opaque to code using the library.  It's exported as a
- * forward-reference pointer-only declaration; the user can use the pointer with
- * other APIs to get information out of it.
- */
-
-struct lws_fragments {
-	unsigned short offset;
-	unsigned short len;
-	unsigned char nfrag; /* which ah->frag[] continues this content, or 0 */
-};
-
 /* notice that these union members:
  *
  *  hdr
@@ -617,28 +653,6 @@ struct lws_fragments {
  * used interchangeably to access the same data
  */
 
-struct allocated_headers {
-	unsigned char nfrag;
-	unsigned short pos;
-	/*
-	 * for each recognized token, frag_index says which frag[] his data
-	 * starts in (0 means the token did not appear)
-	 * the actual header data gets dumped as it comes in, into data[]
-	 */
-	unsigned char frag_index[WSI_TOKEN_COUNT];
-	/*
-	 * the randomly ordered fragments, indexed by frag_index and
-	 * lws_fragments->nfrag for continuation.
-	 */
-	struct lws_fragments frags[WSI_TOKEN_COUNT * 2];
-	char data[LWS_MAX_HEADER_LEN];
-
-#ifndef LWS_NO_CLIENT
-	char initial_handshake_hash_base64[30];
-	unsigned short c_port;
-#endif
-};
-
 struct _lws_http_mode_related {
 	/* MUST be first in struct */
 	struct allocated_headers *ah; /* mirroring  _lws_header_related */
@@ -1104,7 +1118,7 @@ lws_change_pollfd(struct lws *wsi, int _and, int _or);
 
 #ifndef LWS_NO_SERVER
 int lws_context_init_server(struct lws_context_creation_info *info,
-			    struct lws_context *context);
+			    struct lws_context *context);;
 LWS_EXTERN int
 handshake_0405(struct lws_context *context, struct lws *wsi);
 LWS_EXTERN int
diff --git a/lib/server.c b/lib/server.c
index 7fa1bdff47439f4fbabaaf2c37541cf1ae40f65e..aacdeb96329192ebaa0dd25a73cf76c3d958b71a 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -111,7 +111,6 @@ int lws_context_init_server(struct lws_context_creation_info *info,
 	else
 		info->port = ntohs(sin.sin_port);
 #endif
-
 	context->listen_port = info->port;
 
 	wsi = lws_zalloc(sizeof(struct lws));
@@ -191,6 +190,8 @@ _lws_server_listen_accept_flow_control(struct lws_context *context, int on)
 	if (!wsi)
 		return 0;
 
+	lwsl_debug("%s: wsi %p: state %d\n", __func__, (void *)wsi, on);
+
 	if (on)
 		n = lws_change_pollfd(wsi, 0, LWS_POLLIN);
 	else
@@ -321,7 +322,7 @@ int lws_http_action(struct lws *wsi)
 	}
 
 	/* now drop the header info we kept a pointer to */
-	lws_free_set_NULL(wsi->u.http.ah);
+	lws_free_header_table(wsi);
 
 	if (n) {
 		lwsl_info("LWS_CALLBACK_HTTP closing\n");
@@ -343,8 +344,7 @@ int lws_http_action(struct lws *wsi)
 	return 0;
 
 bail_nuke_ah:
-	/* drop the header info */
-	lws_free_set_NULL(wsi->u.hdr.ah);
+	lws_free_header_table(wsi);
 
 	return 1;
 }
@@ -388,6 +388,7 @@ int lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
 
 			/* expose it at the same offset as u.hdr */
 			wsi->u.http.ah = ah;
+			lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi, (void *)wsi->u.hdr.ah);
 
 			n = lws_http_action(wsi);
 
@@ -667,6 +668,7 @@ lws_create_new_server_wsi(struct lws_context *context)
 LWS_VISIBLE
 int lws_http_transaction_completed(struct lws *wsi)
 {
+	lwsl_debug("%s: wsi %p\n", __func__, wsi);
 	/* if we can't go back to accept new headers, drop the connection */
 	if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
 		lwsl_info("%s: close connection\n", __func__);
diff --git a/test-server/test-server.c b/test-server/test-server.c
index dcf5ec4350f4358969b89ac1dfb460f12e74fa18..18c9bea08110d15786453fa642be414fe83226fd 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -284,6 +284,7 @@ int main(int argc, char **argv)
 	}
 	info.gid = -1;
 	info.uid = -1;
+	info.max_http_header_pool = 1;
 	info.options = opts;
 
 	context = lws_create_context(&info);