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:
parent
984b7d3b53
commit
27ae132e7b
3 changed files with 53 additions and 13 deletions
|
@ -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 -----
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue