mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
client: bind and drop protocol like server
HTTP server protocols have had for a while LWS_CALLBACK_HTTP_DROP/BIND_PROTOCOL callbacks that mark when a wsi is attched to a protocol and detached. It turns out this is generally useful for everything to know when a wsi is joining a protocol and definitively completely finished with a protocol. Particularly with client wsi where you provided the userdata externally, this makes a clear point to free() it on the protocol binding being dropped. This patch adds protocol bind / unbind callbacks to the role definition and lets them operate on all roles. For the various roles HTTP server: LWS_CALLBACK_HTTP_BIND/DROP_PROTOCOL as before HTTP client: LWS_CALLBACK_CLIENT_HTTP_BIND/DROP_PROTOCOL ws server: LWS_CALLBACK_WS_SERVER_BIND/DROP_PROTOCOL ws client: LWS_CALLBACK_WS_CLIENT_BIND/DROP_PROTOCOL raw file: LWS_CALLBACK_RAW_FILE_BIND/DROP_PROTOCOL raw skt: LWS_CALLBACK_RAW_SKT_BIND/DROP_PROTOCOL
This commit is contained in:
parent
d461f46a97
commit
5c0b0450f2
12 changed files with 98 additions and 34 deletions
|
@ -133,11 +133,21 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
wsi->protocol = &wsi->vhost->protocols[0];
|
||||
wsi->client_pipeline = !!(i->ssl_connection & LCCSCF_PIPELINE);
|
||||
|
||||
/*
|
||||
* PHASE 5: handle external user_space now, generic alloc is done in
|
||||
* role finalization
|
||||
*/
|
||||
|
||||
if (wsi && !wsi->user_space && i->userdata) {
|
||||
wsi->user_space_externally_allocated = 1;
|
||||
wsi->user_space = i->userdata;
|
||||
}
|
||||
|
||||
if (local) {
|
||||
lwsl_info("%s: protocol binding to %s\n", __func__, local);
|
||||
p = lws_vhost_name_to_protocol(wsi->vhost, local);
|
||||
if (p)
|
||||
wsi->protocol = p;
|
||||
lws_bind_protocol(wsi, p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -544,7 +544,8 @@ lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
|
|||
const struct lws_protocols *vp = wsi->vhost->protocols, *vpo;
|
||||
|
||||
if (wsi->protocol && wsi->protocol_bind_balance) {
|
||||
wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,
|
||||
wsi->protocol->callback(wsi,
|
||||
wsi->role_ops->protocol_unbind_cb[!!lwsi_role_server(wsi)],
|
||||
wsi->user_space, NULL, 0);
|
||||
wsi->protocol_bind_balance = 0;
|
||||
}
|
||||
|
@ -581,7 +582,8 @@ lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
|
|||
__func__, p, wsi->vhost->name);
|
||||
}
|
||||
|
||||
if (wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL,
|
||||
if (wsi->protocol->callback(wsi, wsi->role_ops->protocol_bind_cb[
|
||||
!!lwsi_role_server(wsi)],
|
||||
wsi->user_space, NULL, 0))
|
||||
return 1;
|
||||
|
||||
|
@ -742,15 +744,13 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *
|
|||
lwsi_state(wsi) == LRS_H1C_ISSUE_HANDSHAKE)
|
||||
goto just_kill_connection;
|
||||
|
||||
if (!wsi->told_user_closed && lwsi_role_http(wsi) &&
|
||||
lwsi_role_server(wsi)) {
|
||||
if (wsi->user_space && wsi->protocol &&
|
||||
wsi->protocol_bind_balance) {
|
||||
wsi->protocol->callback(wsi,
|
||||
LWS_CALLBACK_HTTP_DROP_PROTOCOL,
|
||||
wsi->user_space, NULL, 0);
|
||||
wsi->protocol_bind_balance = 0;
|
||||
}
|
||||
if (!wsi->told_user_closed && wsi->user_space && wsi->protocol &&
|
||||
wsi->protocol_bind_balance) {
|
||||
wsi->protocol->callback(wsi,
|
||||
wsi->role_ops->protocol_unbind_cb[
|
||||
!!lwsi_role_server(wsi)],
|
||||
wsi->user_space, NULL, 0);
|
||||
wsi->protocol_bind_balance = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -781,8 +781,10 @@ just_kill_connection:
|
|||
wsi->protocol_bind_balance) {
|
||||
lwsl_debug("%s: %p: DROP_PROTOCOL %s\n", __func__, wsi,
|
||||
wsi->protocol->name);
|
||||
wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,
|
||||
wsi->user_space, NULL, 0);
|
||||
wsi->protocol->callback(wsi,
|
||||
wsi->role_ops->protocol_unbind_cb[
|
||||
!!lwsi_role_server(wsi)],
|
||||
wsi->user_space, NULL, 0);
|
||||
wsi->protocol_bind_balance = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -940,23 +940,6 @@ enum lws_callback_reasons {
|
|||
LWS_CALLBACK_WSI_DESTROY = 30,
|
||||
/**< outermost (latest) wsi destroy notification to protocols[0] */
|
||||
|
||||
LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49,
|
||||
/**< By default, all HTTP handling is done in protocols[0].
|
||||
* However you can bind different protocols (by name) to
|
||||
* different parts of the URL space using callback mounts. This
|
||||
* callback occurs in the new protocol when a wsi is bound
|
||||
* to that protocol. Any protocol allocation related to the
|
||||
* http transaction processing should be created then.
|
||||
* These specific callbacks are necessary because with HTTP/1.1,
|
||||
* a single connection may perform at series of different
|
||||
* transactions at different URLs, thus the lifetime of the
|
||||
* protocol bind is just for one transaction, not connection. */
|
||||
|
||||
LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50,
|
||||
/**< This is called when a transaction is unbound from a protocol.
|
||||
* It indicates the connection completed its transaction and may
|
||||
* do something different now. Any protocol allocation related
|
||||
* to the http transaction processing should be destroyed. */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to Server TLS -----
|
||||
|
@ -1145,6 +1128,24 @@ enum lws_callback_reasons {
|
|||
* bytes per buffer).
|
||||
*/
|
||||
|
||||
LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49,
|
||||
/**< By default, all HTTP handling is done in protocols[0].
|
||||
* However you can bind different protocols (by name) to
|
||||
* different parts of the URL space using callback mounts. This
|
||||
* callback occurs in the new protocol when a wsi is bound
|
||||
* to that protocol. Any protocol allocation related to the
|
||||
* http transaction processing should be created then.
|
||||
* These specific callbacks are necessary because with HTTP/1.1,
|
||||
* a single connection may perform at series of different
|
||||
* transactions at different URLs, thus the lifetime of the
|
||||
* protocol bind is just for one transaction, not connection. */
|
||||
|
||||
LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50,
|
||||
/**< This is called when a transaction is unbound from a protocol.
|
||||
* It indicates the connection completed its transaction and may
|
||||
* do something different now. Any protocol allocation related
|
||||
* to the http transaction processing should be destroyed. */
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to HTTP Client -----
|
||||
*/
|
||||
|
@ -1192,6 +1193,9 @@ enum lws_callback_reasons {
|
|||
* lws know by calling lws_client_http_body_pending(wsi, 0)
|
||||
*/
|
||||
|
||||
LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL = 75,
|
||||
LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL = 76,
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to Websocket Server -----
|
||||
*/
|
||||
|
@ -1252,6 +1256,9 @@ enum lws_callback_reasons {
|
|||
* happened yet so if you initialize user content there, user
|
||||
* content during this callback might not be useful for anything. */
|
||||
|
||||
LWS_CALLBACK_WS_SERVER_BIND_PROTOCOL = 77,
|
||||
LWS_CALLBACK_WS_SERVER_DROP_PROTOCOL = 78,
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to Websocket Client -----
|
||||
*/
|
||||
|
@ -1392,6 +1399,9 @@ enum lws_callback_reasons {
|
|||
* network connection from the client, there's no websocket protocol
|
||||
* selected yet so this callback is issued only to protocol 0. */
|
||||
|
||||
LWS_CALLBACK_WS_CLIENT_BIND_PROTOCOL = 79,
|
||||
LWS_CALLBACK_WS_CLIENT_DROP_PROTOCOL = 80,
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to external poll loop integration -----
|
||||
*/
|
||||
|
@ -1519,6 +1529,9 @@ enum lws_callback_reasons {
|
|||
LWS_CALLBACK_RAW_ADOPT = 62,
|
||||
/**< RAW mode connection was adopted (equivalent to 'wsi created') */
|
||||
|
||||
LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL = 81,
|
||||
LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL = 82,
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to RAW file handles -----
|
||||
*/
|
||||
|
@ -1538,6 +1551,9 @@ enum lws_callback_reasons {
|
|||
LWS_CALLBACK_RAW_CLOSE_FILE = 66,
|
||||
/**< RAW mode wsi that adopted a file is closing */
|
||||
|
||||
LWS_CALLBACK_RAW_FILE_BIND_PROTOCOL = 83,
|
||||
LWS_CALLBACK_RAW_FILE_DROP_PROTOCOL = 84,
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* ----- Callbacks related to generic wsi events -----
|
||||
*/
|
||||
|
|
|
@ -116,5 +116,7 @@ struct lws_role_ops role_ops_cgi = {
|
|||
/* client_bind */ NULL,
|
||||
/* writeable cb clnt, srv */ { 0, 0 },
|
||||
/* close cb clnt, srv */ { 0, 0 },
|
||||
/* protocol_bind_cb c,s */ { 0, 0 },
|
||||
/* protocol_unbind_cb c,s */ { 0, 0 },
|
||||
/* file_handle */ 0,
|
||||
};
|
||||
|
|
|
@ -838,5 +838,9 @@ struct lws_role_ops role_ops_h1 = {
|
|||
LWS_CALLBACK_HTTP_WRITEABLE },
|
||||
/* close cb clnt, srv */ { LWS_CALLBACK_CLOSED_CLIENT_HTTP,
|
||||
LWS_CALLBACK_CLOSED_HTTP },
|
||||
/* protocol_bind cb c, srv */ { LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL,
|
||||
LWS_CALLBACK_HTTP_BIND_PROTOCOL },
|
||||
/* protocol_unbind cb c, srv */ { LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL,
|
||||
LWS_CALLBACK_HTTP_DROP_PROTOCOL },
|
||||
/* file_handle */ 0,
|
||||
};
|
||||
|
|
|
@ -1082,5 +1082,9 @@ struct lws_role_ops role_ops_h2 = {
|
|||
LWS_CALLBACK_HTTP_WRITEABLE },
|
||||
/* close cb clnt, srv */ { LWS_CALLBACK_CLOSED_CLIENT_HTTP,
|
||||
LWS_CALLBACK_CLOSED_HTTP },
|
||||
/* protocol_bind cb c, srv */ { LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL,
|
||||
LWS_CALLBACK_HTTP_BIND_PROTOCOL },
|
||||
/* protocol_unbind cb c, srv */ { LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL,
|
||||
LWS_CALLBACK_HTTP_DROP_PROTOCOL },
|
||||
/* file_handle */ 0,
|
||||
};
|
||||
|
|
|
@ -180,5 +180,7 @@ struct lws_role_ops role_ops_listen = {
|
|||
/* client_bind */ NULL,
|
||||
/* writeable cb clnt, srv */ { 0, 0 },
|
||||
/* close cb clnt, srv */ { 0, 0 },
|
||||
/* protocol_bind_cb c,s */ { 0, 0 },
|
||||
/* protocol_unbind_cb c,s */ { 0, 0 },
|
||||
/* file_handle */ 0,
|
||||
};
|
||||
|
|
|
@ -79,5 +79,7 @@ struct lws_role_ops role_ops_pipe = {
|
|||
/* client_bind */ NULL,
|
||||
/* writeable cb clnt, srv */ { 0, 0 },
|
||||
/* close cb clnt, srv */ { 0, 0 },
|
||||
/* protocol_bind_cb c,s */ { 0, 0 },
|
||||
/* protocol_unbind_cb c,s */ { 0, 0 },
|
||||
/* file_handle */ 1,
|
||||
};
|
||||
|
|
|
@ -241,6 +241,16 @@ struct lws_role_ops {
|
|||
* (just client applies if no concept of client or server)
|
||||
*/
|
||||
uint16_t close_cb[2];
|
||||
/*
|
||||
* the callback reasons for protocol bind for client, server
|
||||
* (just client applies if no concept of client or server)
|
||||
*/
|
||||
uint16_t protocol_bind_cb[2];
|
||||
/*
|
||||
* the callback reasons for protocol unbind for client, server
|
||||
* (just client applies if no concept of client or server)
|
||||
*/
|
||||
uint16_t protocol_unbind_cb[2];
|
||||
|
||||
unsigned int file_handle:1; /* role operates on files not sockets */
|
||||
};
|
||||
|
|
|
@ -100,5 +100,9 @@ struct lws_role_ops role_ops_raw_file = {
|
|||
/* client_bind */ NULL,
|
||||
/* writeable cb clnt, srv */ { LWS_CALLBACK_RAW_WRITEABLE_FILE, 0 },
|
||||
/* close cb clnt, srv */ { LWS_CALLBACK_RAW_CLOSE_FILE, 0 },
|
||||
/* protocol_bind cb c, srv */ { LWS_CALLBACK_RAW_FILE_BIND_PROTOCOL,
|
||||
LWS_CALLBACK_RAW_FILE_BIND_PROTOCOL },
|
||||
/* protocol_unbind cb c, srv */ { LWS_CALLBACK_RAW_FILE_DROP_PROTOCOL,
|
||||
LWS_CALLBACK_RAW_FILE_DROP_PROTOCOL },
|
||||
/* file_handle */ 1,
|
||||
};
|
||||
|
|
|
@ -152,6 +152,9 @@ rops_adoption_bind_raw_skt(struct lws *wsi, int type, const char *vh_prot_name)
|
|||
wsi->udp = lws_malloc(sizeof(*wsi->udp), "udp struct");
|
||||
#endif
|
||||
|
||||
lws_role_transition(wsi, 0, type & LWS_ADOPT_ALLOW_SSL ? LRS_SSL_INIT :
|
||||
LRS_ESTABLISHED, &role_ops_raw_skt);
|
||||
|
||||
if (vh_prot_name)
|
||||
lws_bind_protocol(wsi, wsi->protocol);
|
||||
else
|
||||
|
@ -159,9 +162,6 @@ rops_adoption_bind_raw_skt(struct lws *wsi, int type, const char *vh_prot_name)
|
|||
lws_bind_protocol(wsi,
|
||||
&wsi->vhost->protocols[wsi->vhost->raw_protocol_index]);
|
||||
|
||||
lws_role_transition(wsi, 0, type & LWS_ADOPT_ALLOW_SSL ? LRS_SSL_INIT :
|
||||
LRS_ESTABLISHED, &role_ops_raw_skt);
|
||||
|
||||
return 1; /* bound */
|
||||
}
|
||||
#endif
|
||||
|
@ -224,5 +224,9 @@ struct lws_role_ops role_ops_raw_skt = {
|
|||
#endif
|
||||
/* writeable cb clnt, srv */ { LWS_CALLBACK_RAW_WRITEABLE, 0 },
|
||||
/* close cb clnt, srv */ { LWS_CALLBACK_RAW_CLOSE, 0 },
|
||||
/* protocol_bind cb c, srv */ { LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL,
|
||||
LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL },
|
||||
/* protocol_unbind cb c, srv */ { LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL,
|
||||
LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL },
|
||||
/* file_handle */ 0,
|
||||
};
|
||||
|
|
|
@ -1988,5 +1988,9 @@ struct lws_role_ops role_ops_ws = {
|
|||
LWS_CALLBACK_SERVER_WRITEABLE },
|
||||
/* close cb clnt, srv */ { LWS_CALLBACK_CLIENT_CLOSED,
|
||||
LWS_CALLBACK_CLOSED },
|
||||
/* protocol_bind cb c, srv */ { LWS_CALLBACK_WS_CLIENT_BIND_PROTOCOL,
|
||||
LWS_CALLBACK_WS_SERVER_BIND_PROTOCOL },
|
||||
/* protocol_unbind cb c, srv */ { LWS_CALLBACK_WS_CLIENT_DROP_PROTOCOL,
|
||||
LWS_CALLBACK_WS_SERVER_DROP_PROTOCOL },
|
||||
/* file handles */ 0
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue