Skip to content

Commit

Permalink
obs-browser: flush panel cookie store on exit
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zavitax committed Mar 6, 2019
1 parent d5b6812 commit 4c54fae
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
68 changes: 68 additions & 0 deletions obs-browser-plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,72 @@ bool QueueCEFTask(std::function<void()> task)

/* ========================================================================= */

static std::mutex cookie_managers_mutex;
static std::vector<CefRefPtr<CefCookieManager>> cookie_managers;

void register_cookie_manager(CefRefPtr<CefCookieManager> cm)
{
std::lock_guard<std::mutex> guard(cookie_managers_mutex);

cookie_managers.emplace_back(cm);
}

static void flush_cookie_manager(CefRefPtr<CefCookieManager> cm)
{
os_event_t* complete_event;

os_event_init(&complete_event, OS_EVENT_TYPE_AUTO);

class CompletionCallback : public CefCompletionCallback
{
public:
CompletionCallback(os_event_t* complete_event) : m_complete_event(complete_event)
{
}

virtual void OnComplete() override
{
os_event_signal(m_complete_event);
}

IMPLEMENT_REFCOUNTING(CompletionCallback);

private:
os_event_t* m_complete_event;
};

CefRefPtr<CefCompletionCallback> callback =
new CompletionCallback(complete_event);

auto task = [&]() {
if (!cm->FlushStore(callback)) {
blog(LOG_WARNING,
"Failed flushing cookie store");

os_event_signal(complete_event);
}
else {
blog(LOG_INFO, "Flushed cookie store");
}
};

CefPostTask(TID_IO, CefRefPtr<BrowserTask>(new BrowserTask(task)));

os_event_wait(complete_event);
os_event_destroy(complete_event);
}

static void flush_cookie_managers()
{
std::lock_guard<std::mutex> guard(cookie_managers_mutex);

for (auto cm : cookie_managers) {
flush_cookie_manager(cm);
}
}

/* ========================================================================= */

static const char *default_css = "\
body { \
background-color: rgba(0, 0, 0, 0); \
Expand Down Expand Up @@ -500,6 +566,8 @@ bool obs_module_load(void)

void obs_module_unload(void)
{
flush_cookie_managers();

if (manager_thread.joinable()) {
while (!QueueCEFTask([] () {CefQuitMessageLoop();}))
os_sleep_ms(5);
Expand Down
4 changes: 4 additions & 0 deletions panel/browser-panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ extern bool QueueCEFTask(std::function<void()> task);
extern "C" void obs_browser_initialize(void);
extern os_event_t *cef_started_event;

void register_cookie_manager(CefRefPtr<CefCookieManager> cm);

std::mutex popup_whitelist_mutex;
std::vector<PopupWhitelistInfo> popup_whitelist;
std::vector<PopupWhitelistInfo> forced_popups;
Expand Down Expand Up @@ -83,6 +85,8 @@ struct QCefCookieManagerInternal : QCefCookieManager {
if (!cm)
throw "Failed to create cookie manager";

register_cookie_manager(cm);

rch = new QCefRequestContextHandler(cm);

rc = CefRequestContext::CreateContext(
Expand Down

0 comments on commit 4c54fae

Please sign in to comment.