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

raw: take care about same vh protocol linked list

This commit is contained in:
Andy Green 2017-04-06 13:49:17 +08:00
parent 54c22623ab
commit 19242db55b
4 changed files with 98 additions and 50 deletions

View file

@ -174,6 +174,7 @@ lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
{
// if (wsi->protocol == p)
// return 0;
const struct lws_protocols *vp = wsi->vhost->protocols, *vpo;
if (wsi->protocol)
wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL,
@ -181,6 +182,8 @@ lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
if (!wsi->user_space_externally_allocated)
lws_free_set_NULL(wsi->user_space);
lws_same_vh_protocol_remove(wsi);
wsi->protocol = p;
if (!p)
return 0;
@ -188,6 +191,27 @@ lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
if (lws_ensure_user_space(wsi))
return 1;
if (p > vp && p < &vp[wsi->vhost->count_protocols])
lws_same_vh_protocol_insert(wsi, p - vp);
else {
int n = wsi->vhost->count_protocols;
int hit = 0;
vpo = vp;
while (n--) {
if (!strcmp(p->name, vp->name)) {
hit = 1;
lws_same_vh_protocol_insert(wsi, vp - vpo);
break;
}
vp++;
}
if (!hit)
lwsl_err("%s: protocol %p is not in vhost %s protocols list\n",
__func__, p, wsi->vhost->name);
}
if (wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL,
wsi->user_space, NULL, 0))
return 1;

View file

@ -247,31 +247,7 @@ remove_wsi_socket_from_fds(struct lws *wsi)
wsi->user_space, (void *)&pa, 1))
return -1;
/*
* detach ourselves from vh protocol list if we're on one
* A -> B -> C
* A -> C , or, B -> C, or A -> B
*/
lwsl_info("%s: removing same prot wsi %p\n", __func__, wsi);
if (wsi->same_vh_protocol_prev) {
assert (*(wsi->same_vh_protocol_prev) == wsi);
lwsl_info("have prev %p, setting him to our next %p\n",
wsi->same_vh_protocol_prev,
wsi->same_vh_protocol_next);
/* guy who pointed to us should point to our next */
*(wsi->same_vh_protocol_prev) = wsi->same_vh_protocol_next;
} //else
//lwsl_err("null wsi->prev\n");
/* our next should point back to our prev */
if (wsi->same_vh_protocol_next) {
wsi->same_vh_protocol_next->same_vh_protocol_prev =
wsi->same_vh_protocol_prev;
} //else
//lwsl_err("null wsi->next\n");
wsi->same_vh_protocol_prev = NULL;
wsi->same_vh_protocol_next = NULL;
lws_same_vh_protocol_remove(wsi);
/* the guy who is to be deleted's slot index in pt->fds */
m = wsi->position_in_fds_table;
@ -430,6 +406,74 @@ network_sock:
return 1;
}
/*
* stitch protocol choice into the vh protocol linked list
* We always insert ourselves at the start of the list
*
* X <-> B
* X <-> pAn <-> pB
*
* Illegal to attach more than once without detach inbetween
*/
void
lws_same_vh_protocol_insert(struct lws *wsi, int n)
{
//lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
// __func__,
// wsi->vhost->same_vh_protocol_list[n],
// wsi->same_vh_protocol_prev);
if (wsi->same_vh_protocol_prev || wsi->same_vh_protocol_next) {
lwsl_err("Attempted to attach wsi twice to same vh prot\n");
assert(0);
}
wsi->same_vh_protocol_prev = /* guy who points to us */
&wsi->vhost->same_vh_protocol_list[n];
wsi->same_vh_protocol_next = /* old first guy is our next */
wsi->vhost->same_vh_protocol_list[n];
/* we become the new first guy */
wsi->vhost->same_vh_protocol_list[n] = wsi;
if (wsi->same_vh_protocol_next)
/* old first guy points back to us now */
wsi->same_vh_protocol_next->same_vh_protocol_prev =
&wsi->same_vh_protocol_next;
}
void
lws_same_vh_protocol_remove(struct lws *wsi)
{
/*
* detach ourselves from vh protocol list if we're on one
* A -> B -> C
* A -> C , or, B -> C, or A -> B
*
* OK to call on already-detached wsi
*/
lwsl_info("%s: removing same prot wsi %p\n", __func__, wsi);
if (wsi->same_vh_protocol_prev) {
assert (*(wsi->same_vh_protocol_prev) == wsi);
lwsl_info("have prev %p, setting him to our next %p\n",
wsi->same_vh_protocol_prev,
wsi->same_vh_protocol_next);
/* guy who pointed to us should point to our next */
*(wsi->same_vh_protocol_prev) = wsi->same_vh_protocol_next;
}
/* our next should point back to our prev */
if (wsi->same_vh_protocol_next) {
wsi->same_vh_protocol_next->same_vh_protocol_prev =
wsi->same_vh_protocol_prev;
}
wsi->same_vh_protocol_prev = NULL;
wsi->same_vh_protocol_next = NULL;
}
LWS_VISIBLE int
lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
const struct lws_protocols *protocol)

View file

@ -2067,6 +2067,10 @@ LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len);
LWS_EXTERN int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,
lws_filepos_t *amount);
LWS_EXTERN void
lws_same_vh_protocol_remove(struct lws *wsi);
LWS_EXTERN void
lws_same_vh_protocol_insert(struct lws *wsi, int n);
#ifdef __cplusplus
};

View file

@ -1161,7 +1161,6 @@ transaction_result_n:
#endif
}
int
lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
{
@ -1498,30 +1497,7 @@ upgrade_ws:
goto bail_nuke_ah;
}
/*
* stitch protocol choice into the vh protocol linked list
* We always insert ourselves at the start of the list
*
* X <-> B
* X <-> pAn <-> pB
*/
//lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
// __func__,
// wsi->vhost->same_vh_protocol_list[n],
// wsi->same_vh_protocol_prev);
wsi->same_vh_protocol_prev = /* guy who points to us */
&wsi->vhost->same_vh_protocol_list[n];
wsi->same_vh_protocol_next = /* old first guy is our next */
wsi->vhost->same_vh_protocol_list[n];
/* we become the new first guy */
wsi->vhost->same_vh_protocol_list[n] = wsi;
if (wsi->same_vh_protocol_next)
/* old first guy points back to us now */
wsi->same_vh_protocol_next->same_vh_protocol_prev =
&wsi->same_vh_protocol_next;
lws_same_vh_protocol_insert(wsi, n);
/* we are upgrading to ws, so http/1.1 and keepalive +
* pipelined header considerations about keeping the ah around