diff --git a/lib/client.c b/lib/client.c
index 19a819d9c110c48ca4990f1722f042b1a335eaa7..2b9a943cc4d4e38b0fbc5f8193fba11ae776067c 100755
--- a/lib/client.c
+++ b/lib/client.c
@@ -411,7 +411,7 @@ int lws_client_socket_service(struct libwebsocket_context *context,
 				return 0;
 			}
 
-			if (libwebsocket_parse(wsi, c)) {
+			if (libwebsocket_parse(context, wsi, c)) {
 				lwsl_warn("problems parsing header\n");
 				goto bail3;
 			}
diff --git a/lib/context.c b/lib/context.c
index 2c283d767bbab44fb6a8bb38a5acc06e6c64bc05..f2f30ade04d8aa10696a2e9798ee3b40304ce50b 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -116,6 +116,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
 
 	context->listen_service_extraseen = 0;
 	context->protocols = info->protocols;
+	context->token_limits = info->token_limits;
 	context->listen_port = info->port;
 	context->http_proxy_port = 0;
 	context->http_proxy_address[0] = '\0';
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 47ae4df3adc888a46915f31c5ba56e6333b7a57a..dd0bd372baee1ae6d1de6f7bdc604ca929279321 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -341,6 +341,10 @@ enum lws_token_indexes {
 	WSI_INIT_TOKEN_MUXURL,
 };
 
+struct lws_token_limits {
+    unsigned short token_limit[WSI_TOKEN_COUNT];
+};
+
 /*
  * From RFC 6455
    1000
@@ -947,6 +951,7 @@ struct lws_context_creation_info {
 	const char *iface;
 	struct libwebsocket_protocols *protocols;
 	struct libwebsocket_extension *extensions;
+    struct lws_token_limits *token_limits;
 	const char *ssl_cert_filepath;
 	const char *ssl_private_key_filepath;
 	const char *ssl_ca_filepath;
diff --git a/lib/parsers.c b/lib/parsers.c
index 68a7e5d31d06a2a25197e9e075d00b7c48497126..07c55001d5428c368f5ed8da4c12e560af2a0200 100644
--- a/lib/parsers.c
+++ b/lib/parsers.c
@@ -165,12 +165,22 @@ static char char_to_hex(const char c)
 	return -1;
 }
 
-static int issue_char(struct libwebsocket *wsi, unsigned char c)
+static int issue_char(
+		struct libwebsocket_context *context,
+		struct libwebsocket *wsi, unsigned char c)
 {
 	if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
 		lwsl_warn("excessive header content\n");
 		return -1;
 	}
+
+	if( context->token_limits &&
+		(wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len >= 
+		context->token_limits->token_limit[wsi->u.hdr.parser_state]) ) {
+		lwsl_warn("header %i exceeds limit\n", wsi->u.hdr.parser_state);
+		return 1;
+	};
+
 	wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
 	if (c)
 		wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++;
@@ -178,7 +188,9 @@ static int issue_char(struct libwebsocket *wsi, unsigned char c)
 	return 0;
 }
 
-int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
+int libwebsocket_parse(
+		struct libwebsocket_context *context,
+		struct libwebsocket *wsi, unsigned char c)
 {
 	int n;
 
@@ -234,7 +246,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
 		if (c == ' ') {
 			/* enforce starting with / */
 			if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len)
-				if (issue_char(wsi, '/') < 0)
+				if (issue_char(context, wsi, '/') < 0)
 					return -1;
 			c = '\0';
 			wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
@@ -253,7 +265,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
 		case URIES_SEEN_PERCENT:
 			if (char_to_hex(c) < 0) {
 				/* regurgitate */
-				if (issue_char(wsi, '%') < 0)
+				if (issue_char(context, wsi, '%') < 0)
 					return -1;
 				wsi->u.hdr.ues = URIES_IDLE;
 				/* continue on to assess c */
@@ -266,10 +278,10 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
 		case URIES_SEEN_PERCENT_H1:
 			if (char_to_hex(c) < 0) {
 				/* regurgitate */
-				issue_char(wsi, '%');
+				issue_char(context, wsi, '%');
 				wsi->u.hdr.ues = URIES_IDLE;
 				/* regurgitate + assess */
-				if (libwebsocket_parse(wsi, wsi->u.hdr.esc_stash) < 0)
+				if (libwebsocket_parse(context, wsi, wsi->u.hdr.esc_stash) < 0)
 					return -1;
 				/* continue on to assess c */
 				break;
@@ -332,7 +344,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
 			}
 			/* it was like /.dir ... regurgitate the . */
 			wsi->u.hdr.ups = URIPS_IDLE;
-			issue_char(wsi, '.');
+			issue_char(context, wsi, '.');
 			break;
 			
 		case URIPS_SEEN_SLASH_DOT_DOT:
@@ -383,8 +395,15 @@ check_eol:
 		}
 
 spill:
-		if (issue_char(wsi, c) < 0)
-			return -1;
+		{
+			int issue_result = issue_char(context, wsi, c);
+			if (issue_result < 0) {
+				return -1;
+			}
+			else if(issue_result > 0) {
+				wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
+			};
+		};
 swallow:
 		/* per-protocol end of headers management */
 
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index d05c48f2efd1de2355ca40e50eb1b6b80bf20ac1..281bd7f448c06649ae3b71ac7bbb453bab9d9098 100755
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -432,6 +432,7 @@ struct libwebsocket_context {
 #ifndef LWS_NO_EXTENSIONS
 	struct libwebsocket_extension *extensions;
 #endif
+    struct lws_token_limits *token_limits;
 	void *user_space;
 };
 
@@ -645,7 +646,8 @@ LWS_EXTERN int
 libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
 
 LWS_EXTERN int
-libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
+libwebsocket_parse(struct libwebsocket_context *context,
+		struct libwebsocket *wsi, unsigned char c);
 
 LWS_EXTERN int
 lws_b64_selftest(void);
diff --git a/lib/server.c b/lib/server.c
index 37ce6a17f73d488d5ccca9d1f99b3ca1f9a189a5..1e8518646b32e159ae57b44edc615e5f1fd24a39 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -179,7 +179,7 @@ int lws_handshake_server(struct libwebsocket_context *context,
 	/* LWS_CONNMODE_WS_SERVING */
 
 	while (len--) {
-		if (libwebsocket_parse(wsi, *(*buf)++)) {
+		if (libwebsocket_parse(context, wsi, *(*buf)++)) {
 			lwsl_info("libwebsocket_parse failed\n");
 			goto bail_nuke_ah;
 		}