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

interpreter: support unchunked mode when h2 connection

This commit is contained in:
Andy Green 2018-01-14 20:09:41 +08:00
parent 673e3aa549
commit a3bbb0a374
4 changed files with 46 additions and 35 deletions

View file

@ -3687,6 +3687,7 @@ struct lws_process_html_args {
int len; /**< length of the original data at p */ int len; /**< length of the original data at p */
int max_len; /**< maximum length we can grow the data to */ int max_len; /**< maximum length we can grow the data to */
int final; /**< set if this is the last chunk of the file */ 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); typedef const char *(*lws_process_html_state_cb)(void *data, int index);

View file

@ -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; poss = context->pt_serv_buf_size - n - LWS_H2_FRAME_HEADER_LENGTH;
if (poss > wsi->http.tx_content_remain) if (wsi->http.tx_content_length)
poss = wsi->http.tx_content_remain; 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, * 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, lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
context->timeout_secs); context->timeout_secs);
if (wsi->sending_chunked) { if (wsi->interpreting) {
args.p = (char *)p; args.p = (char *)p;
args.len = n; args.len = n;
args.max_len = (unsigned int)poss + 128; args.max_len = (unsigned int)poss + 128;
args.final = wsi->http.filepos + n == args.final = wsi->http.filepos + n ==
wsi->http.filelen; wsi->http.filelen;
args.chunked = wsi->sending_chunked;
if (user_callback_handle_rxflow( if (user_callback_handle_rxflow(
wsi->vhost->protocols[ wsi->vhost->protocols[
(int)wsi->protocol_interpret_idx].callback, (int)wsi->protocol_interpret_idx].callback,
@ -745,7 +747,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
} }
#endif #endif
m = lws_write(wsi, p, n, 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_FINAL :
LWS_WRITE_HTTP LWS_WRITE_HTTP
); );

View file

@ -1921,6 +1921,7 @@ struct lws {
unsigned int cache_intermediaries:1; unsigned int cache_intermediaries:1;
unsigned int favoured_pollin:1; unsigned int favoured_pollin:1;
unsigned int sending_chunked:1; unsigned int sending_chunked:1;
unsigned int interpreting:1;
unsigned int already_did_cce:1; unsigned int already_did_cce:1;
unsigned int told_user_closed:1; unsigned int told_user_closed:1;
unsigned int waiting_to_send_close_frame:1; unsigned int waiting_to_send_close_frame:1;

View file

@ -531,7 +531,9 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
n = (int)strlen(path); n = (int)strlen(path);
if (n > (int)strlen(pvo->name) && if (n > (int)strlen(pvo->name) &&
!strcmp(&path[n - strlen(pvo->name)], 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 = wsi->protocol_interpret_idx =
(char)(lws_intptr_t)pvo->value; (char)(lws_intptr_t)pvo->value;
lwsl_info("want %s interpreted by %s\n", path, lwsl_info("want %s interpreted by %s\n", path,
@ -1125,6 +1127,7 @@ lws_http_action(struct lws *wsi)
args.len = uri_len; args.len = uri_len;
args.max_len = hit->auth_mask; args.max_len = hit->auth_mask;
args.final = 0; /* used to signal callback dealt with it */ args.final = 0; /* used to signal callback dealt with it */
args.chunked = 0;
n = wsi->protocol->callback(wsi, n = wsi->protocol->callback(wsi,
LWS_CALLBACK_CHECK_ACCESS_RIGHTS, 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; return -1;
#endif #endif
if (!wsi->sending_chunked) { if (!wsi->http2_substream) {
if (lws_add_http_header_content_length(wsi, if (!wsi->sending_chunked) {
total_content_length, if (lws_add_http_header_content_length(wsi,
&p, end)) total_content_length,
return -1; &p, end))
} else { return -1;
if (lws_add_http_header_by_token(wsi, } else {
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_TRANSFER_ENCODING, WSI_TOKEN_HTTP_TRANSFER_ENCODING,
(unsigned char *)"chunked", (unsigned char *)"chunked",
7, &p, end)) 7, &p, end))
return -1; return -1;
}
} }
if (wsi->cache_secs && wsi->cache_reuse) { if (wsi->cache_secs && wsi->cache_reuse) {
@ -3075,31 +3080,33 @@ skip:
sp++; sp++;
} }
/* no space left for final chunk trailer */ if (args->chunked) {
if (args->final && args->len + 7 >= args->max_len) /* no space left for final chunk trailer */
return -1; 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; args->p -= n;
memcpy(args->p, buffer, n); memcpy(args->p, buffer, n);
args->len += n; args->len += n;
if (args->final) { if (args->final) {
sp = args->p + args->len; sp = args->p + args->len;
*sp++ = '\x0d'; *sp++ = '\x0d';
*sp++ = '\x0a'; *sp++ = '\x0a';
*sp++ = '0'; *sp++ = '0';
*sp++ = '\x0d'; *sp++ = '\x0d';
*sp++ = '\x0a'; *sp++ = '\x0a';
*sp++ = '\x0d'; *sp++ = '\x0d';
*sp++ = '\x0a'; *sp++ = '\x0a';
args->len += 7; args->len += 7;
} else { } else {
sp = args->p + args->len; sp = args->p + args->len;
*sp++ = '\x0d'; *sp++ = '\x0d';
*sp++ = '\x0a'; *sp++ = '\x0a';
args->len += 2; args->len += 2;
}
} }
return 0; return 0;