server: expose lws_adopt_socket_vhost() as public API

Allows a socket to be adopted and associated with an existing vhost.
Also added corresponding  lws_adopt_socket_vhost_readbuf()
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 98debfd..d7f7df6 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -3579,6 +3579,7 @@
 
 /**
  * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it
+ * for the default vhost of context.
  * \param context: lws context
  * \param accept_fd: fd of already-accepted socket to adopt
  *
@@ -3591,7 +3592,22 @@
 LWS_VISIBLE LWS_EXTERN struct lws *
 lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd);
 /**
+ * lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted it
+ * for vhost
+ * \param vhost: lws vhost
+ * \param accept_fd: fd of already-accepted socket to adopt
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ *
+ * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
+ * to ws or just serve http.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
+/**
  * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
+ * for the default vhost of context.
  * \param context:	lws context
  * \param accept_fd:	fd of already-accepted socket to adopt
  * \param readbuf:	NULL or pointer to data that must be drained before reading from
@@ -3614,7 +3630,33 @@
  */
 LWS_VISIBLE LWS_EXTERN struct lws *
 lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
-		const char *readbuf, size_t len);
+                         const char *readbuf, size_t len);
+/**
+ * lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket
+ * accepted it for vhost.
+ * \param vhost:	lws vhost
+ * \param accept_fd:	fd of already-accepted socket to adopt
+ * \param readbuf:	NULL or pointer to data that must be drained before reading from
+ *			accept_fd
+ * \param len:		The length of the data held at \param readbuf
+ *
+ * Either returns new wsi bound to accept_fd, or closes accept_fd and
+ * returns NULL, having cleaned up any new wsi pieces.
+ *
+ * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
+ * to ws or just serve http.
+ *
+ * If your external code did not already read from the socket, you can use
+ * lws_adopt_socket() instead.
+ *
+ * This api is guaranteed to use the data at \param readbuf first, before reading from
+ * the socket.
+ *
+ * readbuf is limited to the size of the ah rx buf, currently 2048 bytes.
+ */
+LWS_VISIBLE LWS_EXTERN struct lws *
+lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, lws_sockfd_type accept_fd,
+                               const char *readbuf, size_t len);
 ///@}
 
 /** \defgroup net Network related helper APIs
diff --git a/lib/server.c b/lib/server.c
index 45f691b..bc9033a 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -1672,7 +1672,7 @@
 	return 0;
 }
 
-struct lws *
+LWS_VISIBLE struct lws *
 lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd)
 {
 	struct lws_context *context = vh->context;
@@ -1745,11 +1745,10 @@
 	return lws_adopt_socket_vhost(context->vhost_list, accept_fd);
 }
 
-LWS_VISIBLE LWS_EXTERN struct lws *
-lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
-			 const char *readbuf, size_t len)
+/* Common read-buffer adoption for lws_adopt_*_readbuf */
+static struct lws*
+adopt_socket_readbuf(struct lws *wsi, const char *readbuf, size_t len)
 {
-	struct lws *wsi = lws_adopt_socket(context, accept_fd);
 	struct lws_context_per_thread *pt;
 	struct allocated_headers *ah;
 	struct lws_pollfd *pfd;
@@ -1757,7 +1756,7 @@
 	if (!wsi)
 		return NULL;
 
-	if (!readbuf)
+	if (!readbuf || len == 0)
 		return wsi;
 
 	if (len > sizeof(ah->rx)) {
@@ -1782,7 +1781,7 @@
 		ah->rxlen = len;
 
 		lwsl_notice("%s: calling service on readbuf ah\n", __func__);
-		pt = &context->pt[(int)wsi->tsi];
+		pt = &wsi->context->pt[(int)wsi->tsi];
 
 		/* unlike a normal connect, we have the headers already
 		 * (or the first part of them anyway).
@@ -1792,7 +1791,7 @@
 		pfd = &pt->fds[wsi->position_in_fds_table];
 		pfd->revents |= LWS_POLLIN;
 		lwsl_err("%s: calling service\n", __func__);
-		if (lws_service_fd_tsi(context, pfd, wsi->tsi))
+		if (lws_service_fd_tsi(wsi->context, pfd, wsi->tsi))
 			/* service closed us */
 			return NULL;
 
@@ -1822,6 +1821,20 @@
 	return NULL;
 }
 
+LWS_VISIBLE struct lws *
+lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
+			 const char *readbuf, size_t len)
+{
+        return adopt_socket_readbuf(lws_adopt_socket(context, accept_fd), readbuf, len);
+}
+
+LWS_VISIBLE struct lws *
+lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, lws_sockfd_type accept_fd,
+			 const char *readbuf, size_t len)
+{
+        return adopt_socket_readbuf(lws_adopt_socket_vhost(vhost, accept_fd), readbuf, len);
+}
+
 LWS_VISIBLE int
 lws_server_socket_service(struct lws_context *context, struct lws *wsi,
 			  struct lws_pollfd *pollfd)