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

http: add callback to allow upgrade reject

https://github.com/warmcat/libwebsockets/issues/1415
This commit is contained in:
Andy Green 2018-10-31 13:38:37 +08:00
parent 984b7d3b53
commit 27ae132e7b
3 changed files with 53 additions and 13 deletions

View file

@ -311,6 +311,20 @@ enum lws_callback_reasons {
* do something different now. Any protocol allocation related
* to the http transaction processing should be destroyed. */
LWS_CALLBACK_HTTP_CONFIRM_UPGRADE = 86,
/**< This is your chance to reject an HTTP upgrade action. The
* name of the protocol being upgraded to is in 'in', and the ah
* is still bound to the wsi, so you can look at the headers.
*
* The default of returning 0 (ie, also if not handled) means the
* upgrade may proceed. Return <0 to just hang up the connection,
* or >0 if you have rejected the connection by returning http headers
* and response code yourself.
*
* There is no need for you to call transaction_completed() as the
* caller will take care of it when it sees you returned >0.
*/
/* ---------------------------------------------------------------------
* ----- Callbacks related to HTTP Client -----
*/

View file

@ -916,8 +916,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
wsi->http.rx_content_length;
} else /* can't do 1.1 without a content length or chunked */
if (!wsi->chunked)
wsi->http.conn_type =
HTTP_CONNECTION_CLOSE;
wsi->http.conn_type = HTTP_CONNECTION_CLOSE;
/*
* we seem to be good to go, give client last chance to check

View file

@ -1699,12 +1699,44 @@ raw_transition:
lwsi_set_state(wsi, LRS_PRE_WS_SERVING_ACCEPT);
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
/* is this websocket protocol or normal http 1.0? */
if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
if (!strcasecmp(lws_hdr_simple_ptr(wsi,
WSI_TOKEN_UPGRADE),
"websocket")) {
const char *up = lws_hdr_simple_ptr(wsi,
WSI_TOKEN_UPGRADE);
if (strcasecmp(up, "websocket") &&
strcasecmp(up, "h2c")) {
lwsl_info("Unknown upgrade '%s'\n", up);
if (lws_return_http_status(wsi,
HTTP_STATUS_FORBIDDEN, NULL) ||
lws_http_transaction_completed(wsi))
goto bail_nuke_ah;
}
n = user_callback_handle_rxflow(wsi->protocol->callback,
wsi, LWS_CALLBACK_HTTP_CONFIRM_UPGRADE,
wsi->user_space, (char *)up, 0);
/* just hang up? */
if (n < 0)
goto bail_nuke_ah;
/* callback returned headers already, do t_c? */
if (n > 0) {
if (lws_http_transaction_completed(wsi))
goto bail_nuke_ah;
/* continue on */
return 0;
}
/* callback said 0, it was allowed */
if (!strcasecmp(up, "websocket")) {
#if defined(LWS_ROLE_WS)
wsi->vhost->conn_stats.ws_upg++;
lwsl_info("Upgrade to ws\n");
@ -1712,17 +1744,12 @@ raw_transition:
#endif
}
#if defined(LWS_WITH_HTTP2)
if (!strcasecmp(lws_hdr_simple_ptr(wsi,
WSI_TOKEN_UPGRADE),
"h2c")) {
if (!strcasecmp(up, "h2c")) {
wsi->vhost->conn_stats.h2_upg++;
lwsl_info("Upgrade to h2c\n");
goto upgrade_h2c;
}
#endif
lwsl_info("Unknown upgrade\n");
/* dunno what he wanted to upgrade to */
goto bail_nuke_ah;
}
/* no upgrade ack... he remained as HTTP */