mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
protocol_client_loopback_test
This is used to confirm that SSL client connections can coexist with a vhost doing serving. To set it up, /* * This is a bit fiddly... * * 0) If you want the wss:// test to work, make sure the vhost is marked with * enable-client-ssl if using lwsws, or call lws_init_vhost_client_ssl() on * the vhost if you're doing it by hand. * * 1) enable the protocol on a vhost * * "ws-protocols": [{ * "client-loopback-test": { * "status": "ok" * }, ... * * the vhost should listen on 80 (ws://) or 443 (wss://) * * 2) mount the http part of the test one level down on the same vhost, eg * { * "mountpoint": "/c", * "origin": "callback://client-loopback-test" * } * * 3) Use a browser to visit the mountpoint with a URI attached for looping * back, eg, if testing on localhost * * http://localhost/c/ws://localhost * https://localhost/c/wss://localhost * * 4) The HTTP part of this test protocol will try to do the requested * ws client connection, to the same test protocol on the same * server. */ Results should look like this lwsws[29938]: client connection to localhost:443 with ssl: 1 started lwsws[29938]: server part: LWS_CALLBACK_ESTABLISHED lwsws[29938]: checking client ext permessage-deflate lwsws[29938]: instantiating client ext permessage-deflate lwsws[29938]: Client connection established lwsws[29938]: Client connection received 7 from server 'Made it' Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
fb8be0507e
commit
2700d1c0c3
2 changed files with 200 additions and 0 deletions
|
@ -1231,6 +1231,12 @@ if (LWS_WITH_SERVER_STATUS)
|
|||
create_plugin(protocol_lws_server_status
|
||||
"plugins/protocol_lws_server_status.c")
|
||||
endif()
|
||||
|
||||
if (NOT LWS_WITHOUT_CLIENT)
|
||||
create_plugin(protocol_client_loopback_test
|
||||
"plugins/protocol_client_loopback_test.c")
|
||||
endif(NOT LWS_WITHOUT_CLIENT)
|
||||
|
||||
endif(LWS_WITH_PLUGINS AND LWS_WITH_SHARED)
|
||||
|
||||
#
|
||||
|
|
194
plugins/protocol_client_loopback_test.c
Normal file
194
plugins/protocol_client_loopback_test.c
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* ws protocol handler plugin for "client_loopback_test"
|
||||
*
|
||||
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* These test plugins 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 "../lib/libwebsockets.h"
|
||||
#include <string.h>
|
||||
|
||||
struct per_session_data__client_loopback_test {
|
||||
struct lws *wsi;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a bit fiddly...
|
||||
*
|
||||
* 0) If you want the wss:// test to work, make sure the vhost is marked with
|
||||
* enable-client-ssl if using lwsws, or call lws_init_vhost_client_ssl() on
|
||||
* the vhost if you're doing it by hand.
|
||||
*
|
||||
* 1) enable the protocol on a vhost
|
||||
*
|
||||
* "ws-protocols": [{
|
||||
* "client-loopback-test": {
|
||||
* "status": "ok"
|
||||
* }, ...
|
||||
*
|
||||
* the vhost should listen on 80 (ws://) or 443 (wss://)
|
||||
*
|
||||
* 2) mount the http part of the test one level down on the same vhost, eg
|
||||
* {
|
||||
* "mountpoint": "/c",
|
||||
* "origin": "callback://client-loopback-test"
|
||||
* }
|
||||
*
|
||||
* 3) Use a browser to visit the mountpoint with a URI attached for looping
|
||||
* back, eg, if testing on localhost
|
||||
*
|
||||
* http://localhost/c/ws://localhost
|
||||
* https://localhost/c/wss://localhost
|
||||
*
|
||||
* 4) The HTTP part of this test protocol will try to do the requested
|
||||
* ws client connection, to the same test protocol on the same
|
||||
* server.
|
||||
*/
|
||||
|
||||
static int
|
||||
callback_client_loopback_test(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct lws_client_connect_info i;
|
||||
struct per_session_data__client_loopback_test *pss =
|
||||
(struct per_session_data__client_loopback_test *)user;
|
||||
const char *p = (const char *)in;
|
||||
char buf[100];
|
||||
int n;
|
||||
|
||||
switch (reason) {
|
||||
|
||||
/* HTTP part */
|
||||
|
||||
case LWS_CALLBACK_HTTP:
|
||||
if (len < 10)
|
||||
return -1;
|
||||
|
||||
p++;
|
||||
while (*p && *p != '/')
|
||||
p++;
|
||||
if (!*p) {
|
||||
lws_return_http_status(wsi, 400, "Arg needs to be in format ws://xxx or wss://xxx");
|
||||
return -1;
|
||||
}
|
||||
p++;
|
||||
|
||||
memset(&i, 0, sizeof(i));
|
||||
i.context = lws_get_context(wsi);
|
||||
|
||||
// stacked /// get resolved to /
|
||||
|
||||
if (strncmp(p, "ws:/", 4) == 0) {
|
||||
i.ssl_connection = 0;
|
||||
i.port = 80;
|
||||
p += 4;
|
||||
} else
|
||||
if (strncmp(p, "wss:/", 5) == 0) {
|
||||
i.port = 443;
|
||||
i.ssl_connection = 1;
|
||||
p += 5;
|
||||
} else {
|
||||
sprintf(buf, "Arg %s is not in format ws://xxx or wss://xxx\n", p);
|
||||
lws_return_http_status(wsi, 400, buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i.address = p;
|
||||
i.path = "";
|
||||
i.host = p;
|
||||
i.origin = p;
|
||||
i.ietf_version_or_minus_one = -1;
|
||||
i.protocol = "client-loopback-test";
|
||||
|
||||
pss->wsi = lws_client_connect_via_info(&i);
|
||||
if (!pss->wsi)
|
||||
lws_return_http_status(wsi, 401, "client-loopback-test: connect failed\n");
|
||||
else {
|
||||
lwsl_notice("client connection to %s:%d with ssl: %d started\n",
|
||||
i.address, i.port, i.ssl_connection);
|
||||
lws_return_http_status(wsi, 200, "OK");
|
||||
}
|
||||
|
||||
/* either way, close the triggering http link */
|
||||
|
||||
return -1;
|
||||
|
||||
case LWS_CALLBACK_CLOSED_HTTP:
|
||||
lwsl_notice("Http part closed\n");
|
||||
break;
|
||||
|
||||
/* server part */
|
||||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
lwsl_notice("server part: LWS_CALLBACK_ESTABLISHED\n");
|
||||
strcpy(buf + LWS_PRE, "Made it");
|
||||
n = lws_write(wsi, (unsigned char *)buf + LWS_PRE,
|
||||
7, LWS_WRITE_TEXT);
|
||||
if (n < 7)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
/* client part */
|
||||
|
||||
case LWS_CALLBACK_CLIENT_ESTABLISHED:
|
||||
lwsl_notice("Client connection established\n");
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE:
|
||||
strncpy(buf, in, sizeof(buf) - 1);
|
||||
lwsl_notice("Client connection received %d from server '%s'\n", len, buf);
|
||||
|
||||
/* OK we are done with the client connection */
|
||||
return -1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
{
|
||||
"client-loopback-test",
|
||||
callback_client_loopback_test,
|
||||
sizeof(struct per_session_data__client_loopback_test),
|
||||
1024, /* rx buf size must be >= permessage-deflate rx size */
|
||||
},
|
||||
};
|
||||
|
||||
LWS_VISIBLE int
|
||||
init_protocol_client_loopback_test(struct lws_context *context,
|
||||
struct lws_plugin_capability *c)
|
||||
{
|
||||
if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
|
||||
lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
|
||||
c->api_magic);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c->protocols = protocols;
|
||||
c->count_protocols = ARRAY_SIZE(protocols);
|
||||
c->extensions = NULL;
|
||||
c->count_extensions = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int
|
||||
destroy_protocol_client_loopback_test(struct lws_context *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue