User api additions
------------------
-The info struct gained two new members
+1) The info struct gained two new members
- max_http_header_data: 0 for default (1024) or set the maximum amount of known
http header payload that lws can deal with. Payload in unknown http
for HTTP connections the HTTP callback.
So these settings are not related to the maximum number of simultaneous
-connections but the number of HTTP handshakes that may be expected or ongoing,
+connections, but the number of HTTP handshakes that may be expected or ongoing,
or have just completed, at one time. The reason it's useful is it changes the
memory allocation for header processing to be one-time at context creation
instead of every time there is a new connection, and gives you control over
connections before the accept as necessary, you can still have as many
simultaneous post-header connections as you like.
+User api changes
+----------------
+
+1) LWS_SEND_BUFFER_POST_PADDING is now 0 and deprecated. You can remove it; if
+you still use it, obviously it does nothing. Old binary code with nonzero
+LWS_SEND_BUFFER_POST_PADDING is perfectly compatible, the old code just
+allocated a buffer bigger than needed.
+
+The example apps no longer user it.
+
+The only path who made use of it was sending with LWS_WRITE_CLOSE.
+
+If you use LWS_WRITE_CLOSE by hand in your user code, you need to allow an
+extra 2 bytes space at the end of your buffer. This ONLY applies to
+LWS_WRITE_CLOSE, which you normally don't send directly, but cause by returning
+nonzero from a callback letting the library actually send it.
+
+
v1.6.0-chrome48-firefox42
=======================
n = wsi->protocol->rx_buffer_size;
if (!n)
n = LWS_MAX_SOCKET_IO_BUF;
- n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING;
+ n += LWS_SEND_BUFFER_PRE_PADDING;
wsi->u.ws.rx_user_buffer = lws_malloc(n);
if (!wsi->u.ws.rx_user_buffer) {
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
conn->compressed_out = 0;
conn->buf_pre = NULL;
conn->buf_in = lws_malloc(LWS_SEND_BUFFER_PRE_PADDING +
- conn->buf_in_length +
- LWS_SEND_BUFFER_POST_PADDING);
+ conn->buf_in_length);
if (!conn->buf_in)
goto bail;
conn->buf_out = lws_malloc(LWS_SEND_BUFFER_PRE_PADDING +
- conn->buf_out_length +
- LWS_SEND_BUFFER_POST_PADDING);
+ conn->buf_out_length);
if (!conn->buf_out)
goto bail;
lwsl_ext("zlibs constructed\n");
}
conn->buf_in = lws_realloc(conn->buf_in,
LWS_SEND_BUFFER_PRE_PADDING +
- conn->buf_in_length +
- LWS_SEND_BUFFER_POST_PADDING);
+ conn->buf_in_length);
if (!conn->buf_in) {
lwsl_err("Out of memory\n");
return -1;
}
conn->buf_out = lws_realloc(conn->buf_out,
LWS_SEND_BUFFER_PRE_PADDING +
- conn->buf_out_length +
- LWS_SEND_BUFFER_POST_PADDING);
+ conn->buf_out_length);
if (!conn->buf_out) {
lwsl_err("Out of memory\n");
return -1;
struct lws_context *context = wsi->context;
int n, m, ret, old_state;
struct lws_tokens eff_buf;
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
- LWS_SEND_BUFFER_POST_PADDING];
+ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4];
if (!wsi)
return;
/*
* IMPORTANT NOTICE!
*
- * When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
+ * When sending with websocket protocol
+ *
+ * LWS_WRITE_TEXT,
+ * LWS_WRITE_BINARY,
+ * LWS_WRITE_CONTINUATION,
+ * LWS_WRITE_CLOSE,
+ * LWS_WRITE_PING,
+ * LWS_WRITE_PONG
+ *
* the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
- * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
+ * the buffer pointer you pass to lws_write().
*
* This allows us to add protocol info before and after the data, and send as
* one packet on the network without payload copying, for maximum efficiency.
* So for example you need this kind of code to use lws_write with a
* 128-byte payload
*
- * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
+ * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128];
*
* // fill your part of the buffer... for example here it's all zeros
* memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
*
* lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128, LWS_WRITE_TEXT);
*
- * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
- * use the whole buffer without taking care of the above.
- */
-
-/*
- * this is the frame nonce plus two header plus 8 length
- * there's an additional two for mux extension per mux nesting level
- * 2 byte prepend on close will already fit because control frames cannot use
- * the big length style
- */
-
-/*
+ * When sending
+ *
+ * LWS_WRITE_CLOSE
+ *
+ * only, you must allow your buffer to be 2 bytes longer than otherwise
+ * needed.
+ *
+ * When sending HTTP, with
+ *
+ * LWS_WRITE_HTTP,
+ * LWS_WRITE_HTTP_HEADERS
+ * LWS_WRITE_HTTP_FINAL
+ *
+ * there is no protocol data prepended, and don't need to take care about the
+ * LWS_SEND_BUFFER_PRE_PADDING bytes valid before the buffer pointer.
+ *
+ * LWS_SEND_BUFFER_PRE_PADDING is at least the frame nonce + 2 header + 8 length
+ * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off.
+ * The example apps no longer use it.
+ *
* Pad LWS_SEND_BUFFER_PRE_PADDING to the CPU word size, so that word references
* to the address immediately after the padding won't cause an unaligned access
* error. Sometimes for performance reasons the recommended padding is even
#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \
((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n))
#define LWS_SEND_BUFFER_PRE_PADDING _LWS_PAD(4 + 10)
-#define LWS_SEND_BUFFER_POST_PADDING 4
+#define LWS_SEND_BUFFER_POST_PADDING 0
LWS_VISIBLE LWS_EXTERN int
lws_write(struct lws *wsi, unsigned char *buf, size_t len,
* @wsi: Websocket instance (available from user callback)
* @buf: The data to send. For data being sent on a websocket
* connection (ie, not default http), this buffer MUST have
- * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
- * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
- * in the buffer after (buf + len). This is so the protocol
- * header and trailer data can be added in-situ.
+ * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer.
+ * This is so the protocol header data can be added in-situ.
* @len: Count of the data bytes in the payload starting from buf
* @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one
* of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
n = wsi->protocol->rx_buffer_size;
if (!n)
n = LWS_MAX_SOCKET_IO_BUF;
- n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING;
+ n += LWS_SEND_BUFFER_PRE_PADDING;
wsi->u.ws.rx_user_buffer = lws_malloc(n);
if (!wsi->u.ws.rx_user_buffer) {
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 +
- LWS_SEND_BUFFER_POST_PADDING];
+ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096];
unsigned int rands[4];
int l = 0;
int n;
#define LOCAL_RESOURCE_PATH INSTALL_DATADIR"/libwebsockets-test-server"
struct per_session_data__echo {
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING];
+ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD];
unsigned int len;
unsigned int index;
};
void *user, void *in, size_t len)
{
int n;
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 8000 +
- LWS_SEND_BUFFER_POST_PADDING];
+ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 8000];
struct per_session_data__fraggle *psf = user;
int chunk;
int write_mode = LWS_WRITE_CONTINUATION;
static unsigned int size = 64;
static int flood;
static const char *address;
-static unsigned char pingbuf[LWS_SEND_BUFFER_PRE_PADDING + MAX_MIRROR_PAYLOAD +
- LWS_SEND_BUFFER_POST_PADDING];
+static unsigned char pingbuf[LWS_SEND_BUFFER_PRE_PADDING + MAX_MIRROR_PAYLOAD];
static char peer_name[128];
static unsigned long started;
static int screen_width = 80;
callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
- LWS_SEND_BUFFER_POST_PADDING];
+ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512];
struct per_session_data__dumb_increment *pss =
(struct per_session_data__dumb_increment *)user;
unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
pss->ringbuffer_tail++;
if (((ringbuffer_head - pss->ringbuffer_tail) &
- (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
+ (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15))
lws_rx_flow_allow_all_protocol(lws_get_context(wsi),
lws_get_protocol(wsi));
- if (lws_partial_buffered(wsi) || lws_send_pipe_choked(wsi)) {
+ if (lws_partial_buffered(wsi) ||
+ lws_send_pipe_choked(wsi)) {
lws_callback_on_writable(wsi);
break;
}
free(ringbuffer[ringbuffer_head].payload);
ringbuffer[ringbuffer_head].payload =
- malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
- LWS_SEND_BUFFER_POST_PADDING);
+ malloc(LWS_SEND_BUFFER_PRE_PADDING + len);
ringbuffer[ringbuffer_head].len = len;
memcpy((char *)ringbuffer[ringbuffer_head].payload +
LWS_SEND_BUFFER_PRE_PADDING, in, len);
done:
lws_callback_on_writable_all_protocol(lws_get_context(wsi),
- lws_get_protocol(wsi));
+ lws_get_protocol(wsi));
break;
/*