2 * ws protocol handler plugin for "client_loopback_test"
4 * Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
9 * The person who associated a work with this deed has dedicated
10 * the work to the public domain by waiving all of his or her rights
11 * to the work worldwide under copyright law, including all related
12 * and neighboring rights, to the extent allowed by law. You can copy,
13 * modify, distribute and perform the work, even for commercial purposes,
14 * all without asking permission.
16 * These test plugins are intended to be adapted for use in your code, which
17 * may be proprietary. So unlike the library itself, they are licensed
23 #include "../lib/libwebsockets.h"
26 struct per_session_data__client_loopback_test {
31 * This is a bit fiddly...
33 * 0) If you want the wss:// test to work, make sure the vhost is marked with
34 * enable-client-ssl if using lwsws, or call lws_init_vhost_client_ssl() on
35 * the vhost if you're doing it by hand.
37 * 1) enable the protocol on a vhost
40 * "client-loopback-test": {
44 * the vhost should listen on 80 (ws://) or 443 (wss://)
46 * 2) mount the http part of the test one level down on the same vhost, eg
49 * "origin": "callback://client-loopback-test"
52 * 3) Use a browser to visit the mountpoint with a URI attached for looping
53 * back, eg, if testing on localhost
55 * http://localhost/c/ws://localhost
56 * https://localhost/c/wss://localhost
58 * 4) The HTTP part of this test protocol will try to do the requested
59 * ws client connection, to the same test protocol on the same
64 callback_client_loopback_test(struct lws *wsi, enum lws_callback_reasons reason,
65 void *user, void *in, size_t len)
67 struct lws_client_connect_info i;
68 struct per_session_data__client_loopback_test *pss =
69 (struct per_session_data__client_loopback_test *)user;
70 const char *p = (const char *)in;
78 case LWS_CALLBACK_HTTP:
83 while (*p && *p != '/')
86 lws_return_http_status(wsi, 400, "Arg needs to be in format ws://xxx or wss://xxx");
91 memset(&i, 0, sizeof(i));
92 i.context = lws_get_context(wsi);
94 // stacked /// get resolved to /
96 if (strncmp(p, "ws:/", 4) == 0) {
101 if (strncmp(p, "wss:/", 5) == 0) {
103 i.ssl_connection = 1;
106 sprintf(buf, "Arg %s is not in format ws://xxx or wss://xxx\n", p);
107 lws_return_http_status(wsi, 400, buf);
115 i.ietf_version_or_minus_one = -1;
116 i.protocol = "client-loopback-test";
118 pss->wsi = lws_client_connect_via_info(&i);
120 lws_return_http_status(wsi, 401, "client-loopback-test: connect failed\n");
122 lwsl_notice("client connection to %s:%d with ssl: %d started\n",
123 i.address, i.port, i.ssl_connection);
124 lws_return_http_status(wsi, 200, "OK");
127 /* either way, close the triggering http link */
131 case LWS_CALLBACK_CLOSED_HTTP:
132 lwsl_notice("Http part closed\n");
137 case LWS_CALLBACK_ESTABLISHED:
138 lwsl_notice("server part: LWS_CALLBACK_ESTABLISHED\n");
139 strcpy(buf + LWS_PRE, "Made it");
140 n = lws_write(wsi, (unsigned char *)buf + LWS_PRE,
148 case LWS_CALLBACK_CLIENT_ESTABLISHED:
149 lwsl_notice("Client connection established\n");
152 case LWS_CALLBACK_CLIENT_RECEIVE:
153 strncpy(buf, in, sizeof(buf) - 1);
154 lwsl_notice("Client connection received %ld from server '%s'\n", (long)len, buf);
156 /* OK we are done with the client connection */
166 static const struct lws_protocols protocols[] = {
168 "client-loopback-test",
169 callback_client_loopback_test,
170 sizeof(struct per_session_data__client_loopback_test),
171 1024, /* rx buf size must be >= permessage-deflate rx size */
175 LWS_EXTERN LWS_VISIBLE int
176 init_protocol_client_loopback_test(struct lws_context *context,
177 struct lws_plugin_capability *c)
179 if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
180 lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
185 c->protocols = protocols;
186 c->count_protocols = ARRAY_SIZE(protocols);
187 c->extensions = NULL;
188 c->count_extensions = 0;
193 LWS_EXTERN LWS_VISIBLE int
194 destroy_protocol_client_loopback_test(struct lws_context *context)