/*
* 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>
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:
lwsl_notice("denied deflate-stream extension\n");
return 1;
}
- if ((strcmp(in, "deflate-frame") == 0) && deny_deflate) {
- lwsl_notice("denied deflate-frame extension\n");
+ if ((strcmp(in, "x-webkit-deflate-frame") == 0))
return 1;
- }
- if ((strcmp(in, "x-google-mux") == 0) && deny_mux) {
- lwsl_notice("denied x-google-mux extension\n");
+ if ((strcmp(in, "deflate-frame") == 0))
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:
callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 +
- LWS_SEND_BUFFER_POST_PADDING];
+ unsigned char buf[LWS_PRE + 4096];
unsigned int rands[4];
int l = 0;
int n;
lwsl_notice("mirror: LWS_CALLBACK_CLIENT_ESTABLISHED\n");
- lws_get_random(lws_get_ctx(wsi), rands, sizeof(rands[0]));
+ lws_get_random(lws_get_context(wsi), rands, sizeof(rands[0]));
mirror_lifetime = 16384 + (rands[0] & 65535);
/* useful to test single connection stability */
if (longlived)
case LWS_CALLBACK_CLIENT_WRITEABLE:
for (n = 0; n < 1; n++) {
- lws_get_random(lws_get_ctx(wsi), rands, sizeof(rands));
- l += sprintf((char *)&buf[LWS_SEND_BUFFER_PRE_PADDING + l],
- "c #%06X %d %d %d;",
- (int)rands[0] & 0xffffff,
- (int)rands[1] % 500,
- (int)rands[2] % 250,
- (int)rands[3] % 24);
+ lws_get_random(lws_get_context(wsi), rands, sizeof(rands));
+ l += sprintf((char *)&buf[LWS_PRE + l],
+ "c #%06X %u %u %u;",
+ rands[0] & 0xffffff, /* colour */
+ rands[1] & 511, /* x */
+ rands[2] & 255, /* y */
+ (rands[3] & 31) + 1); /* radius */
}
- n = lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], l,
+ n = lws_write(wsi, &buf[LWS_PRE], l,
opts | LWS_WRITE_TEXT);
if (n < 0)
return -1;
{ NULL, NULL, 0, 0 } /* end */
};
+static const struct lws_extension exts[] = {
+ {
+ "permessage-deflate",
+ lws_extension_callback_pm_deflate,
+ "permessage-deflate; client_max_window_bits"
+ },
+ {
+ "deflate-frame",
+ lws_extension_callback_pm_deflate,
+ "deflate_frame"
+ },
+ { NULL, NULL, NULL /* terminator */ }
+};
+
+
+
void sighandler(int sig)
{
force_exit = 1;
{ NULL, 0, 0, 0 }
};
-static int ratelimit_connects(unsigned int *last, int secs)
+static int ratelimit_connects(unsigned int *last, unsigned int secs)
{
struct timeval tv;
int main(int argc, char **argv)
{
- int n = 0, ret = 0, port = 7681, use_ssl = 0;
- unsigned int rl_dumb = 0, rl_mirror = 0;
+ int n = 0, ret = 0, port = 7681, use_ssl = 0, ietf_version = -1;
+ 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;
- int ietf_version = -1; /* latest */
- 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;
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
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = protocols;
-#ifndef LWS_NO_EXTENSIONS
- info.extensions = lws_get_internal_extensions();
-#endif
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;
}
+ i.context = context;
+ i.ssl_connection = use_ssl;
+ 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
while (!force_exit) {
- if (!wsi_dumb && ratelimit_connects(&rl_dumb, 2)) {
- lwsl_notice("dumb: connecting\n");
- wsi_dumb = lws_client_connect(context, address, port,
- use_ssl, "/", argv[optind], argv[optind],
- protocols[PROTOCOL_DUMB_INCREMENT].name,
- ietf_version);
- }
-
- if (!wsi_mirror && ratelimit_connects(&rl_mirror, 2)) {
- lwsl_notice("mirror: connecting\n");
- wsi_mirror = lws_client_connect(context,
- address, port, use_ssl, "/",
- argv[optind], argv[optind],
- protocols[PROTOCOL_LWS_MIRROR].name,
- ietf_version);
- }
+ 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);
}