summaryrefslogtreecommitdiff
path: root/thirdparty/libwebsockets/roles/http/server
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/libwebsockets/roles/http/server')
-rw-r--r--thirdparty/libwebsockets/roles/http/server/lejp-conf.c64
-rw-r--r--thirdparty/libwebsockets/roles/http/server/parsers.c26
-rw-r--r--thirdparty/libwebsockets/roles/http/server/server.c50
3 files changed, 89 insertions, 51 deletions
diff --git a/thirdparty/libwebsockets/roles/http/server/lejp-conf.c b/thirdparty/libwebsockets/roles/http/server/lejp-conf.c
index e9ce854cfc..fbf10c288e 100644
--- a/thirdparty/libwebsockets/roles/http/server/lejp-conf.c
+++ b/thirdparty/libwebsockets/roles/http/server/lejp-conf.c
@@ -205,6 +205,7 @@ struct jpargs {
unsigned int enable_client_ssl:1;
unsigned int fresh_mount:1;
unsigned int any_vhosts:1;
+ unsigned int chunk:1;
};
static void *
@@ -213,6 +214,8 @@ lwsws_align(struct jpargs *a)
if ((lws_intptr_t)(a->p) & 15)
a->p += 16 - ((lws_intptr_t)(a->p) & 15);
+ a->chunk = 0;
+
return a->p;
}
@@ -225,7 +228,7 @@ arg_to_bool(const char *s)
if (n)
return 1;
- for (n = 0; n < (int)ARRAY_SIZE(on); n++)
+ for (n = 0; n < (int)LWS_ARRAY_SIZE(on); n++)
if (!strcasecmp(s, on[n]))
return 1;
@@ -413,25 +416,30 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
}
/* this catches, eg, vhosts[].headers[].xxx */
- if (reason == LEJPCB_VAL_STR_END &&
+ if ((reason == LEJPCB_VAL_STR_END || reason == LEJPCB_VAL_STR_CHUNK) &&
ctx->path_match == LEJPVP_HEADERS_NAME + 1) {
- headers = lwsws_align(a);
- a->p += sizeof(*headers);
-
- n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p);
- /* ie, enable this protocol, no options yet */
- headers->next = a->info->headers;
- a->info->headers = headers;
- headers->name = a->p;
- // lwsl_notice(" adding header %s=%s\n", a->p, ctx->buf);
- a->p += n - 1;
- *(a->p++) = ':';
- if (a->p < a->end)
- *(a->p++) = '\0';
- else
- *(a->p - 1) = '\0';
- headers->value = a->p;
- headers->options = NULL;
+ if (!a->chunk) {
+ headers = lwsws_align(a);
+ a->p += sizeof(*headers);
+
+ n = lejp_get_wildcard(ctx, 0, a->p,
+ lws_ptr_diff(a->end, a->p));
+ /* ie, add this header */
+ headers->next = a->info->headers;
+ a->info->headers = headers;
+ headers->name = a->p;
+
+ lwsl_notice(" adding header %s=%s\n", a->p, ctx->buf);
+ a->p += n - 1;
+ *(a->p++) = ':';
+ if (a->p < a->end)
+ *(a->p++) = '\0';
+ else
+ *(a->p - 1) = '\0';
+ headers->value = a->p;
+ headers->options = NULL;
+ }
+ a->chunk = reason == LEJPCB_VAL_STR_CHUNK;
goto dostring;
}
@@ -502,7 +510,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
if (a->last)
a->last->mount_next = m;
- for (n = 0; n < (int)ARRAY_SIZE(mount_protocols); n++)
+ for (n = 0; n < (int)LWS_ARRAY_SIZE(mount_protocols); n++)
if (!strncmp(a->m.origin, mount_protocols[n],
strlen(mount_protocols[n]))) {
lwsl_info("----%s\n", a->m.origin);
@@ -512,7 +520,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
break;
}
- if (n == (int)ARRAY_SIZE(mount_protocols)) {
+ if (n == (int)LWS_ARRAY_SIZE(mount_protocols)) {
lwsl_err("unsupported protocol:// %s\n", a->m.origin);
return 1;
}
@@ -750,6 +758,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
dostring:
p = ctx->buf;
+ p[LEJP_STRING_CHUNK] = '\0';
p1 = strstr(p, ESC_INSTALL_DATADIR);
if (p1) {
n = p1 - p;
@@ -762,7 +771,8 @@ dostring:
}
a->p += lws_snprintf(a->p, a->end - a->p, "%s", p);
- *(a->p)++ = '\0';
+ if (reason == LEJPCB_VAL_STR_END)
+ *(a->p)++ = '\0';
return 0;
}
@@ -779,7 +789,7 @@ lwsws_get_config(void *user, const char *f, const char * const *paths,
struct lejp_ctx ctx;
int n, m, fd;
- fd = open(f, O_RDONLY);
+ fd = lws_open(f, O_RDONLY);
if (fd < 0) {
lwsl_err("Cannot open %s\n", f);
return 2;
@@ -927,11 +937,11 @@ lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d);
if (lwsws_get_config(&a, dd, paths_global,
- ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
+ LWS_ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
return 1;
lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d);
if (lwsws_get_config_d(&a, dd, paths_global,
- ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
+ LWS_ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
return 1;
a.plugin_dirs[a.count_plugin_dirs] = NULL;
@@ -962,11 +972,11 @@ lwsws_get_config_vhosts(struct lws_context *context,
lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d);
if (lwsws_get_config(&a, dd, paths_vhosts,
- ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
+ LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
return 1;
lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d);
if (lwsws_get_config_d(&a, dd, paths_vhosts,
- ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
+ LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
return 1;
*cs = a.p;
diff --git a/thirdparty/libwebsockets/roles/http/server/parsers.c b/thirdparty/libwebsockets/roles/http/server/parsers.c
index cb022e362b..482bdc676a 100644
--- a/thirdparty/libwebsockets/roles/http/server/parsers.c
+++ b/thirdparty/libwebsockets/roles/http/server/parsers.c
@@ -563,7 +563,7 @@ int LWS_WARN_UNUSED_RESULT
lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s)
{
wsi->http.ah->nfrag++;
- if (wsi->http.ah->nfrag == ARRAY_SIZE(wsi->http.ah->frags)) {
+ if (wsi->http.ah->nfrag == LWS_ARRAY_SIZE(wsi->http.ah->frags)) {
lwsl_warn("More hdr frags than we can deal with, dropping\n");
return -1;
}
@@ -677,18 +677,16 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
return -1;
/* genuine delimiter */
if ((c == '&' || c == ';') && !enc) {
- if (issue_char(wsi, c) < 0)
+ if (issue_char(wsi, '\0') < 0)
return -1;
- /* swallow the terminator */
- ah->frags[ah->nfrag].len--;
/* link to next fragment */
ah->frags[ah->nfrag].nfrag = ah->nfrag + 1;
ah->nfrag++;
- if (ah->nfrag >= ARRAY_SIZE(ah->frags))
+ if (ah->nfrag >= LWS_ARRAY_SIZE(ah->frags))
goto excessive;
/* start next fragment after the & */
ah->post_literal_equal = 0;
- ah->frags[ah->nfrag].offset = ah->pos;
+ ah->frags[ah->nfrag].offset = ++ah->pos;
ah->frags[ah->nfrag].len = 0;
ah->frags[ah->nfrag].nfrag = 0;
goto swallow;
@@ -787,9 +785,9 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
/* move to using WSI_TOKEN_HTTP_URI_ARGS */
ah->nfrag++;
- if (ah->nfrag >= ARRAY_SIZE(ah->frags))
+ if (ah->nfrag >= LWS_ARRAY_SIZE(ah->frags))
goto excessive;
- ah->frags[ah->nfrag].offset = ah->pos;
+ ah->frags[ah->nfrag].offset = ++ah->pos;
ah->frags[ah->nfrag].len = 0;
ah->frags[ah->nfrag].nfrag = 0;
@@ -852,10 +850,10 @@ lws_parse(struct lws *wsi, unsigned char *buf, int *len)
c == ' ')
break;
- for (m = 0; m < ARRAY_SIZE(methods); m++)
+ for (m = 0; m < LWS_ARRAY_SIZE(methods); m++)
if (ah->parser_state == methods[m])
break;
- if (m == ARRAY_SIZE(methods))
+ if (m == LWS_ARRAY_SIZE(methods))
/* it was not any of the methods */
goto check_eol;
@@ -983,7 +981,7 @@ nope:
if (ah->lextable_pos < 0 && lwsi_role_h1(wsi) &&
lwsi_role_server(wsi)) {
/* this is not a header we know about */
- for (m = 0; m < ARRAY_SIZE(methods); m++)
+ for (m = 0; m < LWS_ARRAY_SIZE(methods); m++)
if (ah->frag_index[methods[m]]) {
/*
* already had the method, no idea what
@@ -996,7 +994,7 @@ nope:
* hm it's an unknown http method from a client in fact,
* it cannot be valid http
*/
- if (m == ARRAY_SIZE(methods)) {
+ if (m == LWS_ARRAY_SIZE(methods)) {
/*
* are we set up to accept raw in these cases?
*/
@@ -1025,7 +1023,7 @@ nope:
lextable[ah->lextable_pos + 1];
lwsl_parser("known hdr %d\n", n);
- for (m = 0; m < ARRAY_SIZE(methods); m++)
+ for (m = 0; m < LWS_ARRAY_SIZE(methods); m++)
if (n == methods[m] &&
ah->frag_index[methods[m]]) {
lwsl_warn("Duplicated method\n");
@@ -1061,7 +1059,7 @@ nope:
start_fragment:
ah->nfrag++;
excessive:
- if (ah->nfrag == ARRAY_SIZE(ah->frags)) {
+ if (ah->nfrag == LWS_ARRAY_SIZE(ah->frags)) {
lwsl_warn("More hdr frags than we can deal with\n");
return -1;
}
diff --git a/thirdparty/libwebsockets/roles/http/server/server.c b/thirdparty/libwebsockets/roles/http/server/server.c
index 350af3cd7e..abd86dc9b5 100644
--- a/thirdparty/libwebsockets/roles/http/server/server.c
+++ b/thirdparty/libwebsockets/roles/http/server/server.c
@@ -131,6 +131,17 @@ done_list:
(void)n;
#if defined(__linux__)
+#ifdef LWS_WITH_UNIX_SOCK
+ /*
+ * A Unix domain sockets cannot be bound for several times, even if we set
+ * the SO_REUSE* options on.
+ * However, fortunately, each thread is able to independently listen when
+ * running on a reasonably new Linux kernel. So we can safely assume
+ * creating just one listening socket for a multi-threaded environment won't
+ * fail in most cases.
+ */
+ if (!LWS_UNIX_SOCK_ENABLED(vhost))
+#endif
limit = vhost->context->count_threads;
#endif
@@ -694,7 +705,7 @@ lws_find_string_in_file(const char *filename, const char *string, int stringlen)
char buf[128];
int fd, match = 0, pos = 0, n = 0, hit = 0;
- fd = open(filename, O_RDONLY);
+ fd = lws_open(filename, O_RDONLY);
if (fd < 0) {
lwsl_err("can't open auth file: %s\n", filename);
return 0;
@@ -812,7 +823,7 @@ lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len)
{
int n, count = 0;
- for (n = 0; n < (int)ARRAY_SIZE(methods); n++)
+ for (n = 0; n < (int)LWS_ARRAY_SIZE(methods); n++)
if (lws_hdr_total_length(wsi, methods[n]))
count++;
if (!count) {
@@ -827,7 +838,7 @@ lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len)
return -1;
}
- for (n = 0; n < (int)ARRAY_SIZE(methods); n++)
+ for (n = 0; n < (int)LWS_ARRAY_SIZE(methods); n++)
if (lws_hdr_total_length(wsi, methods[n])) {
*puri_ptr = lws_hdr_simple_ptr(wsi, methods[n]);
*puri_len = lws_hdr_total_length(wsi, methods[n]);
@@ -857,7 +868,7 @@ lws_http_action(struct lws *wsi)
};
meth = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len);
- if (meth < 0 || meth >= (int)ARRAY_SIZE(method_names))
+ if (meth < 0 || meth >= (int)LWS_ARRAY_SIZE(method_names))
goto bail_nuke_ah;
/* we insist on absolute paths */
@@ -1128,7 +1139,7 @@ lws_http_action(struct lws *wsi)
}
if (pcolon > pslash)
pcolon = NULL;
-
+
if (pcolon)
n = pcolon - hit->origin;
else
@@ -1142,13 +1153,13 @@ lws_http_action(struct lws *wsi)
i.address = ads;
i.port = 80;
- if (hit->origin_protocol == LWSMPRO_HTTPS) {
+ if (hit->origin_protocol == LWSMPRO_HTTPS) {
i.port = 443;
i.ssl_connection = 1;
}
if (pcolon)
i.port = atoi(pcolon + 1);
-
+
lws_snprintf(rpath, sizeof(rpath) - 1, "/%s/%s", pslash + 1,
uri_ptr + hit->mountpoint_len);
lws_clean_url(rpath);
@@ -1164,7 +1175,7 @@ lws_http_action(struct lws *wsi)
p++;
}
}
-
+
i.path = rpath;
i.host = i.address;
@@ -1178,7 +1189,7 @@ lws_http_action(struct lws *wsi)
"from %s, to %s\n",
i.address, i.port, i.path, i.ssl_connection,
i.uri_replace_from, i.uri_replace_to);
-
+
if (!lws_client_connect_via_info(&i)) {
lwsl_err("proxy connect fail\n");
return 1;
@@ -1714,12 +1725,31 @@ lws_http_transaction_completed(struct lws *wsi)
{
int n = NO_PENDING_TIMEOUT;
+ if (wsi->trunc_len) {
+ /*
+ * ...so he tried to send something large as the http reply,
+ * it went as a partial, but he immediately said the
+ * transaction was completed.
+ *
+ * Defer the transaction completed until the last part of the
+ * partial is sent.
+ */
+ lwsl_notice("%s: deferring due to partial\n", __func__);
+ wsi->http.deferred_transaction_completed = 1;
+
+ return 0;
+ }
+
lwsl_info("%s: wsi %p\n", __func__, wsi);
lws_access_log(wsi);
if (!wsi->hdr_parsing_completed) {
- lwsl_notice("%s: ignoring, ah parsing incomplete\n", __func__);
+ char peer[64];
+ lws_get_peer_simple(wsi, peer, sizeof(peer) - 1);
+ peer[sizeof(peer) - 1] = '\0';
+ lwsl_notice("%s: (from %s) ignoring, ah parsing incomplete\n",
+ __func__, peer);
return 0;
}