diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d3bdee391f9ee7d6bcc127359a3130d511cca8f..a79fdf9dbfd33da7b60a1bab3829ec760ea3059e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -98,7 +98,7 @@ option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket" OFF)
 option(LWS_WITH_HTTP2 "Compile with support for http2" OFF)
 option(LWS_SSL_SERVER_WITH_ECDH_CERT "Include SSL server use ECDH certificate" OFF)
 option(LWS_WITH_CGI "Include CGI (spawn process with network-connected stdin/out/err) APIs" OFF)
-option(LWS_WITH_HTTP_PROXY "Support for rewriting HTTP proxying" OFF)
+option(LWS_WITH_HTTP_PROXY "Support for rewriting HTTP proxying (requires libhubbub)" OFF)
 option(LWS_WITH_LWSWS "Libwebsockets Webserver" OFF)
 option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions" OFF)
 option(LWS_WITH_ACCESS_LOG "Support generating Apache-compatible access logs" OFF)
@@ -392,7 +392,7 @@ if (LWS_WITH_HTTP2)
 endif()
 
 if ("${LWS_MAX_SMP}" STREQUAL "")
-	set(LWS_MAX_SMP 32)
+	set(LWS_MAX_SMP 1)
 endif()
 
 
@@ -735,7 +735,7 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_C_COMPILER_ID
 endif ()
 
 if ((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT LWS_WITHOUT_TESTAPPS)
-    if (UNIX)
+	if (UNIX AND LWS_MAX_SMP GREATER 1)
 	# jeez clang understands -pthread but dies if he sees it at link time!
 	# http://stackoverflow.com/questions/2391194/what-is-gs-pthread-equiv-in-clang
 	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread" )
@@ -1251,7 +1251,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 					""
 					"")
 			endif()
-			if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")))
+			if (UNIX AND NOT ((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND LWS_MAX_SMP GREATER 1)
 				create_test_app(test-server-pthreads
 					"test-server/test-server-pthreads.c"
 					"test-server/test-server-http.c"
diff --git a/README.lwsws.md b/README.lwsws.md
index 12ad81e7b691fe5e78c1c0430b6e9c8e031eec24..04ba81ade6f4fd3e82d706754bd14be2567a4066 100644
--- a/README.lwsws.md
+++ b/README.lwsws.md
@@ -292,6 +292,20 @@ Mount protocols are used to control what kind of translation happens
 ```
  would cause the url /git/myrepo to pass "myrepo" to the cgi /var/www/cgi-bin/cgit and send the results to the client.
 
+ - http:// or https://  these perform reverse proxying, serving the remote origin content from the mountpoint.  Eg
+
+```
+		{
+		 "mountpoint": "/proxytest",
+		 "origin": "https://libwebsockets.org"
+		}
+```
+
+This will cause your local url `/proxytest` to serve content fetched from libwebsockets.org over ssl; whether it's served from your server using ssl is unrelated and depends how you configured your local server.  Notice if you will use the proxying feature, `LWS_WITH_HTTP_PROXY` is required to be enabled at cmake, and for `https` proxy origins, your lwsws configuration must include `"init-ssl": "1"` and the vhost with the proxy mount must have `"enable-client-ssl": "1"`, even if you are not using ssl to serve.
+
+`/proxytest/abc`, or `/proxytest/abc?def=ghi` etc map to the origin + the part past `/proxytest`, so links and img src urls etc work as do all urls under the origin path.
+
+In addition link and src urls in the document are rewritten so / or the origin url part are rewritten to the mountpoint part.
 
 
 @section lwswsomo Lwsws Other mount options
diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index dc6de916f1f94716b4394ef6347c29dbccd57b42..26543b9b8b24fbf194aa6c8c26bb8e49334e0524 100644
--- a/lib/client-handshake.c
+++ b/lib/client-handshake.c
@@ -262,7 +262,8 @@ lws_client_connect_2(struct lws *wsi)
 		n = sizeof(struct sockaddr);
 	}
 
-	if (connect(wsi->desc.sockfd, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
+	if (connect(wsi->desc.sockfd, v, n) == -1 ||
+	    LWS_ERRNO == LWS_EISCONN) {
 		if (LWS_ERRNO == LWS_EALREADY ||
 		    LWS_ERRNO == LWS_EINPROGRESS ||
 		    LWS_ERRNO == LWS_EWOULDBLOCK
@@ -527,14 +528,14 @@ html_parser_cb(const hubbub_token *token, void *pw)
 						"(force-quirks) " : "");
 
 		if (token->data.doctype.public_missing)
-			printf("\tpublic: missing\n");
+			lwsl_debug("\tpublic: missing\n");
 		else
 			p += lws_snprintf(p, end - p, "PUBLIC \"%.*s\"\n",
 				(int) token->data.doctype.public_id.len,
 				token->data.doctype.public_id.ptr);
 
 		if (token->data.doctype.system_missing)
-			printf("\tsystem: missing\n");
+			lwsl_debug("\tsystem: missing\n");
 		else
 			p += lws_snprintf(p, end - p, " \"%.*s\">\n",
 				(int) token->data.doctype.system_id.len,
@@ -557,25 +558,28 @@ html_parser_cb(const hubbub_token *token, void *pw)
 				const char *pp = (const char *)token->data.tag.attributes[i].value.ptr;
 				int plen = (int) token->data.tag.attributes[i].value.len;
 
-				if (!hstrcmp(&token->data.tag.attributes[i].value,
-					     r->from, r->from_len)) {
-					pp += r->from_len;
-					plen -= r->from_len;
+				if (strncmp(pp, "http:", 5) && strncmp(pp, "https:", 6)) {
+
+					if (!hstrcmp(&token->data.tag.attributes[i].value,
+						     r->from, r->from_len)) {
+						pp += r->from_len;
+						plen -= r->from_len;
+					}
+					p += lws_snprintf(p, end - p, " %.*s=\"%s/%.*s\"",
+					       (int) token->data.tag.attributes[i].name.len,
+					       token->data.tag.attributes[i].name.ptr,
+					       r->to, plen, pp);
+					continue;
 				}
-				p += lws_snprintf(p, end - p, " %.*s=\"%s/%.*s\"",
-				       (int) token->data.tag.attributes[i].name.len,
-				       token->data.tag.attributes[i].name.ptr,
-				       r->to, plen, pp);
-
-			} else
-
-				p += lws_snprintf(p, end - p, " %.*s=\"%.*s\"",
-					(int) token->data.tag.attributes[i].name.len,
-					token->data.tag.attributes[i].name.ptr,
-					(int) token->data.tag.attributes[i].value.len,
-					token->data.tag.attributes[i].value.ptr);
+			}
+
+			p += lws_snprintf(p, end - p, " %.*s=\"%.*s\"",
+				(int) token->data.tag.attributes[i].name.len,
+				token->data.tag.attributes[i].name.ptr,
+				(int) token->data.tag.attributes[i].value.len,
+				token->data.tag.attributes[i].value.ptr);
 		}
-		p += lws_snprintf(p, end - p, ">\n");
+		p += lws_snprintf(p, end - p, ">");
 		break;
 	case HUBBUB_TOKEN_END_TAG:
 		p += lws_snprintf(p, end - p, "</%.*s", (int) token->data.tag.name.len,
@@ -593,7 +597,7 @@ html_parser_cb(const hubbub_token *token, void *pw)
 				(int) token->data.tag.attributes[i].value.len,
 				token->data.tag.attributes[i].value.ptr);
 		}
-		p += lws_snprintf(p, end - p, ">\n");
+		p += lws_snprintf(p, end - p, ">");
 		break;
 	case HUBBUB_TOKEN_COMMENT:
 		p += lws_snprintf(p, end - p, "<!-- %.*s -->\n",
@@ -601,6 +605,21 @@ html_parser_cb(const hubbub_token *token, void *pw)
 				token->data.comment.ptr);
 		break;
 	case HUBBUB_TOKEN_CHARACTER:
+		if (token->data.character.len == 1) {
+			if (*token->data.character.ptr == '<') {
+				p += lws_snprintf(p, end - p, "&lt;");
+				break;
+			}
+			if (*token->data.character.ptr == '>') {
+				p += lws_snprintf(p, end - p, "&gt;");
+				break;
+			}
+			if (*token->data.character.ptr == '&') {
+				p += lws_snprintf(p, end - p, "&amp;");
+				break;
+			}
+		}
+
 		p += lws_snprintf(p, end - p, "%.*s", (int) token->data.character.len,
 				token->data.character.ptr);
 		break;
diff --git a/lib/context.c b/lib/context.c
index f71f01da5fa34d7707b0fd26f7521eaa798016da..fab3dc27e53afe278a5f624bb1f9b8b0bcca3c5a 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -222,10 +222,13 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
 {
 #ifdef LWS_WITH_CGI
 	struct lws_cgi_args *args;
-	char buf[128];
+#endif
+#if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY)
+	char buf[512];
 	int n;
 #endif
 
+
 	switch (reason) {
 	case LWS_CALLBACK_HTTP:
 #ifndef LWS_NO_SERVER
@@ -250,9 +253,92 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
 			break;
 		}
 #endif
+#if defined(LWS_WITH_HTTP_PROXY)
+		if (wsi->reason_bf & 2) {
+			char *px = buf + LWS_PRE;
+			int lenx = sizeof(buf) - LWS_PRE;
+			/*
+			 * our sink is writeable and our source has something
+			 * to read.  So read a lump of source material of
+			 * suitable size to send or what's available, whichever
+			 * is the smaller.
+			 */
 
+
+			wsi->reason_bf &= ~2;
+			if (!lws_get_child(wsi))
+				break;
+			if (lws_http_client_read(lws_get_child(wsi), &px, &lenx) < 0)
+				return -1;
+			break;
+		}
+#endif
+		break;
+
+#if defined(LWS_WITH_HTTP_PROXY)
+	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
+		//lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP: wsi %p\n", wsi);
+		assert(lws_get_parent(wsi));
+		if (!lws_get_parent(wsi))
+			break;
+		lws_get_parent(wsi)->reason_bf |= 2;
+		lws_callback_on_writable(lws_get_parent(wsi));
 		break;
 
+	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
+		//lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ len %d\n", (int)len);
+		assert(lws_get_parent(wsi));
+		n = lws_write(lws_get_parent(wsi), (unsigned char *)in,
+				len, LWS_WRITE_HTTP);
+		if (n < 0)
+			return -1;
+		break;
+
+	case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: {
+		unsigned char *p, *end;
+		char ctype[64], ctlen = 0;
+
+		//lwsl_err("LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP\n");
+	
+		p = (unsigned char *)buf + LWS_PRE;
+		end = p + sizeof(buf) - LWS_PRE;
+
+		if (lws_add_http_header_status(lws_get_parent(wsi), HTTP_STATUS_OK, &p, end))
+			return 1;
+		if (lws_add_http_header_by_token(lws_get_parent(wsi),
+				WSI_TOKEN_HTTP_SERVER,
+			    	(unsigned char *)"libwebsockets",
+				13, &p, end))
+			return 1;
+
+		ctlen = lws_hdr_copy(wsi, ctype, sizeof(ctype), WSI_TOKEN_HTTP_CONTENT_TYPE);
+		if (ctlen > 0) {
+			if (lws_add_http_header_by_token(lws_get_parent(wsi),
+				WSI_TOKEN_HTTP_CONTENT_TYPE,
+				(unsigned char *)ctype, ctlen, &p, end))
+				return 1;
+		}
+#if 0
+		if (lws_add_http_header_content_length(lws_get_parent(wsi),
+						       file_len, &p, end))
+			return 1;
+#endif
+		if (lws_finalize_http_header(lws_get_parent(wsi), &p, end))
+			return 1;
+
+		*p = '\0';
+//		lwsl_info("%s\n", buf + LWS_PRE);
+
+		n = lws_write(lws_get_parent(wsi), (unsigned char *)buf + LWS_PRE,
+			      p - ((unsigned char *)buf + LWS_PRE),
+			      LWS_WRITE_HTTP_HEADERS);
+		if (n < 0)
+			return -1;
+
+		break; }
+
+#endif
+
 #ifdef LWS_WITH_CGI
 	/* CGI IO events (POLLIN/OUT) appear here, our default policy is:
 	 *
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 2db2fc683e90dd8ea0c5272a11c939b6f3e980f2..23d658855b153e557c3d6a600da8da33e1a8b26a 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -2289,8 +2289,8 @@ struct lws_protocol_vhost_options {
  * served from a filesystem, or it is a cgi etc.
  */
 enum lws_mount_protocols {
-	LWSMPRO_HTTP		= 0, /**< not supported yet */
-	LWSMPRO_HTTPS		= 1, /**< not supported yet */
+	LWSMPRO_HTTP		= 0, /**< http reverse proxy */
+	LWSMPRO_HTTPS		= 1, /**< https reverse proxy */
 	LWSMPRO_FILE		= 2, /**< serve from filesystem directory */
 	LWSMPRO_CGI		= 3, /**< pass to CGI to handle */
 	LWSMPRO_REDIR_HTTP	= 4, /**< redirect to http:// url */
diff --git a/lib/parsers.c b/lib/parsers.c
index 1140b4d95bebaba96521fb77ca59bf9332919d07..9cd70e05e2b94b5e4362b8df48fd68c86f4ee143 100644
--- a/lib/parsers.c
+++ b/lib/parsers.c
@@ -321,15 +321,18 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
 	pt->ah_wait_list_length--;
 
 #ifndef LWS_NO_CLIENT
-	if (wsi->state == LWSS_CLIENT_UNCONNECTED)
+	if (wsi->state == LWSS_CLIENT_UNCONNECTED) {
+		lws_pt_unlock(pt);
+
 		if (!lws_client_connect_via_info2(wsi)) {
 			/* our client connect has failed, the wsi
 			 * has been closed
 			 */
-			lws_pt_unlock(pt);
 
 			return -1;
 		}
+		return 0;
+	}
 #endif
 
 	assert(!!pt->ah_wait_list_length == !!(int)(long)pt->ah_wait_list);
diff --git a/lib/server.c b/lib/server.c
index 54e974a1436aa56a5c35ffd6cf272e27ab90b921..2693cc0b826ee14902472774b495bc6fe16a4c18 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -662,6 +662,23 @@ lws_unauthorised_basic_auth(struct lws *wsi)
 
 #endif
 
+int lws_clean_url(char *p)
+{
+	while (*p) {
+		if (p[0] == '/' && p[1] == '/') {
+			char *p1 = p;
+			while (*p1) {
+				*p1 = p1[1];
+				p1++;
+			}
+			continue;
+		}
+		p++;
+	}
+
+	return 0;
+}
+
 int
 lws_http_action(struct lws *wsi)
 {
@@ -958,6 +975,7 @@ lws_http_action(struct lws *wsi)
 			    "%s%s%s/", oprot[lws_is_ssl(wsi)],
 			    lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST),
 			    uri_ptr);
+		lws_clean_url((char *)end);
 
 		n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY,
 				      end, n, &p, end);
@@ -1013,6 +1031,84 @@ lws_http_action(struct lws *wsi)
 	}
 #endif
 
+#if defined(LWS_WITH_HTTP_PROXY)
+	/*
+	 * The mount is a reverse proxy?
+	 */
+
+	if (hit->origin_protocol == LWSMPRO_HTTPS ||
+	    hit->origin_protocol == LWSMPRO_HTTP)  {
+		struct lws_client_connect_info i;
+		char ads[96], rpath[256], *pcolon, *pslash, *p;
+		int n, na;
+
+		memset(&i, 0, sizeof(i));
+		i.context = lws_get_context(wsi);
+
+		pcolon = strchr(hit->origin, ':');
+		pslash = strchr(hit->origin, '/');
+		if (!pslash) {
+			lwsl_err("Proxy mount origin '%s' must have /\n", hit->origin);
+			return -1;
+		}
+		if (pcolon > pslash)
+			pcolon = NULL;
+		
+		if (pcolon)
+			n = pcolon - hit->origin;
+		else
+			n = pslash - hit->origin;
+
+		if (n >= sizeof(ads) - 2)
+			n = sizeof(ads) - 2;
+
+		memcpy(ads, hit->origin, n);
+		ads[n] = '\0';
+
+		i.address = ads;
+		i.port = 80;
+		if (hit->origin_protocol == LWSMPRO_HTTPS) { 
+			i.port = 443;
+			i.ssl_connection = 1;
+		}
+		if (pcolon)
+			i.port = atoi(pcolon + 1);
+		
+		lws_snprintf(rpath, sizeof(rpath) - 1, "/%s/%s", pslash + 1, uri_ptr + hit->mountpoint_len);
+		lws_clean_url(rpath);
+		na = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_URI_ARGS);
+		if (na) {
+			p = rpath + strlen(rpath);
+			*p++ = '?';
+			lws_hdr_copy(wsi, p, &rpath[sizeof(rpath) - 1] - p, WSI_TOKEN_HTTP_URI_ARGS);
+			while (--na) {
+				if (*p == '\0')
+					*p = '&';
+				p++;
+			}
+		}
+				
+
+		i.path = rpath;
+		i.host = i.address;
+		i.origin = NULL;
+		i.method = "GET";
+		i.parent_wsi = wsi;
+		i.uri_replace_from = hit->origin;
+		i.uri_replace_to = hit->mountpoint;
+
+		lwsl_notice("proxying to %s port %d url %s, ssl %d, from %s, to %s\n",
+				i.address, i.port, i.path, i.ssl_connection, i.uri_replace_from, i.uri_replace_to);
+	
+		if (!lws_client_connect_via_info(&i)) {
+			lwsl_err("proxy connect fail\n");
+			return 1;
+		}
+
+		return 0;
+	}
+#endif
+
 	/*
 	 * A particular protocol callback is mounted here?
 	 *
diff --git a/lib/service.c b/lib/service.c
index 6f08deeb8603d43854bae889031b330766859247..6d7e53893b2d4482e1fc1bb4da97216db474bdce 100644
--- a/lib/service.c
+++ b/lib/service.c
@@ -1203,6 +1203,9 @@ drain:
 				lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP closed it\n");
 				goto close_and_handled;
 			}
+
+			n = 0;
+			goto handled;
 		}
 #endif
 		/*
diff --git a/lib/ssl-client.c b/lib/ssl-client.c
index 45c9fb779508c78b4b9a3f743fe7f58ca043736e..aba337b2f165f094f1ad43c1d329a87a3b41681a 100644
--- a/lib/ssl-client.c
+++ b/lib/ssl-client.c
@@ -318,7 +318,7 @@ lws_ssl_client_connect2(struct lws *wsi)
 	if (wsi->mode == LWSCM_WSCL_WAITING_SSL) {
 		lws_latency_pre(context, wsi);
 		n = SSL_connect(wsi->ssl);
-		lwsl_notice("%s: SSL_connect says %d\n", __func__, n);
+		lwsl_debug("%s: SSL_connect says %d\n", __func__, n);
 
 		lws_latency(context, wsi,
 			    "SSL_connect LWSCM_WSCL_WAITING_SSL", n, n > 0);
@@ -395,7 +395,7 @@ lws_ssl_client_connect2(struct lws *wsi)
 	lws_latency(context, wsi,
 		"SSL_get_verify_result LWS_CONNMODE..HANDSHAKE", n, n > 0);
 
-	lwsl_notice("get_verify says %d\n", n);
+	lwsl_debug("get_verify says %d\n", n);
 
 	if (n != X509_V_OK) {
 		if ((n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
diff --git a/test-server/test-server-http.c b/test-server/test-server-http.c
index eeda0f09eac7ffb43e2415ada03ac0df25bcb758..ea852c2aa9680c80daa7fc073152d007822d128a 100644
--- a/test-server/test-server-http.c
+++ b/test-server/test-server-http.c
@@ -230,38 +230,37 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 			goto try_to_reuse;
 		}
 
-#ifndef LWS_NO_CLIENT
+#if !defined(LWS_NO_CLIENT) && defined(LWS_OPENSSL_SUPPORT)
 		if (!strncmp(in, "/proxytest", 10)) {
 			struct lws_client_connect_info i;
-			char *rootpath = "/";
+			char *rootpath = "/git/";
 			const char *p = (const char *)in;
 
 			if (lws_get_child(wsi))
 				break;
 
 			pss->client_finished = 0;
-			memset(&i,0, sizeof(i));
+			memset(&i, 0, sizeof(i));
 			i.context = lws_get_context(wsi);
-			i.address = "git.libwebsockets.org";
-			i.port = 80;
-			i.ssl_connection = 0;
+			i.address = "libwebsockets.org";
+			i.port = 443;
+			i.ssl_connection = 1;
 			if (p[10])
 				i.path = (char *)in + 10;
 			else
 				i.path = rootpath;
-			i.host = "git.libwebsockets.org";
+			i.host = i.address;
 			i.origin = NULL;
 			i.method = "GET";
 			i.parent_wsi = wsi;
-			i.uri_replace_from = "git.libwebsockets.org/";
+			i.uri_replace_from = "libwebsockets.org/git/";
 			i.uri_replace_to = "/proxytest/";
+
 			if (!lws_client_connect_via_info(&i)) {
 				lwsl_err("proxy connect fail\n");
 				break;
 			}
 
-
-
 			break;
 		}
 #endif
@@ -421,6 +420,11 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 		 */
 		break;
 
+        case LWS_CALLBACK_CLIENT_RECEIVE:
+                ((char *)in)[len] = '\0';
+                lwsl_info("rx %d '%s'\n", (int)len, (char *)in);
+                break;
+
 	case LWS_CALLBACK_HTTP_BODY:
 		/* create the POST argument parser if not already existing */
 		if (!pss->spa) {
@@ -511,8 +515,10 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 		if (pss->client_finished)
 			return -1;
 
-		if (!pss->fop_fd)
+		if (!lws_get_child(wsi) && !pss->fop_fd) {
+			lwsl_notice("fop_fd NULL\n");
 			goto try_to_reuse;
+		}
 
 #ifndef LWS_NO_CLIENT
 		if (pss->reason_bf & 2) {
@@ -524,17 +530,24 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 			 * suitable size to send or what's available, whichever
 			 * is the smaller.
 			 */
+
+
 			pss->reason_bf &= ~2;
 			wsi1 = lws_get_child(wsi);
 			if (!wsi1)
 				break;
 			if (lws_http_client_read(wsi1, &px, &lenx) < 0)
-				goto bail;
+				return -1;
 
 			if (pss->client_finished)
 				return -1;
+
 			break;
 		}
+
+		if (lws_get_child(wsi))
+			break;
+
 #endif
 		/*
 		 * we can send more of whatever it is we were sending
@@ -657,16 +670,12 @@ bail:
 		assert(lws_get_parent(wsi));
 		if (!lws_get_parent(wsi))
 			break;
-		// lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP: wsi %p: sock: %d, parent_wsi: %p, parent_sock:%d,  len %d\n",
-		//		wsi, lws_get_socket_fd(wsi),
-		//		lws_get_parent(wsi),
-		//		lws_get_socket_fd(lws_get_parent(wsi)), len);
 		pss1 = lws_wsi_user(lws_get_parent(wsi));
 		pss1->reason_bf |= 2;
 		lws_callback_on_writable(lws_get_parent(wsi));
 		break;
 	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
-		//lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ len %d\n", len);
+		//lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ len %d\n", (int)len);
 		assert(lws_get_parent(wsi));
 		m = lws_write(lws_get_parent(wsi), (unsigned char *)in,
 				len, LWS_WRITE_HTTP);
diff --git a/test-server/test-server.c b/test-server/test-server.c
index d6ddb9ded18428e6398ac45902c535b0b568da6f..7c1f9eaf7d6e2ff6c3971dcfc04c3d0d2162fc73 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -191,6 +191,7 @@ static struct option options[] = {
 int main(int argc, char **argv)
 {
 	struct lws_context_creation_info info;
+	struct lws_vhost *vhost;
 	char interface_name[128] = "";
 	unsigned int ms, oldms = 0;
 	const char *iface = NULL;
@@ -382,7 +383,7 @@ int main(int argc, char **argv)
 	info.gid = gid;
 	info.uid = uid;
 	info.max_http_header_pool = 16;
-	info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8;
+	info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8 | LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
 	info.extensions = exts;
 	info.timeout_secs = 5;
 	info.ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
@@ -409,6 +410,16 @@ int main(int argc, char **argv)
 		return -1;
 	}
 
+	vhost = lws_create_vhost(context, &info);
+	if (!vhost) {
+		lwsl_err("vhost creation failed\n");
+		return -1;
+	}
+
+#if !defined(LWS_NO_CLIENT) && defined(LWS_OPENSSL_SUPPORT)
+	lws_init_vhost_client_ssl(&info, vhost);
+#endif
+
 	/* this shows how to override the lws file operations.	You don't need
 	 * to do any of this unless you have a reason (eg, want to serve
 	 * compressed files without decompressing the whole archive)