uri processing reject paths not starting with slash
[platform/upstream/libwebsockets.git] / test-server / test-client.c
index 475b8b1..b35260d 100644 (file)
@@ -1,22 +1,21 @@
 /*
  * libwebsockets-test-client - libwebsockets test implementation
  *
- * Copyright (C) 2011 Andy Green <andy@warmcat.com>
+ * Copyright (C) 2011-2016 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
- *  License as published by the Free Software Foundation:
- *  version 2.1 of the License.
+ * This file is made available under the Creative Commons CC0 1.0
+ * Universal Public Domain Dedication.
  *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
+ * The person who associated a work with this deed has dedicated
+ * the work to the public domain by waiving all of his or her rights
+ * to the work worldwide under copyright law, including all related
+ * and neighboring rights, to the extent allowed by law. You can copy,
+ * modify, distribute and perform the work, even for commercial purposes,
+ * all without asking permission.
  *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- *  MA  02110-1301  USA
+ * The test apps are intended to be adapted for use in your code, which
+ * may be proprietary.  So unlike the library itself, they are licensed
+ * Public Domain.
  */
 
 #include <stdio.h>
@@ -75,6 +74,8 @@ static int
 callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
                        void *user, void *in, size_t len)
 {
+       char *buf = (char *)in;
+
        switch (reason) {
 
        case LWS_CALLBACK_CLIENT_ESTABLISHED:
@@ -115,6 +116,16 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
                        return 1;
                break;
 
+       case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
+               while (len--)
+                       putchar(*buf++);
+               break;
+
+       case LWS_CALLBACK_COMPLETED_CLIENT_HTTP:
+               wsi_dumb = NULL;
+               force_exit = 1;
+               break;
+
        default:
                break;
        }
@@ -270,17 +281,17 @@ static int ratelimit_connects(unsigned int *last, unsigned int secs)
 int main(int argc, char **argv)
 {
        int n = 0, ret = 0, port = 7681, use_ssl = 0, ietf_version = -1;
-       unsigned int rl_dumb = 0, rl_mirror = 0;
+       unsigned int rl_dumb = 0, rl_mirror = 0, do_ws = 1;
        struct lws_context_creation_info info;
        struct lws_client_connect_info i;
        struct lws_context *context;
-       const char *address;
+       const char *prot, *p;
+       char path[300];
 
        memset(&info, 0, sizeof info);
 
-       fprintf(stderr, "libwebsockets test client\n"
-                       "(C) Copyright 2010-2015 Andy Green <andy@warmcat.com> "
-                       "licensed under LGPL2.1\n");
+       lwsl_notice("libwebsockets test client - license LGPL2.1+SLE\n");
+       lwsl_notice("(C) Copyright 2010-2016 Andy Green <andy@warmcat.com>\n");
 
        if (argc < 2)
                goto usage;
@@ -321,7 +332,22 @@ int main(int argc, char **argv)
 
        signal(SIGINT, sighandler);
 
-       address = argv[optind];
+       memset(&i, 0, sizeof(i));
+
+       i.port = port;
+       if (lws_parse_uri(argv[optind], &prot, &i.address, &i.port, &p))
+               goto usage;
+
+       /* add back the leading / on path */
+       path[0] = '/';
+       strncpy(path + 1, p, sizeof(path) - 2);
+       path[sizeof(path) - 1] = '\0';
+       i.path = path;
+
+       if (!strcmp(prot, "http") || !strcmp(prot, "ws"))
+               use_ssl = 0;
+       if (!strcmp(prot, "https") || !strcmp(prot, "wss"))
+               use_ssl = 1;
 
        /*
         * create the websockets context.  This tracks open connections and
@@ -336,23 +362,29 @@ int main(int argc, char **argv)
        info.gid = -1;
        info.uid = -1;
 
+       if (use_ssl)
+               info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
+
        context = lws_create_context(&info);
        if (context == NULL) {
                fprintf(stderr, "Creating libwebsocket context failed\n");
                return 1;
        }
 
-       memset(&i, 0, sizeof(i));
-
        i.context = context;
-       i.address = address;
-       i.port = port;
        i.ssl_connection = use_ssl;
-       i.path = "/";
-       i.host = argv[optind];
-       i.origin = argv[optind];
+       i.host = i.address;
+       i.origin = i.address;
        i.ietf_version_or_minus_one = ietf_version;
        i.client_exts = exts;
+
+       if (!strcmp(prot, "http") || !strcmp(prot, "https")) {
+               lwsl_notice("using %s mode (non-ws)\n", prot);
+               i.method = "GET";
+               do_ws = 0;
+       } else
+               lwsl_notice("using %s mode (ws)\n", prot);
+
        /*
         * sit there servicing the websocket context to handle incoming
         * packets, and drawing random circles on the mirror protocol websocket
@@ -365,17 +397,23 @@ int main(int argc, char **argv)
 
        while (!force_exit) {
 
-               if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
-                       lwsl_notice("dumb: connecting\n");
-                       i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
-                       wsi_dumb = lws_client_connect_via_info(&i);
-               }
-
-               if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2u)) {
-                       lwsl_notice("mirror: connecting\n");
-                       i.protocol = protocols[PROTOCOL_LWS_MIRROR].name;
-                       wsi_mirror = lws_client_connect_via_info(&i);
-               }
+               if (do_ws) {
+                       if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
+                               lwsl_notice("dumb: connecting\n");
+                               i.protocol = protocols[PROTOCOL_DUMB_INCREMENT].name;
+                               wsi_dumb = lws_client_connect_via_info(&i);
+                       }
+
+                       if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2u)) {
+                               lwsl_notice("mirror: connecting\n");
+                               i.protocol = protocols[PROTOCOL_LWS_MIRROR].name;
+                               wsi_mirror = lws_client_connect_via_info(&i);
+                       }
+               } else
+                       if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2u)) {
+                               lwsl_notice("http: connecting\n");
+                               wsi_dumb = lws_client_connect_via_info(&i);
+                       }
 
                lws_service(context, 500);
        }