From 4f3943a8f818be392ac9f059589f341ff311affa Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 12 Nov 2010 10:44:16 +0000 Subject: [PATCH] move-to-automatic-protocol-list-scheme.patch Signed-off-by: Andy Green --- lib/Makefile.am | 4 +- lib/Makefile.in | 4 +- lib/handshake.c | 52 +++++++++--- lib/libwebsockets.c | 119 ++++++++++++++++++--------- lib/libwebsockets.h | 37 +++++++-- lib/parsers.c | 6 +- lib/private-libwebsockets.h | 6 +- libwebsockets-api-doc.html | 106 ++++++++++++++++++++++-- test-server/test-server.c | 195 ++++++++++++++++---------------------------- 9 files changed, 325 insertions(+), 204 deletions(-) diff --git a/lib/Makefile.am b/lib/Makefile.am index 78ced38..7cc2120 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -12,7 +12,7 @@ libwebsockets_la_LDFLAGS=-version-info 0:1 all-local: ../scripts/kernel-doc -html \ libwebsockets.c \ - parsers.c \ - ../test-server/test-server.c \ + parsers.c \ + libwebsockets.h \ > ../libwebsockets-api-doc.html diff --git a/lib/Makefile.in b/lib/Makefile.in index 493db5b..dcf4a67 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -578,8 +578,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES all-local: ../scripts/kernel-doc -html \ libwebsockets.c \ - parsers.c \ - ../test-server/test-server.c \ + parsers.c \ + libwebsockets.h \ > ../libwebsockets-api-doc.html # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/lib/handshake.c b/lib/handshake.c index 2ca7938..7deb581 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -94,9 +94,9 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) if (!wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len || !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len) { - if (wsi->callback) - (wsi->callback)(wsi, LWS_CALLBACK_HTTP, - &wsi->user_space[0], + if (wsi->protocol->callback) + (wsi->protocol->callback)(wsi, LWS_CALLBACK_HTTP, + &wsi->user_space, wsi->utf8_token[WSI_TOKEN_GET_URI].token, 0); wsi->state = WSI_STATE_HTTP; return 0; @@ -132,11 +132,41 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) /* Make sure user side is happy about protocol */ - if (wsi->callback) - wsi->callback(wsi, LWS_CALLBACK_PROTOCOL_FILTER, - &wsi->user_space[0], - wsi->utf8_token[WSI_TOKEN_PROTOCOL].token, - 0); + while (wsi->protocol->callback) { + + if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL) { + if (wsi->protocol->name == NULL) + break; + } else + if (strcmp( + wsi->utf8_token[WSI_TOKEN_PROTOCOL].token, + wsi->protocol->name) == 0) + break; + + wsi->protocol++; + } + if (wsi->protocol->callback == NULL) { + if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL) + fprintf(stderr, "[no protocol] " + "not supported (use NULL .name)\n"); + else + fprintf(stderr, "Requested protocol %s " + "not supported\n", + wsi->utf8_token[WSI_TOKEN_PROTOCOL].token); + goto bail; + } + + /* allocate the per-connection user memory (if any) */ + + if (wsi->protocol->per_session_data_size) { + wsi->user_space = malloc( + wsi->protocol->per_session_data_size); + if (wsi->user_space == NULL) { + fprintf(stderr, "Out of memory for " + "conn user space\n"); + goto bail; + } + } /* create the response packet */ @@ -243,9 +273,9 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) /* notify user code that we're ready to roll */ - if (wsi->callback) - wsi->callback(wsi, LWS_CALLBACK_ESTABLISHED, - &wsi->user_space[0], NULL, 0); + if (wsi->protocol->callback) + wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED, + &wsi->user_space, NULL, 0); break; case WSI_STATE_ESTABLISHED: diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 11ab790..60ecde2 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -31,6 +31,48 @@ extern int libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len); +/* document the generic callback (it's a fake prototype under this) */ +/** + * callback() - User server actions + * @wsi: Opaque websocket instance pointer + * @reason: The reason for the call + * @user: Pointer to per-session user data allocated by library + * @in: Pointer used for some callback reasons + * @len: Length set for some callback reasons + * + * 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. + * + * LWS_CALLBACK_ESTABLISHED: after successful websocket handshake + * + * LWS_CALLBACK_CLOSED: when the websocket session ends + * + * LWS_CALLBACK_SEND: opportunity to send to client (you would use + * libwebsocket_write() taking care about the + * special buffer requirements + * 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 + * 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 + * 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, + void *in, size_t len); + void libwebsocket_close_and_free_session(struct libwebsocket *wsi) @@ -39,8 +81,8 @@ libwebsocket_close_and_free_session(struct libwebsocket *wsi) wsi->state = WSI_STATE_DEAD_SOCKET; - if (wsi->callback && n == WSI_STATE_ESTABLISHED) - wsi->callback(wsi, LWS_CALLBACK_CLOSED, &wsi->user_space[0], + if (wsi->protocol->callback && n == WSI_STATE_ESTABLISHED) + wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED, &wsi->user_space, NULL, 0); for (n = 0; n < WSI_TOKEN_COUNT; n++) @@ -62,17 +104,18 @@ libwebsocket_close_and_free_session(struct libwebsocket *wsi) #ifdef LWS_OPENSSL_SUPPORT } #endif + if (wsi->user_space) + free(wsi->user_space); + free(wsi); } /** * libwebsocket_create_server() - Create the listening websockets server * @port: Port to listen on - * @callback: The callback in user code to perform actual serving - * @user_area_size: How much memory to allocate per connection session - * which will be used by the user application to store - * per-session data. A pointer to this space is given - * when the user callback is called. + * @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. * @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 @@ -98,10 +141,7 @@ libwebsocket_close_and_free_session(struct libwebsocket *wsi) */ int libwebsocket_create_server(int port, - int (*callback)(struct libwebsocket *, - enum libwebsocket_callback_reasons, - void *, void *, size_t), - size_t user_area_size, + const struct libwebsocket_protocols *protocols, const char * ssl_cert_filepath, const char * ssl_private_key_filepath, int gid, int uid) @@ -185,14 +225,7 @@ int libwebsocket_create_server(int port, /* SSL is happy and has a cert it's content with */ } #endif - - if (!callback) { - fprintf(stderr, "callback is not optional!\n"); - return -1; - } - - /* sit there listening for connects, accept and spawn session servers */ - + sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { fprintf(stderr, "ERROR opening socket"); @@ -226,7 +259,7 @@ int libwebsocket_create_server(int port, if (n) return sockfd; - // drop any root privs for this thread + /* drop any root privs for this thread */ if (gid != -1) if (setgid(gid)) @@ -235,8 +268,11 @@ int libwebsocket_create_server(int port, if (setuid(uid)) fprintf(stderr, "setuid: %s\n", strerror(errno)); - /* we are running in a forked subprocess now */ - + /* + * sit there listening for connects, accept and service connections + * in a poll loop, without any further forking + */ + listen(sockfd, 5); fprintf(stderr, " Listening on port %d\n", port); @@ -273,8 +309,7 @@ int libwebsocket_create_server(int port, continue; } - wsi[fds_count] = malloc(sizeof(struct libwebsocket) + - user_area_size); + wsi[fds_count] = malloc(sizeof(struct libwebsocket)); if (!wsi[fds_count]) return -1; @@ -313,11 +348,10 @@ int libwebsocket_create_server(int port, ntohs(cli_addr.sin_port), fd, SSL_get_version(wsi[fds_count]->ssl)); - } else { -// fprintf(stderr, "accepted new conn port %u on fd=%d\n", -// ntohs(cli_addr.sin_port), fd); - } + } else #endif + debug("accepted new conn port %u on fd=%d\n", + ntohs(cli_addr.sin_port), fd); /* intialize the instance struct */ @@ -330,11 +364,20 @@ int libwebsocket_create_server(int port, wsi[fds_count]->utf8_token[n].token_len = 0; } - wsi[fds_count]->callback = callback; + /* + * these can only be set once the protocol is known + * we set an unestablished connection's protocol pointer + * to the start of the supported list, so it can look + * for matching ones during the handshake + */ + wsi[fds_count]->protocol = protocols; + wsi[fds_count]->user_space = NULL; + /* * Default protocol is 76 * After 76, there's a header specified to inform which - * draft the client wants + * draft the client wants, when that's seen we modify + * the individual connection's spec revision accordingly */ wsi[fds_count]->ietf_spec_revision = 76; @@ -361,8 +404,6 @@ int libwebsocket_create_server(int port, if (!(fds[client].revents & POLLIN)) continue; - -// fprintf(stderr, "POLLIN\n"); #ifdef LWS_OPENSSL_SUPPORT if (use_ssl) @@ -371,8 +412,6 @@ int libwebsocket_create_server(int port, #endif n = recv(fds[client].fd, buf, sizeof(buf), 0); -// fprintf(stderr, "read returned %d\n", n); - if (n < 0) { fprintf(stderr, "Socket read returned %d\n", n); continue; @@ -389,7 +428,10 @@ int libwebsocket_create_server(int port, if (libwebsocket_read(wsi[client], buf, n) >= 0) continue; - /* it closed and nuked wsi[client] */ + /* + * it closed and nuked wsi[client], so remove the + * socket handle and wsi from our service list + */ nuke_this: for (n = client; n < fds_count - 1; n++) { fds[n] = fds[n + 1]; @@ -404,12 +446,9 @@ poll_out: if (wsi[client]->state != WSI_STATE_ESTABLISHED) continue; - - if (!wsi[client]->callback) - continue; - wsi[client]->callback(wsi[client], LWS_CALLBACK_SEND, - &wsi[client]->user_space[0], NULL, 0); + wsi[client]->protocol->callback(wsi[client], LWS_CALLBACK_SEND, + &wsi[client]->user_space, NULL, 0); } continue; diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index b1588b1..24042fc 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -29,7 +29,6 @@ enum libwebsocket_callback_reasons { LWS_CALLBACK_SEND, LWS_CALLBACK_RECEIVE, LWS_CALLBACK_HTTP, - LWS_CALLBACK_PROTOCOL_FILTER, }; enum libwebsocket_write_protocol { @@ -40,14 +39,36 @@ enum libwebsocket_write_protocol { struct libwebsocket; +/** + * 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 + * @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 + * @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 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 { + const char *name; + int (*callback)(struct libwebsocket * wsi, + enum libwebsocket_callback_reasons reason, void * user, + void *in, size_t len); + size_t per_session_data_size; +}; + extern int libwebsocket_create_server(int port, - int (*callback)(struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, - void *user, void *in, size_t len), - size_t user_space, - const char * ssl_cert_filepath, - const char * ssl_private_key_filepath, - int gid, int uid); + const struct libwebsocket_protocols *protocols, + const char * ssl_cert_filepath, + const char * ssl_private_key_filepath, int gid, int uid); /* * IMPORTANT NOTICE! diff --git a/lib/parsers.c b/lib/parsers.c index 9a767f8..52cd126 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -210,9 +210,9 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER) break; issue: - if (wsi->callback) - wsi->callback(wsi, LWS_CALLBACK_RECEIVE, - &wsi->user_space[0], + if (wsi->protocol->callback) + wsi->protocol->callback(wsi, LWS_CALLBACK_RECEIVE, + &wsi->user_space, &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], wsi->rx_user_buffer_head); wsi->rx_user_buffer_head = 0; diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 27f495a..d3789f1 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -121,8 +121,7 @@ struct lws_tokens { */ struct libwebsocket { - int (*callback)(struct libwebsocket *, - enum libwebsocket_callback_reasons reason, void *, void *, size_t); + const struct libwebsocket_protocols *protocol; enum lws_connection_states state; @@ -145,8 +144,7 @@ struct libwebsocket { SSL *ssl; #endif - /* last */ - char user_space[0]; + void *user_space; }; extern void diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index 5471d3a..e7dcb82 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -1,9 +1,72 @@ +

callback - User server actions

+int +callback +(struct libwebsocket * wsi, +enum libwebsocket_callback_reasons reason, +void * user, +void * in, +size_t len) +

Arguments

+
+
wsi +
Opaque websocket instance pointer +
reason +
The reason for the call +
user +
Pointer to per-session user data allocated by library +
in +
Pointer used for some callback reasons +
len +
Length set for some callback reasons +
+

Description

+
+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. +

+

LWS_CALLBACK_ESTABLISHED

+
+after successful websocket handshake +
+

LWS_CALLBACK_CLOSED

+
+when the websocket session ends +
+

LWS_CALLBACK_SEND

+
+opportunity to send to client (you would use +libwebsocket_write taking care about the +special buffer requirements +
+

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 +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 +libwebsockets_serve_http_file makes it very +simple to send back a file to the client. +
+

libwebsocket_create_server - Create the listening websockets server

int libwebsocket_create_server (int port, -int (*callback) (struct libwebsocket *, enum libwebsocket_callback_reasons, void *, void *, size_t), -size_t user_area_size, +const struct libwebsocket_protocols * protocols, const char * ssl_cert_filepath, const char * ssl_private_key_filepath, int gid, @@ -12,13 +75,10 @@
port
Port to listen on -
callback -
The callback in user code to perform actual serving -
user_area_size -
How much memory to allocate per connection session -which will be used by the user application to store -per-session data. A pointer to this space is given -when the user callback is called. +
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.
ssl_cert_filepath
If libwebsockets was compiled to use ssl, and you want to listen using SSL, set to the filepath to fetch the @@ -109,3 +169,31 @@ to http requests from the client. It allows the callback to issue local files down the http link in a single step.
+

struct libwebsocket_protocols - List of protocols and handlers server supports.

+struct libwebsocket_protocols {
+    const char * name;
+    int (*callback) (struct libwebsocket * wsi,enum libwebsocket_callback_reasons reason, void * user,void *in, size_t len);
+    size_t per_session_data_size;
+};
+

Members

+
+
name +
Protocol name that must match the one given in the client +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 +
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 +
+

Description

+
+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. +
+
diff --git a/test-server/test-server.c b/test-server/test-server.c index 1bba6e0..26f4a86 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -31,116 +31,14 @@ static int port = 7681; static int use_ssl = 0; -struct per_session_data { - int number; -}; - - /** - * libwebsocket_callback() - User server actions - * @wsi: Opaque websocket instance pointer - * @reason: The reason for the call - * @user: Pointer to per-session user data allocated by library - * @in: Pointer used for some callback reasons - * @len: Length set for some callback reasons - * - * 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. - * - * LWS_CALLBACK_ESTABLISHED: after successful websocket handshake - * - * LWS_CALLBACK_CLOSED: when the websocket session ends - * - * LWS_CALLBACK_SEND: opportunity to send to client (you would use - * libwebsocket_write() taking care about the - * special buffer requirements - * 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 - * 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 - * libwebsockets_serve_http_file() makes it very - * simple to send back a file to the client. - * - * LWS_CALLBACK_PROTOCOL_FILTER: before the confirmation handshake is sent - * the user callback is given a chance to confirm - * it's OK with the protocol that was requested - * from the client. The protocol string (which - * may be NULL if no protocol header was sent) - * can be found at parameter @in. Return 0 from - * the callback to allow the connection or nonzero - * to abort the connection. - */ +/* this protocol server (always the first one) just knows how to do HTTP */ -static int websocket_callback(struct libwebsocket * wsi, +static int callback_http(struct libwebsocket * wsi, enum libwebsocket_callback_reasons reason, void * user, void *in, size_t len) { - int n; - char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + - LWS_SEND_BUFFER_POST_PADDING]; - char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING]; - struct per_session_data * pss = user; - switch (reason) { - /* - * Websockets session handshake completed and is established - */ - case LWS_CALLBACK_ESTABLISHED: - fprintf(stderr, "Websocket connection established\n"); - pss->number = 0; - break; - - /* - * Websockets session is closed - */ - case LWS_CALLBACK_CLOSED: - fprintf(stderr, "Websocket connection closed\n"); - break; - - /* - * Opportunity for us to send something on the connection - */ - case LWS_CALLBACK_SEND: - n = sprintf(p, "%d", pss->number++); - n = libwebsocket_write(wsi, (unsigned char *)p, n, - LWS_WRITE_TEXT); - if (n < 0) { - fprintf(stderr, "ERROR writing to socket"); - exit(1); - } - break; - /* - * Something has arrived for us on the connection, it's len bytes long - * and is available at *in - */ - case LWS_CALLBACK_RECEIVE: - fprintf(stderr, "Received %d bytes payload\n", (int)len); - if (strcmp(in, "reset\n") == 0) - pss->number = 0; - break; - - /* - * The client has asked us for something in normal HTTP mode, - * not websockets mode. Normally it means we want to send - * our script / html to the client, and when that script runs - * it will start up separate websocket connections. - * - * Interpret the URI string to figure out what is needed to send - */ - case LWS_CALLBACK_HTTP: - fprintf(stderr, "serving HTTP URI %s\n", in); if (in && strcmp(in, "/favicon.ico") == 0) { @@ -157,34 +55,82 @@ static int websocket_callback(struct libwebsocket * wsi, fprintf(stderr, "Failed to send HTTP file\n"); break; - /* - * This is our chance to choose if we support one of the requested - * protocols or not. in points to the protocol string. Nonzero return - * aborts the connection handshake - */ + default: + break; + } + + return 0; +} + +/* dumb_increment protocol */ + +struct per_session_data__dumb_increment { + int number; +}; + +static int +callback_dumb_increment(struct libwebsocket * wsi, + enum libwebsocket_callback_reasons reason, + void * user, void *in, size_t len) +{ + int n; + char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + + LWS_SEND_BUFFER_POST_PADDING]; + unsigned char *p = (unsigned char *)&buf[LWS_SEND_BUFFER_PRE_PADDING]; + struct per_session_data__dumb_increment * pss = user; + + switch (reason) { - case LWS_CALLBACK_PROTOCOL_FILTER: - if (in == NULL) { - fprintf(stderr, "Client did not request protocol\n"); - /* reject it */ + case LWS_CALLBACK_ESTABLISHED: + pss->number = 0; + break; + + case LWS_CALLBACK_SEND: + n = sprintf(p, "%d", pss->number++); + n = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT); + if (n < 0) { + fprintf(stderr, "ERROR writing to socket"); return 1; } - fprintf(stderr, "Client requested protocol '%s'\n", in); - if (strcmp(in, "dumb-increment-protocol") == 0) - /* accept it */ - return 0; + break; - /* reject the connection */ - return 1; + case LWS_CALLBACK_RECEIVE: + if (len < 6) + break; + if (strcmp(in, "reset\n") == 0) + pss->number = 0; + break; + + default: + break; } return 0; } + +/* list of supported protocols and callbacks */ + +static const struct libwebsocket_protocols protocols[] = { + { + .name = "http-only", + .callback = callback_http, + .per_session_data_size = 0, + }, + { + .name = "dumb-increment-protocol", + .callback = callback_dumb_increment, + .per_session_data_size = + sizeof(struct per_session_data__dumb_increment), + }, + { /* end of list */ + .callback = NULL + } +}; + static struct option options[] = { { "help", no_argument, NULL, 'h' }, { "port", required_argument, NULL, 'p' }, - { "protocol", required_argument, NULL, 'r' }, { "ssl", no_argument, NULL, 's' }, { NULL, 0, 0, 0 } }; @@ -202,7 +148,7 @@ int main(int argc, char **argv) "licensed under LGPL2.1\n"); while (n >= 0) { - n = getopt_long(argc, argv, "hp:r:", options, NULL); + n = getopt_long(argc, argv, "hp:", options, NULL); if (n < 0) continue; switch (n) { @@ -214,7 +160,7 @@ int main(int argc, char **argv) break; case 'h': fprintf(stderr, "Usage: test-server " - "[--port=

] [--protocol=]\n"); + "[--port=

] [--ssl]\n"); exit(1); } } @@ -222,9 +168,8 @@ int main(int argc, char **argv) if (!use_ssl) cert_path = key_path = NULL; - if (libwebsocket_create_server(port, websocket_callback, - sizeof(struct per_session_data), - cert_path, key_path, -1, -1) < 0) { + if (libwebsocket_create_server(port, protocols, + cert_path, key_path, -1, -1) < 0) { fprintf(stderr, "libwebsocket init failed\n"); return -1; } -- 2.7.4