interpreter: support unchunked mode when h2 connection
This commit is contained in:
parent
673e3aa549
commit
a3bbb0a374
4 changed files with 46 additions and 35 deletions
|
@ -3687,6 +3687,7 @@ struct lws_process_html_args {
|
|||
int len; /**< length of the original data at p */
|
||||
int max_len; /**< maximum length we can grow the data to */
|
||||
int final; /**< set if this is the last chunk of the file */
|
||||
int chunked; /**< 0 == unchunked, 1 == produce chunk headers (incompatible with HTTP/2) */
|
||||
};
|
||||
|
||||
typedef const char *(*lws_process_html_state_cb)(void *data, int index);
|
||||
|
|
10
lib/output.c
10
lib/output.c
|
@ -663,8 +663,9 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
|
|||
|
||||
poss = context->pt_serv_buf_size - n - LWS_H2_FRAME_HEADER_LENGTH;
|
||||
|
||||
if (poss > wsi->http.tx_content_remain)
|
||||
poss = wsi->http.tx_content_remain;
|
||||
if (wsi->http.tx_content_length)
|
||||
if (poss > wsi->http.tx_content_remain)
|
||||
poss = wsi->http.tx_content_remain;
|
||||
|
||||
/*
|
||||
* if there is a hint about how much we will do well to send at one time,
|
||||
|
@ -717,12 +718,13 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
|
|||
lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
|
||||
context->timeout_secs);
|
||||
|
||||
if (wsi->sending_chunked) {
|
||||
if (wsi->interpreting) {
|
||||
args.p = (char *)p;
|
||||
args.len = n;
|
||||
args.max_len = (unsigned int)poss + 128;
|
||||
args.final = wsi->http.filepos + n ==
|
||||
wsi->http.filelen;
|
||||
args.chunked = wsi->sending_chunked;
|
||||
if (user_callback_handle_rxflow(
|
||||
wsi->vhost->protocols[
|
||||
(int)wsi->protocol_interpret_idx].callback,
|
||||
|
@ -745,7 +747,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
|
|||
}
|
||||
#endif
|
||||
m = lws_write(wsi, p, n,
|
||||
wsi->http.filepos == wsi->http.filelen ?
|
||||
wsi->http.filepos + amount == wsi->http.filelen ?
|
||||
LWS_WRITE_HTTP_FINAL :
|
||||
LWS_WRITE_HTTP
|
||||
);
|
||||
|
|
|
@ -1921,6 +1921,7 @@ struct lws {
|
|||
unsigned int cache_intermediaries:1;
|
||||
unsigned int favoured_pollin:1;
|
||||
unsigned int sending_chunked:1;
|
||||
unsigned int interpreting:1;
|
||||
unsigned int already_did_cce:1;
|
||||
unsigned int told_user_closed:1;
|
||||
unsigned int waiting_to_send_close_frame:1;
|
||||
|
|
|
@ -531,7 +531,9 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
|
|||
n = (int)strlen(path);
|
||||
if (n > (int)strlen(pvo->name) &&
|
||||
!strcmp(&path[n - strlen(pvo->name)], pvo->name)) {
|
||||
wsi->sending_chunked = 1;
|
||||
wsi->interpreting = 1;
|
||||
if (!wsi->http2_substream)
|
||||
wsi->sending_chunked = 1;
|
||||
wsi->protocol_interpret_idx =
|
||||
(char)(lws_intptr_t)pvo->value;
|
||||
lwsl_info("want %s interpreted by %s\n", path,
|
||||
|
@ -1125,6 +1127,7 @@ lws_http_action(struct lws *wsi)
|
|||
args.len = uri_len;
|
||||
args.max_len = hit->auth_mask;
|
||||
args.final = 0; /* used to signal callback dealt with it */
|
||||
args.chunked = 0;
|
||||
|
||||
n = wsi->protocol->callback(wsi,
|
||||
LWS_CALLBACK_CHECK_ACCESS_RIGHTS,
|
||||
|
@ -2865,17 +2868,19 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
|
|||
return -1;
|
||||
#endif
|
||||
|
||||
if (!wsi->sending_chunked) {
|
||||
if (lws_add_http_header_content_length(wsi,
|
||||
total_content_length,
|
||||
&p, end))
|
||||
return -1;
|
||||
} else {
|
||||
if (lws_add_http_header_by_token(wsi,
|
||||
if (!wsi->http2_substream) {
|
||||
if (!wsi->sending_chunked) {
|
||||
if (lws_add_http_header_content_length(wsi,
|
||||
total_content_length,
|
||||
&p, end))
|
||||
return -1;
|
||||
} else {
|
||||
if (lws_add_http_header_by_token(wsi,
|
||||
WSI_TOKEN_HTTP_TRANSFER_ENCODING,
|
||||
(unsigned char *)"chunked",
|
||||
7, &p, end))
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wsi->cache_secs && wsi->cache_reuse) {
|
||||
|
@ -3075,31 +3080,33 @@ skip:
|
|||
sp++;
|
||||
}
|
||||
|
||||
/* no space left for final chunk trailer */
|
||||
if (args->final && args->len + 7 >= args->max_len)
|
||||
return -1;
|
||||
if (args->chunked) {
|
||||
/* no space left for final chunk trailer */
|
||||
if (args->final && args->len + 7 >= args->max_len)
|
||||
return -1;
|
||||
|
||||
n = sprintf(buffer, "%X\x0d\x0a", args->len);
|
||||
n = sprintf(buffer, "%X\x0d\x0a", args->len);
|
||||
|
||||
args->p -= n;
|
||||
memcpy(args->p, buffer, n);
|
||||
args->len += n;
|
||||
args->p -= n;
|
||||
memcpy(args->p, buffer, n);
|
||||
args->len += n;
|
||||
|
||||
if (args->final) {
|
||||
sp = args->p + args->len;
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
*sp++ = '0';
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
args->len += 7;
|
||||
} else {
|
||||
sp = args->p + args->len;
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
args->len += 2;
|
||||
if (args->final) {
|
||||
sp = args->p + args->len;
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
*sp++ = '0';
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
args->len += 7;
|
||||
} else {
|
||||
sp = args->p + args->len;
|
||||
*sp++ = '\x0d';
|
||||
*sp++ = '\x0a';
|
||||
args->len += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue