diff --git a/changelog b/changelog
index 8ce86c9febdcdcfe77917db7f079b7aadba715dd..c226613b5b424e62a651f37b56415e3d7069edaf 100644
--- a/changelog
+++ b/changelog
@@ -80,6 +80,10 @@ protocol string to its argument in URL format.  If so, it stays in http[s]
 client mode and doesn't upgrade to ws[s], allowing you to do generic http client
 operations.
 
+9) The test server has a new URI path http://localhost:7681/proxytest
+If you visit here, a client connection to http://example.com:80 is spawned,
+and the results piped on to your original connection.
+
 
 User API additions
 ------------------
diff --git a/test-server/test-server-http.c b/test-server/test-server-http.c
index b2f8817071e3945919f5b1d9ecb0043df4ccda34..4de62e8bd1fa7d5d83136db26312abf73a9fea0d 100644
--- a/test-server/test-server-http.c
+++ b/test-server/test-server-http.c
@@ -117,7 +117,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 		  void *in, size_t len)
 {
 	struct per_session_data__http *pss =
-			(struct per_session_data__http *)user;
+			(struct per_session_data__http *)user, *pss1;
 	unsigned char buffer[4096 + LWS_PRE];
 	unsigned long amount, file_len, sent;
 	char leaf_path[1024];
@@ -167,6 +167,32 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 			goto try_to_reuse;
 		}
 
+#ifndef LWS_NO_CLIENT
+		if (!strcmp(in, "/proxytest")) {
+			struct lws_client_connect_info i;
+
+			if (lws_get_child(wsi))
+				break;
+
+			pss->client_finished = 0;
+			memset(&i,0, sizeof(i));
+			i.context = lws_get_context(wsi);
+			i.address = "example.com";
+			i.port = 80;
+			i.ssl_connection = 0;
+			i.path = "/";
+			i.host = "example.com";
+			i.origin = NULL;
+			i.method = "GET";
+			i.parent_wsi = wsi;
+			if (!lws_client_connect_via_info(&i)) {
+				lwsl_err("proxy connect fail\n");
+				break;
+			}
+			break;
+		}
+#endif
+
 #ifdef LWS_WITH_CGI
 		if (!strcmp(in, "/cgitest")) {
 			static char *cmd[] = {
@@ -366,6 +392,9 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 	case LWS_CALLBACK_HTTP_WRITEABLE:
 		lwsl_info("LWS_CALLBACK_HTTP_WRITEABLE\n");
 
+		if (pss->client_finished)
+			return -1;
+
 		if (pss->fd == LWS_INVALID_FILE)
 			goto try_to_reuse;
 #ifdef LWS_WITH_CGI
@@ -460,6 +489,56 @@ bail:
 		/* if we returned non-zero from here, we kill the connection */
 		break;
 
+#ifndef LWS_WITH_CLIENT
+	case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP:
+		p = buffer + LWS_PRE;
+		end = p + sizeof(buffer) - LWS_PRE;
+		if (lws_add_http_header_status(lws_get_parent(wsi), 200, &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;
+		if (lws_add_http_header_by_token(lws_get_parent(wsi),
+				WSI_TOKEN_HTTP_CONTENT_TYPE,
+			    	(unsigned char *)"text/html", 9, &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", buffer + LWS_PRE);
+
+		n = lws_write(lws_get_parent(wsi), buffer + LWS_PRE,
+			      p - (buffer + LWS_PRE),
+			      LWS_WRITE_HTTP_HEADERS);
+		if (n < 0)
+			return -1;
+
+		break;
+	case LWS_CALLBACK_CLOSED_CLIENT_HTTP:
+		return -1;
+		break;
+	case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
+		m = lws_write(lws_get_parent(wsi), in, len, LWS_WRITE_HTTP);
+		if (m < 0)
+			return 1;
+		break;
+	case LWS_CALLBACK_COMPLETED_CLIENT_HTTP:
+		pss1 = lws_wsi_user(lws_get_parent(wsi));
+		pss1->client_finished = 1;
+		lws_callback_on_writable(lws_get_parent(wsi));
+		return -1;
+		break;
+#endif
+
 #ifdef LWS_WITH_CGI
 	/* CGI IO events (POLLIN/OUT) appear here our demo user code policy is
 	 *
diff --git a/test-server/test-server.h b/test-server/test-server.h
index 7217621e4a7a220964df5f0e28b1a65fb967561a..a546904ffe1fd9034a6cae7e0e7a0e488d3b262b 100644
--- a/test-server/test-server.h
+++ b/test-server/test-server.h
@@ -71,6 +71,7 @@ struct per_session_data__http {
 	struct lws_cgi_args args;
 	int reason_bf;
 #endif
+	unsigned int client_finished:1;
 };
 
 /*