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:
parent
fff9ca6ee4
commit
dd3bae8c71
9 changed files with 73 additions and 13 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,"
|
||||
|
|
|
@ -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__,
|
||||
|
|
|
@ -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\","
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue