clean--fix-sigpipe.patch
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
4739e5c450
commit
6964bb5ee5
9 changed files with 255 additions and 118 deletions
|
@ -89,13 +89,13 @@ libwebsocket_client_connect(struct libwebsocket_context *clients,
|
|||
"61AC5F19-FBBA-4540-B96F-6561F1AB40A8";
|
||||
char pkt[1024];
|
||||
char *p = &pkt[0];
|
||||
const char * pc;
|
||||
const char *pc;
|
||||
int len;
|
||||
int okay = 0;
|
||||
struct libwebsocket *wsi;
|
||||
int n;
|
||||
|
||||
wsi = malloc(sizeof (struct libwebsocket));
|
||||
wsi = malloc(sizeof(struct libwebsocket));
|
||||
if (wsi == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -123,7 +123,7 @@ libwebsocket_client_connect(struct libwebsocket_context *clients,
|
|||
}
|
||||
|
||||
wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
|
||||
if (wsi->sock < 0) {
|
||||
fprintf(stderr, "Unable to open socket\n");
|
||||
goto bail1;
|
||||
|
@ -139,11 +139,11 @@ libwebsocket_client_connect(struct libwebsocket_context *clients,
|
|||
sizeof(struct sockaddr)) == -1) {
|
||||
fprintf(stderr, "Connect failed");
|
||||
goto bail1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create the random key
|
||||
*/
|
||||
/*
|
||||
* create the random key
|
||||
*/
|
||||
|
||||
fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
|
||||
if (fd < 1) {
|
||||
|
@ -160,7 +160,7 @@ libwebsocket_client_connect(struct libwebsocket_context *clients,
|
|||
}
|
||||
close(fd);
|
||||
|
||||
lws_b64_encode_string(hash, 16, key_b64, sizeof key_b64);
|
||||
lws_b64_encode_string(hash, 16, key_b64, sizeof key_b64);
|
||||
|
||||
/*
|
||||
* 04 example client handshake
|
||||
|
@ -283,7 +283,7 @@ libwebsocket_client_connect(struct libwebsocket_context *clients,
|
|||
" Upgrade header '%s'\n",
|
||||
wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
|
||||
goto bail2;
|
||||
}
|
||||
}
|
||||
|
||||
strtolower(wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
|
||||
if (strcmp(wsi->utf8_token[WSI_TOKEN_CONNECTION].token, "upgrade")) {
|
||||
|
|
|
@ -376,7 +376,7 @@ handshake_04(struct libwebsocket *wsi)
|
|||
m += nonce_len;
|
||||
strcpy(m, websocket_magic_guid_04_masking);
|
||||
m += strlen(websocket_magic_guid_04_masking);
|
||||
|
||||
|
||||
SHA1((unsigned char *)mask_summing_buf, m - mask_summing_buf,
|
||||
wsi->masking_key_04);
|
||||
|
||||
|
@ -564,9 +564,9 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0)
|
||||
goto bail;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -576,5 +576,6 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len)
|
|||
|
||||
bail:
|
||||
libwebsocket_close_and_free_session(wsi);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,8 @@ libwebsocket_poll_connections(struct libwebsocket_context *this)
|
|||
if (this->fds[client].revents & (POLLERR | POLLHUP)) {
|
||||
|
||||
debug("Session Socket %d %p (fd=%d) dead\n",
|
||||
client, this->wsi[client], this->fds[client]);
|
||||
client, (void *)this->wsi[client],
|
||||
this->fds[client].fd);
|
||||
|
||||
libwebsocket_close_and_free_session(this->wsi[client]);
|
||||
goto nuke_this;
|
||||
|
@ -132,7 +133,7 @@ libwebsocket_poll_connections(struct libwebsocket_context *this)
|
|||
continue;
|
||||
|
||||
/* only to clients connected to us */
|
||||
|
||||
|
||||
if (wsi->client_mode)
|
||||
continue;
|
||||
|
||||
|
@ -174,9 +175,9 @@ libwebsocket_poll_connections(struct libwebsocket_context *this)
|
|||
|
||||
/* service incoming data */
|
||||
|
||||
if (libwebsocket_read(this->wsi[client], buf, n) >= 0)
|
||||
n = libwebsocket_read(this->wsi[client], buf, n);
|
||||
if (n >= 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* it closed and nuked wsi[client], so remove the
|
||||
* socket handle and wsi from our service list
|
||||
|
@ -184,19 +185,82 @@ libwebsocket_poll_connections(struct libwebsocket_context *this)
|
|||
nuke_this:
|
||||
|
||||
debug("nuking wsi %p, fsd_count = %d\n",
|
||||
this->wsi[client], this->fds_count - 1);
|
||||
(void *)this->wsi[client], this->fds_count - 1);
|
||||
|
||||
this->fds_count--;
|
||||
for (n = client; n < this->fds_count; n++) {
|
||||
this->fds[n] = this->fds[n + 1];
|
||||
this->wsi[n] = this->wsi[n + 1];
|
||||
}
|
||||
break;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsocket_context_destroy() - Destroy the websocket context
|
||||
* @this: Websocket context
|
||||
*
|
||||
* This function closes any active connections and then frees the
|
||||
* context. After calling this, any further use of the context is
|
||||
* undefined.
|
||||
*/
|
||||
void
|
||||
libwebsocket_context_destroy(struct libwebsocket_context *this)
|
||||
{
|
||||
int client;
|
||||
|
||||
/* close listening skt and per-protocol broadcast sockets */
|
||||
for (client = 0; client < this->fds_count; client++)
|
||||
libwebsocket_close_and_free_session(this->wsi[client]);
|
||||
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
if (ssl_ctx)
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
#endif
|
||||
|
||||
if (this)
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsocket_service() - Service any pending websocket activity
|
||||
* @this: Websocket context
|
||||
* @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed
|
||||
* service otherwise block and service immediately, returning
|
||||
* after the timeout if nothing needed service.
|
||||
*
|
||||
* This function deals with any pending websocket traffic, for three
|
||||
* kinds of event. It handles these events on both server and client
|
||||
* types of connection the same.
|
||||
*
|
||||
* 1) Accept new connections to our context's server
|
||||
*
|
||||
* 2) Perform pending broadcast writes initiated from other forked
|
||||
* processes (effectively serializing asynchronous broadcasts)
|
||||
*
|
||||
* 3) Call the receive callback for incoming frame data received by
|
||||
* server or client connections.
|
||||
*
|
||||
* You need to call this service function periodically to all the above
|
||||
* functions to happen; if your application is single-threaded you can
|
||||
* just call it in your main event loop.
|
||||
*
|
||||
* Alternatively you can fork a new process that asynchronously handles
|
||||
* calling this service in a loop. In that case you are happy if this
|
||||
* call blocks your thread until it needs to take care of something and
|
||||
* would call it with a large nonzero timeout. Your loop then takes no
|
||||
* CPU while there is nothing happening.
|
||||
*
|
||||
* If you are calling it in a single-threaded app, you don't want it to
|
||||
* wait around blocking other things in your loop from happening, so you
|
||||
* would call it with a timeout_ms of 0, so it returns immediately if
|
||||
* nothing is pending, or as soon as it services whatever was pending.
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
libwebsocket_service(struct libwebsocket_context *this, int timeout_ms)
|
||||
|
@ -218,7 +282,7 @@ libwebsocket_service(struct libwebsocket_context *this, int timeout_ms)
|
|||
n = poll(this->fds, this->fds_count, timeout_ms);
|
||||
else
|
||||
n = poll(&this->fds[1], this->fds_count - 1, timeout_ms);
|
||||
|
||||
|
||||
|
||||
if (n < 0 || this->fds[0].revents & (POLLERR | POLLHUP)) {
|
||||
fprintf(stderr, "Listen Socket dead\n");
|
||||
|
@ -369,6 +433,8 @@ fill_in_fds:
|
|||
|
||||
fatal:
|
||||
|
||||
fprintf(stderr, "service hits fatal\n");
|
||||
|
||||
/* close listening skt and per-protocol broadcast sockets */
|
||||
for (client = 0; client < this->fds_count; client++)
|
||||
close(this->fds[0].fd);
|
||||
|
@ -376,7 +442,6 @@ fatal:
|
|||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
#endif
|
||||
kill(0, SIGTERM);
|
||||
|
||||
if (this)
|
||||
free(this);
|
||||
|
@ -392,12 +457,12 @@ fatal:
|
|||
/**
|
||||
* libwebsocket_create_context() - Create the websocket handler
|
||||
* @port: Port to listen on... you can use 0 to suppress listening on
|
||||
* any port, that's what you want if you are not running a
|
||||
* websocket server at all but just using it as a client
|
||||
* any port, that's what you want if you are not running a
|
||||
* websocket server at all but just using it as a client
|
||||
* @protocols: Array of structures listing supported protocols and a protocol-
|
||||
* specific callback for each one. The list is ended with an
|
||||
* entry that has a NULL callback pointer.
|
||||
* It's not const because we write the owning_server member
|
||||
* It's not const because we write the owning_server member
|
||||
* @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
|
||||
* to listen using SSL, set to the filepath to fetch the
|
||||
* server cert from, otherwise NULL for unencrypted
|
||||
|
@ -644,10 +709,10 @@ libwebsocket_create_context(int port,
|
|||
/**
|
||||
* libwebsockets_fork_service_loop() - Optional helper function forks off
|
||||
* a process for the websocket server loop.
|
||||
* You don't have to use this but if not, you
|
||||
* have to make sure you are calling
|
||||
* libwebsocket_service periodically to service
|
||||
* the websocket traffic
|
||||
* You don't have to use this but if not, you
|
||||
* have to make sure you are calling
|
||||
* libwebsocket_service periodically to service
|
||||
* the websocket traffic
|
||||
* @this: server context returned by creation function
|
||||
*/
|
||||
|
||||
|
@ -798,7 +863,7 @@ libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
|
|||
* set up when the websocket server initializes
|
||||
*/
|
||||
|
||||
n = send(protocol->broadcast_socket_user_fd, buf, len, 0);
|
||||
n = send(protocol->broadcast_socket_user_fd, buf, len, MSG_NOSIGNAL);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -59,11 +59,11 @@ struct libwebsocket_context;
|
|||
*
|
||||
* This callback is the way the user controls what is served. All the
|
||||
* protocol detail is hidden and handled by the library.
|
||||
*
|
||||
*
|
||||
* For each connection / session there is user data allocated that is
|
||||
* pointed to by "user". You set the size of this user data area when
|
||||
* the library is initialized with libwebsocket_create_server.
|
||||
*
|
||||
*
|
||||
* You get an opportunity to initialize user data when called back with
|
||||
* LWS_CALLBACK_ESTABLISHED reason.
|
||||
*
|
||||
|
@ -77,45 +77,45 @@ struct libwebsocket_context;
|
|||
* LWS_CALLBACK_RECEIVE: data has appeared for the server, it can be
|
||||
* found at *in and is len bytes long
|
||||
*
|
||||
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
|
||||
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
|
||||
* asking to upgrade the connection to a websocket
|
||||
* one. This is a chance to serve http content,
|
||||
* for example, to send a script to the client
|
||||
* which will then open the websockets connection.
|
||||
* @in points to the URI path requested and
|
||||
* @in points to the URI path requested and
|
||||
* libwebsockets_serve_http_file() makes it very
|
||||
* simple to send back a file to the client.
|
||||
*/
|
||||
extern int callback(struct libwebsocket * wsi,
|
||||
enum libwebsocket_callback_reasons reason, void * user,
|
||||
extern int callback(struct libwebsocket *wsi,
|
||||
enum libwebsocket_callback_reasons reason, void *user,
|
||||
void *in, size_t len);
|
||||
|
||||
/**
|
||||
* struct libwebsocket_protocols - List of protocols and handlers server
|
||||
* supports.
|
||||
* struct libwebsocket_protocols - List of protocols and handlers server
|
||||
* supports.
|
||||
* @name: Protocol name that must match the one given in the client
|
||||
* Javascript new WebSocket(url, 'protocol') name
|
||||
* Javascript new WebSocket(url, 'protocol') name
|
||||
* @callback: The service callback used for this protocol. It allows the
|
||||
* service action for an entire protocol to be encapsulated in
|
||||
* the protocol-specific callback
|
||||
* service action for an entire protocol to be encapsulated in
|
||||
* the protocol-specific callback
|
||||
* @per_session_data_size: Each new connection using this protocol gets
|
||||
* this much memory allocated on connection establishment and
|
||||
* freed on connection takedown. A pointer to this per-connection
|
||||
* allocation is passed into the callback in the 'user' parameter
|
||||
* this much memory allocated on connection establishment and
|
||||
* freed on connection takedown. A pointer to this per-connection
|
||||
* allocation is passed into the callback in the 'user' parameter
|
||||
* @owning_server: the server init call fills in this opaque pointer when
|
||||
* registering this protocol with the server.
|
||||
* registering this protocol with the server.
|
||||
* @broadcast_socket_port: the server init call fills this in with the
|
||||
* localhost port number used to forward broadcasts for this
|
||||
* protocol
|
||||
* localhost port number used to forward broadcasts for this
|
||||
* protocol
|
||||
* @broadcast_socket_user_fd: the server init call fills this in ... the main()
|
||||
* process context can write to this socket to perform broadcasts
|
||||
* (use the libwebsockets_broadcast() api to do this instead,
|
||||
* it works from any process context)
|
||||
* process context can write to this socket to perform broadcasts
|
||||
* (use the libwebsockets_broadcast() api to do this instead,
|
||||
* it works from any process context)
|
||||
* @protocol_index: which protocol we are starting from zero
|
||||
*
|
||||
* This structure represents one protocol supported by the server. An
|
||||
* array of these structures is passed to libwebsocket_create_server()
|
||||
* allows as many protocols as you like to be handled by one server.
|
||||
* This structure represents one protocol supported by the server. An
|
||||
* array of these structures is passed to libwebsocket_create_server()
|
||||
* allows as many protocols as you like to be handled by one server.
|
||||
*/
|
||||
|
||||
struct libwebsocket_protocols {
|
||||
|
@ -129,7 +129,7 @@ struct libwebsocket_protocols {
|
|||
* below are filled in on server init and can be left uninitialized,
|
||||
* no need for user to use them directly either
|
||||
*/
|
||||
|
||||
|
||||
struct libwebsocket_context *owning_server;
|
||||
int broadcast_socket_port;
|
||||
int broadcast_socket_user_fd;
|
||||
|
@ -142,6 +142,9 @@ libwebsocket_create_context(int port,
|
|||
const char *ssl_cert_filepath,
|
||||
const char *ssl_private_key_filepath, int gid, int uid);
|
||||
|
||||
extern void
|
||||
libwebsocket_context_destroy(struct libwebsocket_context *this);
|
||||
|
||||
extern int
|
||||
libwebsockets_fork_service_loop(struct libwebsocket_context *this);
|
||||
|
||||
|
@ -188,7 +191,7 @@ libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
|
|||
/* notice - you need the pre- and post- padding allocation for buf below */
|
||||
|
||||
extern int
|
||||
libwebsockets_broadcast(const struct libwebsocket_protocols * protocol,
|
||||
libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
|
||||
unsigned char *buf, size_t len);
|
||||
|
||||
extern const struct libwebsocket_protocols *
|
||||
|
|
120
lib/parsers.c
120
lib/parsers.c
|
@ -149,7 +149,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
|||
debug("known hdr '%s'\n", wsi->name_buffer);
|
||||
wsi->parser_state = WSI_TOKEN_GET_URI + n;
|
||||
wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
||||
|
||||
|
||||
wsi->utf8_token[wsi->parser_state].token =
|
||||
malloc(wsi->current_alloc_len);
|
||||
wsi->utf8_token[wsi->parser_state].token_len = 0;
|
||||
|
@ -220,7 +220,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char inline
|
||||
static inline unsigned char
|
||||
xor_mask(struct libwebsocket *wsi, unsigned char c)
|
||||
{
|
||||
c ^= wsi->masking_key_04[wsi->frame_mask_index++];
|
||||
|
@ -286,7 +286,7 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
* wsi->frame_mask_04 will be our recirculating 20-byte XOR key
|
||||
* for this frame
|
||||
*/
|
||||
|
||||
|
||||
SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
|
||||
|
||||
/*
|
||||
|
@ -295,7 +295,7 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
*/
|
||||
|
||||
wsi->frame_mask_index = 0;
|
||||
|
||||
|
||||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
|
||||
break;
|
||||
|
||||
|
@ -305,7 +305,7 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
*
|
||||
* We ignore the possibility of extension data because we don't
|
||||
* negotiate any extensions at the moment.
|
||||
*
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-------+-+-------------+-------------------------------+
|
||||
|
@ -334,23 +334,24 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
* 04 spec defines the opcode like this: (1, 2, and 3 are
|
||||
* "control frame" opcodes which may not be fragmented or
|
||||
* have size larger than 126)
|
||||
*
|
||||
* frame-opcode =
|
||||
* %x0 ; continuation frame
|
||||
* / %x1 ; connection close
|
||||
* / %x2 ; ping
|
||||
* / %x3 ; pong
|
||||
* / %x4 ; text frame
|
||||
* / %x5 ; binary frame
|
||||
* / %x6-F ; reserved
|
||||
*
|
||||
* FIN (b7)
|
||||
* frame-opcode =
|
||||
* %x0 ; continuation frame
|
||||
* / %x1 ; connection close
|
||||
* / %x2 ; ping
|
||||
* / %x3 ; pong
|
||||
* / %x4 ; text frame
|
||||
* / %x5 ; binary frame
|
||||
* / %x6-F ; reserved
|
||||
*
|
||||
* FIN (b7)
|
||||
*/
|
||||
|
||||
c = xor_mask(wsi, c);
|
||||
|
||||
if (c & 0x70) {
|
||||
fprintf(stderr, "Frame has extensions set illegally 1\n");
|
||||
fprintf(stderr,
|
||||
"Frame has extensions set illegally 1\n");
|
||||
/* kill the connection */
|
||||
return -1;
|
||||
}
|
||||
|
@ -412,7 +413,6 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
|
||||
break;
|
||||
default:
|
||||
// fprintf(stderr, "seen incoming 04 frame len %d\n", c);
|
||||
wsi->rx_packet_length = c;
|
||||
wsi->lws_rx_parse_state =
|
||||
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
|
||||
|
@ -605,51 +605,51 @@ int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
|
|||
}
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* 04 logical framing from the spec (all this is masked when incoming
|
||||
* and has to be unmasked)
|
||||
*
|
||||
* We ignore the possibility of extension data because we don't
|
||||
* negotiate any extensions at the moment.
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-------+-+-------------+-------------------------------+
|
||||
* |F|R|R|R| opcode|R| Payload len | Extended payload length |
|
||||
* |I|S|S|S| (4) |S| (7) | (16/63) |
|
||||
* |N|V|V|V| |V| | (if payload len==126/127) |
|
||||
* | |1|2|3| |4| | |
|
||||
* +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|
||||
* | Extended payload length continued, if payload len == 127 |
|
||||
* + - - - - - - - - - - - - - - - +-------------------------------+
|
||||
* | | Extension data |
|
||||
* +-------------------------------+ - - - - - - - - - - - - - - - +
|
||||
* : :
|
||||
* +---------------------------------------------------------------+
|
||||
* : Application data :
|
||||
* +---------------------------------------------------------------+
|
||||
*
|
||||
* We pass payload through to userland as soon as we get it, ignoring
|
||||
* FIN. It's up to userland to buffer it up if it wants to see a
|
||||
* whole unfragmented block of the original size (which may be up to
|
||||
* 2^63 long!)
|
||||
*/
|
||||
/*
|
||||
* 04 logical framing from the spec (all this is masked when
|
||||
* incoming and has to be unmasked)
|
||||
*
|
||||
* We ignore the possibility of extension data because we don't
|
||||
* negotiate any extensions at the moment.
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-------+-+-------------+-------------------------------+
|
||||
* |F|R|R|R| opcode|R| Payload len | Extended payload length |
|
||||
* |I|S|S|S| (4) |S| (7) | (16/63) |
|
||||
* |N|V|V|V| |V| | (if payload len==126/127) |
|
||||
* | |1|2|3| |4| | |
|
||||
* +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|
||||
* | Extended payload length continued, if payload len == 127 |
|
||||
* + - - - - - - - - - - - - - - - +-------------------------------+
|
||||
* | | Extension data |
|
||||
* +-------------------------------+ - - - - - - - - - - - - - - - +
|
||||
* : :
|
||||
* +---------------------------------------------------------------+
|
||||
* : Application data :
|
||||
* +---------------------------------------------------------------+
|
||||
*
|
||||
* We pass payload through to userland as soon as we get it, ignoring
|
||||
* FIN. It's up to userland to buffer it up if it wants to see a
|
||||
* whole unfragmented block of the original size (which may be up to
|
||||
* 2^63 long!)
|
||||
*/
|
||||
|
||||
/*
|
||||
* 04 spec defines the opcode like this: (1, 2, and 3 are
|
||||
* "control frame" opcodes which may not be fragmented or
|
||||
* have size larger than 126)
|
||||
*
|
||||
* frame-opcode =
|
||||
* %x0 ; continuation frame
|
||||
* / %x1 ; connection close
|
||||
* / %x2 ; ping
|
||||
* / %x3 ; pong
|
||||
* / %x4 ; text frame
|
||||
* / %x5 ; binary frame
|
||||
* / %x6-F ; reserved
|
||||
*
|
||||
* FIN (b7)
|
||||
* frame-opcode =
|
||||
* %x0 ; continuation frame
|
||||
* / %x1 ; connection close
|
||||
* / %x2 ; ping
|
||||
* / %x3 ; pong
|
||||
* / %x4 ; text frame
|
||||
* / %x5 ; binary frame
|
||||
* / %x6-F ; reserved
|
||||
*
|
||||
* FIN (b7)
|
||||
*/
|
||||
|
||||
if (c & 0x70) {
|
||||
|
@ -1136,14 +1136,14 @@ send_raw:
|
|||
if (use_ssl) {
|
||||
n = SSL_write(wsi->ssl, buf - pre, len + pre + post);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "ERROR writing to socket");
|
||||
fprintf(stderr, "ERROR writing to socket\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
n = send(wsi->sock, buf - pre, len + pre + post, 0);
|
||||
n = send(wsi->sock, buf - pre, len + pre + post, MSG_NOSIGNAL);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "ERROR writing to socket");
|
||||
fprintf(stderr, "ERROR writing to socket\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
|
@ -1211,7 +1211,7 @@ int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
|
|||
|
||||
/**
|
||||
* libwebsockets_remaining_packet_payload() - Bytes to come before "overall"
|
||||
* rx packet is complete
|
||||
* rx packet is complete
|
||||
* @wsi: Websocket instance (available from user callback)
|
||||
*
|
||||
* This function is intended to be called from the callback if the
|
||||
|
|
|
@ -51,16 +51,20 @@
|
|||
#include <openssl/sha.h>
|
||||
#include "libwebsockets.h"
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#if 0
|
||||
#define DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static inline void debug(const char *format, ...) {
|
||||
static inline void debug(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
|
||||
}
|
||||
#else
|
||||
static inline void debug(const char *format, ...) { }
|
||||
static inline void debug(const char *format, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LWS_OPENSSL_SUPPORT
|
||||
|
|
|
@ -1,3 +1,63 @@
|
|||
<h2>libwebsocket_context_destroy - Destroy the websocket context</h2>
|
||||
<i>void</i>
|
||||
<b>libwebsocket_context_destroy</b>
|
||||
(<i>struct libwebsocket_context *</i> <b>this</b>)
|
||||
<h3>Arguments</h3>
|
||||
<dl>
|
||||
<dt><b>this</b>
|
||||
<dd>Websocket context
|
||||
</dl>
|
||||
<h3>Description</h3>
|
||||
<blockquote>
|
||||
This function closes any active connections and then frees the
|
||||
context. After calling this, any further use of the context is
|
||||
undefined.
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h2>libwebsocket_service - Service any pending websocket activity</h2>
|
||||
<i>int</i>
|
||||
<b>libwebsocket_service</b>
|
||||
(<i>struct libwebsocket_context *</i> <b>this</b>,
|
||||
<i>int</i> <b>timeout_ms</b>)
|
||||
<h3>Arguments</h3>
|
||||
<dl>
|
||||
<dt><b>this</b>
|
||||
<dd>Websocket context
|
||||
<dt><b>timeout_ms</b>
|
||||
<dd>Timeout for poll; 0 means return immediately if nothing needed
|
||||
service otherwise block and service immediately, returning
|
||||
after the timeout if nothing needed service.
|
||||
</dl>
|
||||
<h3>Description</h3>
|
||||
<blockquote>
|
||||
This function deals with any pending websocket traffic, for three
|
||||
kinds of event. It handles these events on both server and client
|
||||
types of connection the same.
|
||||
<p>
|
||||
1) Accept new connections to our context's server
|
||||
<p>
|
||||
2) Perform pending broadcast writes initiated from other forked
|
||||
processes (effectively serializing asynchronous broadcasts)
|
||||
<p>
|
||||
3) Call the receive callback for incoming frame data received by
|
||||
server or client connections.
|
||||
<p>
|
||||
You need to call this service function periodically to all the above
|
||||
functions to happen; if your application is single-threaded you can
|
||||
just call it in your main event loop.
|
||||
<p>
|
||||
Alternatively you can fork a new process that asynchronously handles
|
||||
calling this service in a loop. In that case you are happy if this
|
||||
call blocks your thread until it needs to take care of something and
|
||||
would call it with a large nonzero timeout. Your loop then takes no
|
||||
CPU while there is nothing happening.
|
||||
<p>
|
||||
If you are calling it in a single-threaded app, you don't want it to
|
||||
wait around blocking other things in your loop from happening, so you
|
||||
would call it with a timeout_ms of 0, so it returns immediately if
|
||||
nothing is pending, or as soon as it services whatever was pending.
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h2>libwebsocket_create_context - Create the websocket handler</h2>
|
||||
<i>struct libwebsocket_context *</i>
|
||||
<b>libwebsocket_create_context</b>
|
||||
|
|
|
@ -380,6 +380,8 @@ int main(int argc, char **argv)
|
|||
libwebsocket_client_close(wsi_dumb);
|
||||
libwebsocket_client_close(wsi_mirror);
|
||||
|
||||
libwebsocket_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets-test-server - libwebsockets test implementation
|
||||
*
|
||||
* Copyright (C) 2010 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010-2011 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -233,7 +233,7 @@ int main(int argc, char **argv)
|
|||
struct libwebsocket_context *context;
|
||||
|
||||
fprintf(stderr, "libwebsockets test server\n"
|
||||
"(C) Copyright 2010 Andy Green <andy@warmcat.com> "
|
||||
"(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
|
||||
"licensed under LGPL2.1\n");
|
||||
|
||||
while (n >= 0) {
|
||||
|
@ -349,5 +349,7 @@ int main(int argc, char **argv)
|
|||
|
||||
#endif
|
||||
|
||||
libwebsocket_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue