diff --git a/lib/core/connect.c b/lib/core/connect.c index 1bcb50f01..c5aa1b1de 100644 --- a/lib/core/connect.c +++ b/lib/core/connect.c @@ -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); } /* diff --git a/lib/core/libwebsockets.c b/lib/core/libwebsockets.c index bc076dead..1ffd15629 100644 --- a/lib/core/libwebsockets.c +++ b/lib/core/libwebsockets.c @@ -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; } diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index ddf92f993..2bbf12477 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -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 ----- */ diff --git a/lib/roles/cgi/ops-cgi.c b/lib/roles/cgi/ops-cgi.c index e60487b16..b85a0895b 100644 --- a/lib/roles/cgi/ops-cgi.c +++ b/lib/roles/cgi/ops-cgi.c @@ -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, }; diff --git a/lib/roles/h1/ops-h1.c b/lib/roles/h1/ops-h1.c index a4061b690..d71a6059b 100644 --- a/lib/roles/h1/ops-h1.c +++ b/lib/roles/h1/ops-h1.c @@ -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, }; diff --git a/lib/roles/h2/ops-h2.c b/lib/roles/h2/ops-h2.c index e4eebbb6a..ff201970e 100644 --- a/lib/roles/h2/ops-h2.c +++ b/lib/roles/h2/ops-h2.c @@ -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, }; diff --git a/lib/roles/listen/ops-listen.c b/lib/roles/listen/ops-listen.c index 4387cd2d9..bd39640e2 100644 --- a/lib/roles/listen/ops-listen.c +++ b/lib/roles/listen/ops-listen.c @@ -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, }; diff --git a/lib/roles/pipe/ops-pipe.c b/lib/roles/pipe/ops-pipe.c index 96b06e7fd..27b3739ff 100644 --- a/lib/roles/pipe/ops-pipe.c +++ b/lib/roles/pipe/ops-pipe.c @@ -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, }; diff --git a/lib/roles/private.h b/lib/roles/private.h index 7729b0b39..26f717786 100644 --- a/lib/roles/private.h +++ b/lib/roles/private.h @@ -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 */ }; diff --git a/lib/roles/raw-file/ops-raw-file.c b/lib/roles/raw-file/ops-raw-file.c index bbe80341f..075a2ee8b 100644 --- a/lib/roles/raw-file/ops-raw-file.c +++ b/lib/roles/raw-file/ops-raw-file.c @@ -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, }; diff --git a/lib/roles/raw-skt/ops-raw-skt.c b/lib/roles/raw-skt/ops-raw-skt.c index b22f5e56c..da9798164 100644 --- a/lib/roles/raw-skt/ops-raw-skt.c +++ b/lib/roles/raw-skt/ops-raw-skt.c @@ -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, }; diff --git a/lib/roles/ws/ops-ws.c b/lib/roles/ws/ops-ws.c index 8a25f5315..219546ae5 100644 --- a/lib/roles/ws/ops-ws.c +++ b/lib/roles/ws/ops-ws.c @@ -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 };