diff --git a/examples/websocket_client/websocket_client b/examples/websocket_client/websocket_client deleted file mode 100755 index 30bbec4b..00000000 Binary files a/examples/websocket_client/websocket_client and /dev/null differ diff --git a/examples/websocket_client/websocket_client.c b/examples/websocket_client/websocket_client.c index 4bc205a2..7eedce0c 100644 --- a/examples/websocket_client/websocket_client.c +++ b/examples/websocket_client/websocket_client.c @@ -17,7 +17,7 @@ #define PORT "8888" #define SSL_CERT "./ssl/server.pem" -int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len) +static int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len) { printf("From server: %s\r\n", data); diff --git a/include/civetweb.h b/include/civetweb.h index ca97d761..15d34d22 100644 --- a/include/civetweb.h +++ b/include/civetweb.h @@ -573,7 +573,20 @@ CIVETWEB_API void mg_cry(struct mg_connection *conn, /* utility method to compare two buffers, case incensitive. */ CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len); -/* Connect to a websocket as a client */ +/* Connect to a websocket as a client + Parameters: + host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost" + port: server port + use_ssl: make a secure connection to server + error_buffer, error_buffer_size: error message placeholder. + path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app" + origin: value of the Origin HTTP header + data_func: callback that should be used when data is received from the server + + Return: + On success, valid mg_connection object. + On error, NULL. */ + typedef int (*websocket_data_func)(struct mg_connection *, int bits, char *data, size_t data_len); CIVETWEB_API struct mg_connection *mg_client_websocket_connect(const char *host, int port, int use_ssl, diff --git a/src/civetweb.c b/src/civetweb.c index 1e946d59..2636e15a 100644 --- a/src/civetweb.c +++ b/src/civetweb.c @@ -6615,9 +6615,10 @@ struct mg_connection *mg_client_websocket_connect(const char *host, int port, in "\r\n", path, host, magic, origin); //Connection object will be null if something goes wrong - if(conn == NULL) + if(conn == NULL || (strcmp(conn->request_info.uri, "101") != 0)) { DEBUG_TRACE("Websocket client connect error: %s\r\n", error_buffer); + if(conn != NULL) { mg_free(conn); conn = NULL; } return conn; } diff --git a/test/unit_test.c b/test/unit_test.c index c3384f8c..06078308 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -525,6 +525,57 @@ static void test_mg_download(int use_ssl) { mg_stop(ctx); } +static int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len) +{ + return 1; +} + +static void test_mg_client_websocket_connect(int use_ssl) { + struct mg_connection* conn; + char ebuf[100]; + int port = HTTP_PORT; + + if(use_ssl) { port = HTTPS_PORT; } + + //Try to connect to our own server + //TODO: These do not work right now + + //Invalid port test + /*conn = mg_client_websocket_connect("localhost", 0, use_ssl, + ebuf, sizeof(ebuf), + "/", "http://localhost",websocket_data_handler); + ASSERT(conn == NULL); + + //Should succeed, the default civetweb sever should complete the handshake + conn = mg_client_websocket_connect("localhost", port, use_ssl, + ebuf, sizeof(ebuf), + "/", "http://localhost",websocket_data_handler); + ASSERT(conn != NULL);*/ + + + //Try an external server test + port = 80; + if(use_ssl) { port = 443; } + + //Not a websocket server path + conn = mg_client_websocket_connect("websocket.org", port, use_ssl, + ebuf, sizeof(ebuf), + "/", "http://websocket.org",websocket_data_handler); + ASSERT(conn == NULL); + + //Invalid port test + conn = mg_client_websocket_connect("echo.websocket.org", 0, use_ssl, + ebuf, sizeof(ebuf), + "/", "http://websocket.org",websocket_data_handler); + ASSERT(conn == NULL); + + //Should succeed, echo.websocket.org echos the data back + conn = mg_client_websocket_connect("echo.websocket.org", port, use_ssl, + ebuf, sizeof(ebuf), + "/", "http://websocket.org",websocket_data_handler); + ASSERT(conn != NULL); +} + static int alloc_printf(char **buf, size_t size, char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -1016,6 +1067,12 @@ int __cdecl main(void) { #ifndef NO_SSL test_mg_download(1); #endif + + test_mg_client_websocket_connect(0); +#ifndef NO_SSL + test_mg_client_websocket_connect(1); +#endif + test_mg_upload(); test_request_replies(); test_api_calls();