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)