1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00
libwebsockets/minimal-examples/http-server/minimal-http-server-h2-long-poll/minimal-http-server.c
Andy Green c9731c5f17 type comparisons: fixes
This is a huge patch that should be a global NOP.

For unix type platforms it enables -Wconversion to issue warnings (-> error)
for all automatic casts that seem less than ideal but are normally concealed
by the toolchain.

This is things like passing an int to a size_t argument.  Once enabled, I
went through all args on my default build (which build most things) and
tried to make the removed default cast explicit.

With that approach it neither change nor bloat the code, since it compiles
to whatever it was doing before, just with the casts made explicit... in a
few cases I changed some length args from int to size_t but largely left
the causes alone.

From now on, new code that is relying on less than ideal casting
will complain and nudge me to improve it by warnings.
2021-01-05 10:56:38 +00:00

158 lines
3.9 KiB
C

/*
* lws-minimal-http-server-h2-long-poll
*
* Written in 2010-2019 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* This demonstrates an h2 server that supports "long poll"
* immortal client connections. For simplicity it doesn't serve
* any regular files, you can add a mount to do it if you want.
*
* The protocol keeps the long poll h2 stream open, and sends
* the time on the stream once per minute. Normally idle h2
* connections are closed by default within 30s, so this demonstrates
* the stream and network connection are operating as "immortal"
* on both sides.
*
* See http-client/minimal-http-client-h2-long-poll for the
* client example that connects and transitions the stream to the
* immortal long poll mode.
*/
#include <libwebsockets.h>
#include <string.h>
#include <signal.h>
static int interrupted;
struct pss {
struct lws *wsi;
lws_sorted_usec_list_t sul;
char pending;
};
static const lws_retry_bo_t retry = {
.secs_since_valid_ping = 5,
.secs_since_valid_hangup = 10,
};
static void
sul_cb(lws_sorted_usec_list_t *sul)
{
struct pss *pss = (struct pss *)lws_container_of(sul, struct pss, sul);
pss->pending = 1;
lws_callback_on_writable(pss->wsi);
/* interval 1min... longer than any normal timeout */
lws_sul_schedule(lws_get_context(pss->wsi), 0, &pss->sul, sul_cb,
60 * LWS_US_PER_SEC);
}
static int
callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
void *in, size_t len)
{
struct pss * pss = (struct pss *)user;
uint8_t buf[LWS_PRE + LWS_RECOMMENDED_MIN_HEADER_SPACE],
*start = &buf[LWS_PRE], *p = start,
*end = p + sizeof(buf) - LWS_PRE;
int m, n;
switch (reason) {
case LWS_CALLBACK_HTTP:
lwsl_user("%s: connect\n", __func__);
pss->wsi = wsi;
if (lws_add_http_common_headers(wsi, HTTP_STATUS_OK,
"text/html",
LWS_ILLEGAL_HTTP_CONTENT_LEN, /* no content len */
&p, end))
return 1;
if (lws_finalize_write_http_header(wsi, start, &p, end))
return 1;
sul_cb(&pss->sul);
return 0;
case LWS_CALLBACK_CLOSED_HTTP:
if (!pss)
break;
lws_sul_cancel(&pss->sul);
break;
case LWS_CALLBACK_HTTP_WRITEABLE:
if (!pss->pending)
break;
n = lws_snprintf((char *)p, sizeof(buf) - LWS_PRE, "%llu",
(unsigned long long)lws_now_usecs());
m = lws_write(wsi, p, (unsigned int)n, LWS_WRITE_HTTP);
if (m < n) {
lwsl_err("ERROR %d writing to socket\n", n);
return -1;
}
break;
default:
break;
}
return lws_callback_http_dummy(wsi, reason, user, in, len);
}
static struct lws_protocols protocols[] = {
{ "http", callback_http, sizeof(struct pss), 0 },
{ NULL, NULL, 0, 0 } /* terminator */
};
void sigint_handler(int sig)
{
interrupted = 1;
}
int main(int argc, const char **argv)
{
struct lws_context_creation_info info;
struct lws_context *context;
const char *p;
int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
signal(SIGINT, sigint_handler);
if ((p = lws_cmdline_option(argc, argv, "-d")))
logs = atoi(p);
lws_set_log_level(logs, NULL);
lwsl_user("LWS minimal http server h2 long poll\n");
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
info.port = 7681;
#if defined(LWS_WITH_TLS)
info.ssl_cert_filepath = "localhost-100y.cert";
info.ssl_private_key_filepath = "localhost-100y.key";
#endif
info.protocols = protocols;
info.options =
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
LWS_SERVER_OPTION_VH_H2_HALF_CLOSED_LONG_POLL |
LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
/* the default validity check is 5m / 5m10s... -v = 5s / 10s */
if (lws_cmdline_option(argc, argv, "-v"))
info.retry_and_idle_policy = &retry;
context = lws_create_context(&info);
if (!context) {
lwsl_err("lws init failed\n");
return 1;
}
while (n >= 0 && !interrupted)
n = lws_service(context, 0);
lws_context_destroy(context);
return 0;
}