Skip to content

Commit 7b466ad

Browse files
committed
[fix] [#260] NB Prevent unnecessary participation of Ajax channels in conns_ during handshake
Before this commit: Server channels (schs) for Ajax GET requests destined for handshaking are unnecessarily added to `conns_` before being closed to issue handshake. Sente presumed that once used, such schs would be permanently closed and all future send attempts against the sch would just fail. But as it turns out, @osbert identified [1][2] that at least http-kit may re-use (and re-open) schs for unrelated future requests. This could lead to cases like the following: - Handshake `req1` comes in, `sch1` gets added to `conns_` then closed. - `sch1` gets re-used (and re-opened) by http-kit for unrelated `req2`. - Before `req2` can respond, a broadcast call is made against `sch1`, which is still in `conns_`. The effect: random broadcast data incorrectly being sent to an unrelated request. After this commit: Server channels (schs) for Ajax GET requests destined for handshaking are never added to `conns_`, preventing the possibility of handshake schs from being held for broadcast after closing. Instead, `conns_` contains only schs intended for long-polling (broadcast), and atomically removed from `conns_` on first use+close. This should prevent the issue described above. Separately, a change [2] is also being introduced upstream to http-kit for server-side prevention of this kind of unintentional re-use of channels. [1] #260 [2] http-kit/http-kit#375
1 parent 221f112 commit 7b466ad

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

src/taoensso/sente.cljc

+16-13
Original file line numberDiff line numberDiff line change
@@ -825,29 +825,32 @@
825825
(recur udt-t1))))))
826826

827827
;; Ajax handshake/poll
828-
(let [updated-conn (upd-conn! :ajax uid client-id :any server-ch)
829-
udt-open (:udt updated-conn)
830-
send-handshake? (or (:init? updated-conn) (:handshake? params))]
828+
(let [send-handshake?
829+
(or
830+
(:handshake? params)
831+
(nil? (get-in @conns_ [:ajax uid client-id])))]
831832

832833
(timbre/logf (if send-handshake? :info :trace)
833834
"[ajax/on-open] New server Ajax sch (poll/handshake) for %s: %s"
834835
(lid uid client-id)
835836
{:send-handshake? send-handshake?})
836837

837-
(when (connect-uid! :ajax uid)
838-
(receive-event-msg! [:chsk/uidport-open uid]))
839-
840838
(if send-handshake?
841839
;; Client will immediately repoll
842840
(send-handshake! server-ch websocket?)
843841

844-
(when-let [ms lp-timeout-ms]
845-
(go
846-
(<! (async/timeout ms))
847-
(when-let [[sch udt-t1] (get-in @conns_ [:ajax uid client-id])]
848-
(when (and (= identical? server-ch) (= udt-t1 udt-open))
849-
(interfaces/sch-send! server-ch websocket?
850-
(pack packer :chsk/timeout))))))))))
842+
(let [updated-conn (upd-conn! :ajax uid client-id :any server-ch)
843+
udt-open (:udt updated-conn)]
844+
(when-let [ms lp-timeout-ms]
845+
(go
846+
(<! (async/timeout ms))
847+
(when-let [[sch udt-t1] (get-in @conns_ [:ajax uid client-id])]
848+
(when (and (= identical? server-ch) (= udt-t1 udt-open))
849+
(interfaces/sch-send! server-ch websocket?
850+
(pack packer :chsk/timeout))))))))
851+
852+
(when (connect-uid! :ajax uid)
853+
(receive-event-msg! [:chsk/uidport-open uid])))))
851854

852855
:on-msg
853856
(fn [server-ch websocket? req-ppstr]

0 commit comments

Comments
 (0)