1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

ss: multipart without processing

Change the default to not process multipart mime at SS layer.

If it's desired, then set "http_multipart_ss_in" true in the policy on the streamtype.

To test, use lws-minimal-secure-streams-avs, which uses SS processing as it is.

To check it without the processing, change #if 1 to #if 0 around the policy for
"http_multipart_ss_in" in both places in avs.c, and also enable the hexdump in ss_avs_metadata_rx()
also in avs.c, and observe the multipart framing is passed through unchanged.
This commit is contained in:
Andy Green 2020-08-10 10:38:04 +01:00
parent fff9ca6ee4
commit dd3bae8c71
9 changed files with 73 additions and 13 deletions

View file

@ -126,6 +126,8 @@ enum {
/**< we listen on a socket as a server */
LWSSSPOLF_ALLOW_REDIRECTS = (1 << 16),
/**< follow redirects */
LWSSSPOLF_HTTP_MULTIPART_IN = (1 << 17),
/**< handle inbound multipart mime at SS level */
};
typedef struct lws_ss_trust_store {

View file

@ -403,6 +403,10 @@ sent an `END_STREAM`, even though we have sent headers with `END_HEADERS`.
Set this to `true` if the peer server has the quirk it sends an maximum initial tx credit
of 0x7fffffff and then later increments it illegally.
### `http_multipart_ss_in`
Indicates that SS should parse any incoming multipart mime on this stream
### `http_multipart_name`
Indicates this stream goes out using multipart mime, and provides the name part of the

View file

@ -80,6 +80,7 @@ static const char * const lejp_tokens_policy[] = {
"s[].*.http_www_form_urlencoded",
"s[].*.http_expect",
"s[].*.http_fail_redirect",
"s[].*.http_multipart_ss_in",
"s[].*.ws_subprotocol",
"s[].*.ws_binary",
"s[].*.local_sink",
@ -151,6 +152,7 @@ typedef enum {
LSSPPT_HTTP_WWW_FORM_URLENCODED,
LSSPPT_HTTP_EXPECT,
LSSPPT_HTTP_FAIL_REDIRECT,
LSSPPT_HTTP_MULTIPART_SS_IN,
LSSPPT_WS_SUBPROTOCOL,
LSSPPT_WS_BINARY,
LSSPPT_LOCAL_SINK,
@ -584,6 +586,11 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
a->curr[LTY_POLICY].p->flags |=
LWSSSPOLF_ALLOW_REDIRECTS;
break;
case LSSPPT_HTTP_MULTIPART_SS_IN:
if (reason == LEJPCB_VAL_TRUE)
a->curr[LTY_POLICY].p->flags |=
LWSSSPOLF_HTTP_MULTIPART_IN;
return 0;
case LSSPPT_RETRYPTR:
bot = a->heads[LTY_BACKOFF].b;

View file

@ -318,7 +318,11 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
#if defined(LWS_WITH_SS_RIDESHARE)
/*
* We should only especially process multipart ourselves if
* There are two ways we might want to deal with multipart,
* one is pass it through raw (although the user code needs
* a helping hand for learning the boundary), and the other
* is to deframe it and provide basically submessages in the
* different parts.
*/
if (lws_hdr_copy(wsi, (char *)buf, sizeof(buf),
@ -367,7 +371,8 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
/* inform the ss that a related message group begins */
if (h->u.http.boundary[0])
if ((h->policy->flags & LWSSSPOLF_HTTP_MULTIPART_IN) &&
h->u.http.boundary[0])
h->info.rx(ss_to_userobj(h), NULL, 0,
LWSSS_FLAG_RELATED_START);
@ -460,7 +465,8 @@ malformed:
return 0;
#if defined(LWS_WITH_SS_RIDESHARE)
if (h->u.http.boundary[0])
if ((h->policy->flags & LWSSSPOLF_HTTP_MULTIPART_IN) &&
h->u.http.boundary[0])
return ss_http_multipart_parser(h, in, len);
#endif

View file

@ -203,6 +203,7 @@ static const char * const default_ss_policy =
"\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_ss_in\":" "true,"
"\"nailed_up\":" "true,"
"\"long_poll\":" "true,"
"\"retry\":" "\"default\","
@ -229,6 +230,7 @@ static const char * const default_ss_policy =
"\"http_multipart_name\":" "\"metadata\","
"\"http_mime_content_type\":" "\"application/json; charset=UTF-8\","
"\"http_no_content_length\":" "true,"
"\"http_multipart_ss_in\":" "true,"
"\"rideshare\":" "\"avs_audio\","
"\"retry\":" "\"default\","
"\"plugins\":" "[],"
@ -246,6 +248,7 @@ static const char * const default_ss_policy =
"\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_ss_in\":" "true,"
"\"http_multipart_name\":" "\"audio\","
"\"http_mime_content_type\":" "\"application/octet-stream\","
"\"http_no_content_length\":" "true,"

View file

@ -120,7 +120,9 @@ ss_avs_metadata_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
lwsl_notice("%s: rideshare %s, len %d, flags 0x%x\n", __func__,
lws_ss_rideshare(m->ss), (int)len, flags);
// lwsl_hexdump_warn(buf, len);
#if 0
lwsl_hexdump_warn(buf, len);
#endif
n = sizeof(m->buf) - ((m->head - m->tail) % sizeof(m->buf));
lwsl_info("%s: len %d, buf h %d, t %d, space %d\n", __func__,

View file

@ -195,6 +195,9 @@ static const char * const default_ss_policy =
"\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_name\":" "\"metadata\","
"\"http_mime_content_type\":" "\"application/json; charset=UTF-8\","
#if 1
"\"http_multipart_ss_in\":" "true,"
#endif
"\"rideshare\":" "\"avs_audio\","
"\"retry\":" "\"default\","
"\"plugins\":" "[],"
@ -211,6 +214,9 @@ static const char * const default_ss_policy =
"\"plugins\":" "[],"
"\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
#if 1
"\"http_multipart_ss_in\":" "true,"
#endif
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_name\":" "\"audio\","

View file

@ -14,7 +14,7 @@
extern const lws_ss_info_t ssi_client, ssi_server;
static struct lws_context *context;
int interrupted, bad = 1;
int interrupted, bad = 1, multipart;
static const char * const default_ss_policy =
"{"
"\"release\":" "\"01234567\","
@ -302,6 +302,10 @@ int main(int argc, const char **argv)
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
lws_cmdline_option_handle_builtin(argc, argv, &info);
if (lws_cmdline_option(argc, argv, "-m"))
multipart = 1;
lwsl_user("LWS Secure Streams Server\n");
info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |

View file

@ -10,9 +10,10 @@
#include <libwebsockets.h>
#include <assert.h>
extern int interrupted, bad;
extern int interrupted, bad, multipart;
static const char *html =
/* normally we serve this... */
"<head><meta content=\"text/html;charset=utf-8\" "
"http-equiv=\"Content-Type\"><script>"
" var ws = new WebSocket(\"wss://localhost:7681\", \"mywsprotocol\");"
@ -25,7 +26,23 @@ static const char *html =
"</script></head><html><body>"
"Hello from the web server<br>"
"<div id=\"wsd\"></div>"
"</body></html>";
"</body></html>",
*multipart_html =
/*
* If you use -m commandline switch we send this instead, as
* multipart/form-data
*/
"--aBoundaryString\r\n"
"Content-Disposition: form-data; name=\"myFile\"; filename=\"xxx.txt\"\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"The file contents\r\n"
"--aBoundaryString\r\n"
"Content-Disposition: form-data; name=\"myField\"\r\n"
"\r\n"
"(data)\r\n"
"--aBoundaryString--\r\n";
typedef struct myss {
@ -68,14 +85,18 @@ myss_srv_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len,
int *flags)
{
myss_srv_t *m = (myss_srv_t *)userobj;
const char *send = html;
if (m->upgraded)
return LWSSSSRET_TX_DONT_SEND;
if (multipart)
send = multipart_html;
*flags = LWSSS_FLAG_SOM | LWSSS_FLAG_EOM;
lws_strncpy((char *)buf, html, *len);
*len = strlen(html);
lws_strncpy((char *)buf, send, *len);
*len = strlen(send);
return 0;
}
@ -168,13 +189,18 @@ myss_srv_state(void *userobj, void *sh, lws_ss_constate_t state,
*/
lws_ss_server_ack(m->ss, 0);
/*
* ... it's going to be text/html...
* ... it's going to be either text/html or multipart ...
*/
lws_ss_set_metadata(m->ss, "mime", "text/html", 9);
if (multipart)
lws_ss_set_metadata(m->ss, "mime",
"multipart/form-data; boundary=aBoundaryString", 45);
else
lws_ss_set_metadata(m->ss, "mime", "text/html", 9);
/*
* ...it's going to be 128 byte (and request tx)
* ...it's going to be whatever size it is (and request tx)
*/
lws_ss_request_tx_len(m->ss, strlen(html));
lws_ss_request_tx_len(m->ss, multipart ? strlen(multipart_html) :
strlen(html));
break;
case LWSSSCS_SERVER_UPGRADE: