mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-18 14:34:21 +01:00
Have EventManagers yield before timer code to force SSE response head… (#1400)
* EventManagers should send an initial ping event to force `text/event-steam` header to be set
This commit is contained in:
@@ -52,6 +52,10 @@ class EventManager(object):
|
||||
self.clients.append(q)
|
||||
while True:
|
||||
try:
|
||||
# Immediately yield a ping event to force Response headers to be set
|
||||
# or else some reverse proxies will incorrectly buffer SSE
|
||||
yield ServerSentEvent(data="", type="ping")
|
||||
|
||||
with Timeout(10):
|
||||
message = q[channel].get()
|
||||
yield ServerSentEvent(**message)
|
||||
@@ -76,6 +80,10 @@ class RedisEventManager(EventManager):
|
||||
pubsub = self.client.pubsub()
|
||||
pubsub.subscribe(channel)
|
||||
try:
|
||||
# Immediately yield a ping event to force Response headers to be set
|
||||
# or else some reverse proxies will incorrectly buffer SSE
|
||||
yield ServerSentEvent(data="", type="ping")
|
||||
|
||||
with Timeout(10) as timeout:
|
||||
for message in pubsub.listen():
|
||||
if message["type"] == "message":
|
||||
|
||||
@@ -35,11 +35,18 @@ def test_event_manager_subscription():
|
||||
|
||||
fake_queue.return_value = saved_event
|
||||
event_manager = EventManager()
|
||||
for message in event_manager.subscribe():
|
||||
events = event_manager.subscribe()
|
||||
message = next(events)
|
||||
assert isinstance(message, ServerSentEvent)
|
||||
assert message.to_dict() == {"data": "", "type": "ping"}
|
||||
assert message.__str__().startswith("event:ping")
|
||||
assert len(event_manager.clients) == 1
|
||||
|
||||
message = next(events)
|
||||
assert isinstance(message, ServerSentEvent)
|
||||
assert message.to_dict() == saved_event
|
||||
assert message.__str__().startswith("event:notification\ndata:")
|
||||
assert len(event_manager.clients) == 1
|
||||
break
|
||||
|
||||
|
||||
def test_event_manager_publish():
|
||||
@@ -144,11 +151,17 @@ def test_redis_event_manager_subscription():
|
||||
with patch.object(redis.client.PubSub, "listen") as fake_pubsub_listen:
|
||||
fake_pubsub_listen.return_value = [saved_event]
|
||||
event_manager = RedisEventManager()
|
||||
for message in event_manager.subscribe():
|
||||
|
||||
events = event_manager.subscribe()
|
||||
message = next(events)
|
||||
assert isinstance(message, ServerSentEvent)
|
||||
assert message.to_dict() == {"data": "", "type": "ping"}
|
||||
assert message.__str__().startswith("event:ping")
|
||||
|
||||
message = next(events)
|
||||
assert isinstance(message, ServerSentEvent)
|
||||
assert message.to_dict() == saved_data
|
||||
assert message.__str__().startswith("event:notification\ndata:")
|
||||
break
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user