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()
This commit is contained in:
Alan Conway 2016-12-21 09:32:16 +08:00 committed by Andy Green
parent be9fb919d1
commit acdf0c7066
2 changed files with 64 additions and 9 deletions

View file

@ -3579,6 +3579,7 @@ lws_remaining_packet_payload(struct lws *wsi);
/**
* 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
*
@ -3590,8 +3591,23 @@ lws_remaining_packet_payload(struct lws *wsi);
*/
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_adopt_socket(struct lws_context *context, lws_sockfd_type 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);
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

View file

@ -1672,7 +1672,7 @@ lws_http_transaction_completed(struct lws *wsi)
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 @@ lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd)
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 @@ lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
if (!wsi)
return NULL;
if (!readbuf)
if (!readbuf || len == 0)
return wsi;
if (len > sizeof(ah->rx)) {
@ -1782,7 +1781,7 @@ lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
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 @@ lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
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 @@ bail:
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)