adopt variant with preamble rx
Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
26d4249a3f
commit
51d9afadd6
6 changed files with 139 additions and 0 deletions
|
@ -53,6 +53,14 @@ User API additions
|
||||||
which lets you set the name of the ECDH curve OpenSSL should use. By
|
which lets you set the name of the ECDH curve OpenSSL should use. By
|
||||||
default (if you leave ecdh_curve NULL) it will use "prime256v1"
|
default (if you leave ecdh_curve NULL) it will use "prime256v1"
|
||||||
|
|
||||||
|
2) MINOR NEWAPI It was already possible to adopt a foreign socket that had not
|
||||||
|
been read from using lws_adopt_socket() since v1.7. Now you can adopt a
|
||||||
|
partially-used socket if you don't need SSL, by passing it what you read
|
||||||
|
so it can drain that before reading from the socket.
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
v1.7.0
|
v1.7.0
|
||||||
|
|
|
@ -1712,6 +1712,9 @@ lws_client_connect_via_info(struct lws_client_connect_info * ccinfo);
|
||||||
|
|
||||||
LWS_VISIBLE LWS_EXTERN struct lws *
|
LWS_VISIBLE LWS_EXTERN struct lws *
|
||||||
lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd);
|
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);
|
||||||
|
|
||||||
LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
|
LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
|
||||||
lws_canonical_hostname(struct lws_context *context);
|
lws_canonical_hostname(struct lws_context *context);
|
||||||
|
|
|
@ -81,6 +81,16 @@ lws_header_table_reset(struct lws *wsi)
|
||||||
|
|
||||||
/* since we will restart the ah, our new headers are not completed */
|
/* since we will restart the ah, our new headers are not completed */
|
||||||
wsi->hdr_parsing_completed = 0;
|
wsi->hdr_parsing_completed = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if we inherited pending rx (from socket adoption deferred
|
||||||
|
* processing), apply and free it.
|
||||||
|
*/
|
||||||
|
if (wsi->u.hdr.preamble_rx) {
|
||||||
|
memcpy(ah->rx, wsi->u.hdr.preamble_rx, wsi->u.hdr.preamble_rx_len);
|
||||||
|
ah->rxlen = wsi->u.hdr.preamble_rx_len;
|
||||||
|
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int LWS_WARN_UNUSED_RESULT
|
int LWS_WARN_UNUSED_RESULT
|
||||||
|
@ -179,6 +189,9 @@ int lws_header_table_detach(struct lws *wsi)
|
||||||
(void *)wsi, (void *)wsi->u.hdr.ah, wsi->tsi,
|
(void *)wsi, (void *)wsi->u.hdr.ah, wsi->tsi,
|
||||||
pt->ah_count_in_use);
|
pt->ah_count_in_use);
|
||||||
|
|
||||||
|
if (wsi->u.hdr.preamble_rx)
|
||||||
|
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
|
||||||
|
|
||||||
/* may not be detached while he still has unprocessed rx */
|
/* may not be detached while he still has unprocessed rx */
|
||||||
if (ah && ah->rxpos != ah->rxlen) {
|
if (ah && ah->rxpos != ah->rxlen) {
|
||||||
lwsl_err("%s: %p: rxpos:%d, rxlen:%d\n", __func__, wsi,
|
lwsl_err("%s: %p: rxpos:%d, rxlen:%d\n", __func__, wsi,
|
||||||
|
|
|
@ -940,6 +940,8 @@ struct _lws_header_related {
|
||||||
/* MUST be first in struct */
|
/* MUST be first in struct */
|
||||||
struct allocated_headers *ah;
|
struct allocated_headers *ah;
|
||||||
struct lws *ah_wait_list;
|
struct lws *ah_wait_list;
|
||||||
|
unsigned char *preamble_rx;
|
||||||
|
unsigned int preamble_rx_len;
|
||||||
enum uri_path_states ups;
|
enum uri_path_states ups;
|
||||||
enum uri_esc_states ues;
|
enum uri_esc_states ues;
|
||||||
short lextable_pos;
|
short lextable_pos;
|
||||||
|
|
74
lib/server.c
74
lib/server.c
|
@ -821,6 +821,80 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
|
||||||
|
* @context: lws context
|
||||||
|
* @accept_fd: fd of already-accepted socket to adopt
|
||||||
|
* @readbuf: NULL or pointer to data that must be drained before reading from
|
||||||
|
* accept_fd
|
||||||
|
* @len: The length of the data held at @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 @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_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
|
||||||
|
const char *readbuf, size_t len)
|
||||||
|
{
|
||||||
|
struct lws *wsi = lws_adopt_socket(context, accept_fd);
|
||||||
|
struct allocated_headers *ah;
|
||||||
|
|
||||||
|
if (!wsi)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!readbuf)
|
||||||
|
return wsi;
|
||||||
|
|
||||||
|
if (len > sizeof(ah->rx)) {
|
||||||
|
lwsl_err("%s: rx in too big\n", __func__);
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* we can't process the initial read data until we can attach an ah.
|
||||||
|
*
|
||||||
|
* if one is available, get it and place the data in his ah rxbuf...
|
||||||
|
* wsi with ah that have pending rxbuf get auto-POLLIN service.
|
||||||
|
*/
|
||||||
|
if (!lws_header_table_attach(wsi)) {
|
||||||
|
ah = wsi->u.hdr.ah;
|
||||||
|
memcpy(ah->rx, readbuf, len);
|
||||||
|
ah->rxpos = 0;
|
||||||
|
ah->rxlen = len;
|
||||||
|
|
||||||
|
return wsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hum if no ah came, we are on the wait list and must defer
|
||||||
|
* dealing with this until the ah arrives.
|
||||||
|
*
|
||||||
|
* later successful lws_header_table_attach() will apply the
|
||||||
|
* below to the rx buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
wsi->u.hdr.preamble_rx = lws_malloc(len);
|
||||||
|
wsi->u.hdr.preamble_rx_len = len;
|
||||||
|
|
||||||
|
return wsi;
|
||||||
|
|
||||||
|
bail:
|
||||||
|
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
LWS_VISIBLE int
|
LWS_VISIBLE int
|
||||||
lws_server_socket_service(struct lws_context *context, struct lws *wsi,
|
lws_server_socket_service(struct lws_context *context, struct lws *wsi,
|
||||||
struct lws_pollfd *pollfd)
|
struct lws_pollfd *pollfd)
|
||||||
|
|
|
@ -790,6 +790,42 @@ LWS adopts the socket in http serving mode, it's ready to accept an upgrade
|
||||||
to ws or just serve http.
|
to ws or just serve http.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<hr>
|
<hr>
|
||||||
|
<h2>lws_adopt_socket_readbuf - adopt foreign socket and first rx as if listen socket accepted it</h2>
|
||||||
|
<i>LWS_EXTERN struct lws *</i>
|
||||||
|
<b>lws_adopt_socket_readbuf</b>
|
||||||
|
(<i>struct lws_context *</i> <b>context</b>,
|
||||||
|
<i>lws_sockfd_type</i> <b>accept_fd</b>,
|
||||||
|
<i>const char *</i> <b>readbuf</b>,
|
||||||
|
<i>size_t</i> <b>len</b>)
|
||||||
|
<h3>Arguments</h3>
|
||||||
|
<dl>
|
||||||
|
<dt><b>context</b>
|
||||||
|
<dd>lws context
|
||||||
|
<dt><b>accept_fd</b>
|
||||||
|
<dd>fd of already-accepted socket to adopt
|
||||||
|
<dt><b>readbuf</b>
|
||||||
|
<dd>NULL or pointer to data that must be drained before reading from
|
||||||
|
accept_fd
|
||||||
|
<dt><b>len</b>
|
||||||
|
<dd>The length of the data held at <tt><b>readbuf</b></tt>
|
||||||
|
</dl>
|
||||||
|
<h3>Description</h3>
|
||||||
|
<blockquote>
|
||||||
|
Either returns new wsi bound to accept_fd, or closes accept_fd and
|
||||||
|
returns NULL, having cleaned up any new wsi pieces.
|
||||||
|
<p>
|
||||||
|
LWS adopts the socket in http serving mode, it's ready to accept an upgrade
|
||||||
|
to ws or just serve http.
|
||||||
|
<p>
|
||||||
|
If your external code did not already read from the socket, you can use
|
||||||
|
<b>lws_adopt_socket</b> instead.
|
||||||
|
<p>
|
||||||
|
This api is guaranteed to use the data at <tt><b>readbuf</b></tt> first, before reading from
|
||||||
|
the socket.
|
||||||
|
<p>
|
||||||
|
<tt><b>readbuf</b></tt> is limited to the size of the ah rx buf, currently 2048 bytes.
|
||||||
|
</blockquote>
|
||||||
|
<hr>
|
||||||
<h2>lws_serve_http_file - Send a file back to the client using http</h2>
|
<h2>lws_serve_http_file - Send a file back to the client using http</h2>
|
||||||
<i>int</i>
|
<i>int</i>
|
||||||
<b>lws_serve_http_file</b>
|
<b>lws_serve_http_file</b>
|
||||||
|
@ -1518,6 +1554,7 @@ header.
|
||||||
<i>unsigned int</i> <b>count_threads</b>;<br>
|
<i>unsigned int</i> <b>count_threads</b>;<br>
|
||||||
<i>unsigned int</i> <b>fd_limit_per_thread</b>;<br>
|
<i>unsigned int</i> <b>fd_limit_per_thread</b>;<br>
|
||||||
<i>unsigned int</i> <b>timeout_secs</b>;<br>
|
<i>unsigned int</i> <b>timeout_secs</b>;<br>
|
||||||
|
<i>const char *</i> <b>ecdh_curve</b>;<br>
|
||||||
};<br>
|
};<br>
|
||||||
<h3>Members</h3>
|
<h3>Members</h3>
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -1613,6 +1650,8 @@ limit by the number of threads.
|
||||||
library are protected from hanging forever by timeouts. If
|
library are protected from hanging forever by timeouts. If
|
||||||
nonzero, this member lets you set the timeout used in seconds.
|
nonzero, this member lets you set the timeout used in seconds.
|
||||||
Otherwise a default timeout is used.
|
Otherwise a default timeout is used.
|
||||||
|
<dt><b>ecdh_curve</b>
|
||||||
|
<dd>if NULL, defaults to initializing server with "prime256v1"
|
||||||
</dl>
|
</dl>
|
||||||
<hr>
|
<hr>
|
||||||
<h2>struct lws_client_connect_info - parameters to connect with when using lws_client_connect_via_info()</h2>
|
<h2>struct lws_client_connect_info - parameters to connect with when using lws_client_connect_via_info()</h2>
|
||||||
|
|
Loading…
Add table
Reference in a new issue