Skip to content

Commit 4c54fae

Browse files
committed
obs-browser: flush panel cookie store on exit
If cookie store is not flushed, state might become inconsistent: reading from the cookies file will become impossible. No errors will be returned, yet no information will be available, and no information will be stored: the cookie manager will appear to be empty at all times and the `Cookies` file modified date will not update moving forward. This will result, for example, in Twitch chat window re-opening for users which connected their Twitch account, but not having the `auth-token` cookie available: once the user will try to send a message to the chat, they will be redirected to Twitch login screen.
1 parent d5b6812 commit 4c54fae

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

obs-browser-plugin.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,72 @@ bool QueueCEFTask(std::function<void()> task)
7777

7878
/* ========================================================================= */
7979

80+
static std::mutex cookie_managers_mutex;
81+
static std::vector<CefRefPtr<CefCookieManager>> cookie_managers;
82+
83+
void register_cookie_manager(CefRefPtr<CefCookieManager> cm)
84+
{
85+
std::lock_guard<std::mutex> guard(cookie_managers_mutex);
86+
87+
cookie_managers.emplace_back(cm);
88+
}
89+
90+
static void flush_cookie_manager(CefRefPtr<CefCookieManager> cm)
91+
{
92+
os_event_t* complete_event;
93+
94+
os_event_init(&complete_event, OS_EVENT_TYPE_AUTO);
95+
96+
class CompletionCallback : public CefCompletionCallback
97+
{
98+
public:
99+
CompletionCallback(os_event_t* complete_event) : m_complete_event(complete_event)
100+
{
101+
}
102+
103+
virtual void OnComplete() override
104+
{
105+
os_event_signal(m_complete_event);
106+
}
107+
108+
IMPLEMENT_REFCOUNTING(CompletionCallback);
109+
110+
private:
111+
os_event_t* m_complete_event;
112+
};
113+
114+
CefRefPtr<CefCompletionCallback> callback =
115+
new CompletionCallback(complete_event);
116+
117+
auto task = [&]() {
118+
if (!cm->FlushStore(callback)) {
119+
blog(LOG_WARNING,
120+
"Failed flushing cookie store");
121+
122+
os_event_signal(complete_event);
123+
}
124+
else {
125+
blog(LOG_INFO, "Flushed cookie store");
126+
}
127+
};
128+
129+
CefPostTask(TID_IO, CefRefPtr<BrowserTask>(new BrowserTask(task)));
130+
131+
os_event_wait(complete_event);
132+
os_event_destroy(complete_event);
133+
}
134+
135+
static void flush_cookie_managers()
136+
{
137+
std::lock_guard<std::mutex> guard(cookie_managers_mutex);
138+
139+
for (auto cm : cookie_managers) {
140+
flush_cookie_manager(cm);
141+
}
142+
}
143+
144+
/* ========================================================================= */
145+
80146
static const char *default_css = "\
81147
body { \
82148
background-color: rgba(0, 0, 0, 0); \
@@ -500,6 +566,8 @@ bool obs_module_load(void)
500566

501567
void obs_module_unload(void)
502568
{
569+
flush_cookie_managers();
570+
503571
if (manager_thread.joinable()) {
504572
while (!QueueCEFTask([] () {CefQuitMessageLoop();}))
505573
os_sleep_ms(5);

panel/browser-panel.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ extern bool QueueCEFTask(std::function<void()> task);
1313
extern "C" void obs_browser_initialize(void);
1414
extern os_event_t *cef_started_event;
1515

16+
void register_cookie_manager(CefRefPtr<CefCookieManager> cm);
17+
1618
std::mutex popup_whitelist_mutex;
1719
std::vector<PopupWhitelistInfo> popup_whitelist;
1820
std::vector<PopupWhitelistInfo> forced_popups;
@@ -83,6 +85,8 @@ struct QCefCookieManagerInternal : QCefCookieManager {
8385
if (!cm)
8486
throw "Failed to create cookie manager";
8587

88+
register_cookie_manager(cm);
89+
8690
rch = new QCefRequestContextHandler(cm);
8791

8892
rc = CefRequestContext::CreateContext(

0 commit comments

Comments
 (0)