libwebsockets
Lightweight C library for HTML5 websockets
lws-write.h File Reference

Go to the source code of this file.

Data Structures

struct  lws_write_passthru
 

Macros

#define LWS_WRITE_RAW   LWS_WRITE_HTTP
 
#define lws_write_http(wsi, buf, len)    lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP)
 

Enumerations

enum  lws_write_protocol {
  LWS_WRITE_TEXT = 0 , LWS_WRITE_BINARY = 1 , LWS_WRITE_CONTINUATION = 2 , LWS_WRITE_HTTP = 3 ,
  LWS_WRITE_PING = 5 , LWS_WRITE_PONG = 6 , LWS_WRITE_HTTP_FINAL = 7 , LWS_WRITE_HTTP_HEADERS = 8 ,
  LWS_WRITE_HTTP_HEADERS_CONTINUATION = 9 , LWS_WRITE_BUFLIST = 0x20 , LWS_WRITE_NO_FIN = 0x40 , LWS_WRITE_H2_STREAM_END = 0x80 ,
  LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
}
 

Functions

LWS_VISIBLE LWS_EXTERN int lws_write (struct lws *wsi, unsigned char *buf, size_t len, enum lws_write_protocol protocol)
 
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_raw_transaction_completed (struct lws *wsi)
 

Data Structure Documentation

◆ lws_write_passthru

struct lws_write_passthru

Definition at line 100 of file lws-write.h.

+ Collaboration diagram for lws_write_passthru:
Data Fields
struct lws * wsi
unsigned char * buf
size_t len
enum lws_write_protocol wp

Macro Definition Documentation

◆ LWS_WRITE_RAW

#define LWS_WRITE_RAW   LWS_WRITE_HTTP

Definition at line 30 of file lws-write.h.

◆ lws_write_http

#define lws_write_http (   wsi,
  buf,
  len 
)     lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP)

Definition at line 213 of file lws-write.h.

Enumeration Type Documentation

◆ lws_write_protocol

Enumerator
LWS_WRITE_TEXT 

Send a ws TEXT message,the pointer must have LWS_PRE valid memory behind it.

The receiver expects only valid utf-8 in the payload

LWS_WRITE_BINARY 

Send a ws BINARY message, the pointer must have LWS_PRE valid memory behind it.

Any sequence of bytes is valid

LWS_WRITE_CONTINUATION 

Continue a previous ws message, the pointer must have LWS_PRE valid memory behind it

LWS_WRITE_HTTP 

Send HTTP content

LWS_WRITE_PING 
LWS_WRITE_PONG 
LWS_WRITE_HTTP_FINAL 
LWS_WRITE_HTTP_HEADERS 

Send http headers (http2 encodes this payload and LWS_WRITE_HTTP payload differently, http 1.x links also handle this correctly. so to be compatible with both in the future,header response part should be sent using this regardless of http version expected)

LWS_WRITE_HTTP_HEADERS_CONTINUATION 

Continuation of http/2 headers

LWS_WRITE_BUFLIST 

Don't actually write it... stick it on the output buflist and write it as soon as possible. Useful if you learn you have to write something, have the data to write to hand but the timing is unrelated as to whether the connection is writable or not, and were otherwise going to have to allocate a temp buffer and write it later anyway

LWS_WRITE_NO_FIN 

This part of the message is not the end of the message

LWS_WRITE_H2_STREAM_END 

Flag indicates this packet should go out with STREAM_END if h2 STREAM_END is allowed on DATA or HEADERS.

LWS_WRITE_CLIENT_IGNORE_XOR_MASK 

client packet payload goes out on wire unmunged only useful for security tests since normal servers cannot decode the content if used

Definition at line 36 of file lws-write.h.

36 {
53 /* LWS_WRITE_CLOSE is handled by lws_close_reason() */
56
57 /* Same as write_http but we know this write ends the transaction */
59
60 /* HTTP2 */
61
72 /****** add new things just above ---^ ******/
73
74 /* flags */
75
76 LWS_WRITE_BUFLIST = 0x20,
84 LWS_WRITE_NO_FIN = 0x40,
96};
@ LWS_WRITE_CONTINUATION
Definition: lws-write.h:47
@ LWS_WRITE_NO_FIN
Definition: lws-write.h:84
@ LWS_WRITE_CLIENT_IGNORE_XOR_MASK
Definition: lws-write.h:92
@ LWS_WRITE_H2_STREAM_END
Definition: lws-write.h:87
@ LWS_WRITE_PING
Definition: lws-write.h:54
@ LWS_WRITE_TEXT
Definition: lws-write.h:37
@ LWS_WRITE_PONG
Definition: lws-write.h:55
@ LWS_WRITE_HTTP
Definition: lws-write.h:50
@ LWS_WRITE_HTTP_FINAL
Definition: lws-write.h:58
@ LWS_WRITE_BINARY
Definition: lws-write.h:42
@ LWS_WRITE_BUFLIST
Definition: lws-write.h:76
@ LWS_WRITE_HTTP_HEADERS_CONTINUATION
Definition: lws-write.h:68
@ LWS_WRITE_HTTP_HEADERS
Definition: lws-write.h:62

Function Documentation

◆ lws_write()

LWS_VISIBLE LWS_EXTERN int lws_write ( struct lws *  wsi,
unsigned char *  buf,
size_t  len,
enum lws_write_protocol  protocol 
)

lws_write() - Apply protocol then write data to client

Parameters
wsiWebsocket instance (available from user callback)
bufThe data to send. For data being sent on a websocket connection (ie, not default http), this buffer MUST have LWS_PRE bytes valid BEFORE the pointer. This is so the protocol header data can be added in-situ.
lenCount of the data bytes in the payload starting from buf
protocolUse LWS_WRITE_HTTP to reply to an http connection, and one of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate data on a websockets connection. Remember to allow the extra bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT are used.

This function provides the way to issue data back to the client, for any role (h1, h2, ws, raw, etc). It can only be called from the WRITEABLE callback.

IMPORTANT NOTICE!

When sending with ws protocol

LWS_WRITE_TEXT, LWS_WRITE_BINARY, LWS_WRITE_CONTINUATION, LWS_WRITE_PING, LWS_WRITE_PONG,

or sending on http/2... the send buffer has to have LWS_PRE bytes valid BEFORE the buffer pointer you pass to lws_write(). Since you'll probably want to use http/2 before too long, it's wise to just always do this with lws_write buffers... LWS_PRE is typically 16 bytes it's not going to hurt usually.

start of alloc ptr passed to lws_write end of allocation | | | v <– LWS_PRE bytes --> v v [-------------— allocated memory ------------—] (for lws use) [====== user buffer ======]

This allows us to add protocol info before 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_PRE + 128];

// fill your part of the buffer... for example here it's all zeros memset(&buf[LWS_PRE], 0, 128);

if (lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT) < 128) { ... the connection is dead ... return -1; }

LWS_PRE is currently 16, which covers ws and h2 frame headers, and is compatible with 32 and 64-bit alignment requirements.

(LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off.)

Return may be -1 is the write failed in a way indicating that the connection has ended already, in which case you can close your side, or a positive number that is at least the number of bytes requested to send (under some encapsulation scenarios, it can indicate more than you asked was sent).

The recommended test of the return is less than what you asked indicates the connection has failed.

Truncated Writes

The OS may not accept everything you asked to write on the connection.

Posix defines POLLOUT indication from poll() to show that the connection will accept more write data, but it doesn't specifiy how much. It may just accept one byte of whatever you wanted to send.

LWS will buffer the remainder automatically, and send it out autonomously.

During that time, WRITABLE callbacks to user code will be suppressed and instead used internally. After it completes, it will send an extra WRITEABLE callback to the user code, in case any request was missed. So it is possible to receive unasked-for WRITEABLE callbacks, the user code should have enough state to know if it wants to write anything and just return if not.

This is to handle corner cases where unexpectedly the OS refuses what we usually expect it to accept. It's not recommended as the way to randomly send huge payloads, since it is being copied on to heap and is inefficient.

Huge payloads should instead be sent in fragments that are around 2 x mtu, which is almost always directly accepted by the OS. To simplify this for ws fragments, there is a helper lws_write_ws_flags() below that simplifies selecting the correct flags to give lws_write() for each fragment.

In the case of RFC8441 ws-over-h2, you cannot send ws fragments larger than the max h2 frame size, typically 16KB, but should further restrict it to the same ~2 x mtu limit mentioned above.

◆ lws_raw_transaction_completed()

LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_raw_transaction_completed ( struct lws *  wsi)

lws_raw_transaction_completed() - Helper for flushing before close

Parameters
wsithe struct lws to operate on

Returns -1 if the wsi can close now. However if there is buffered, unsent data, the wsi is marked as to be closed when the output buffer data is drained, and it returns 0.

For raw cases where the transaction completed without failure, return lws_raw_transaction_completed(wsi) should better be used than return -1.