Implement NPAPI ClearSiteData hooks

Now that recent stable versions of Firefox, Chrome, and Flash all
implement it, we should wrap it.

Tested in Flash 10.3 with Chrome's 'Clear Browsing Data', Firefox's
'Clear Recent History', and Firefox's 'Forget About This Site'. It
appears Flash ignores maxAge and, when asked to clear all data ever,
sometimes gives NPERR_GENERIC_ERROR. But those aren't problems on our
end, and it seems to otherwise work.

See bug #6.
This commit is contained in:
David Benjamin 2011-05-13 18:35:06 -04:00
parent ff68174da4
commit 5d64df2acc
4 changed files with 195 additions and 3 deletions

View File

@ -33,7 +33,7 @@
#include <npruntime.h>
/* Supported NPAPI interfaces */
#define NPW_NPAPI_VERSION 24
#define NPW_NPAPI_VERSION 27
#define NPW_NP_CLASS_STRUCT_VERSION 3
#define NPW_TOOLKIT NPNVGtk2

View File

@ -4496,6 +4496,87 @@ static int handle_NPP_HandleEvent(rpc_connection_t *connection)
return rpc_method_send_reply(connection, RPC_TYPE_INT32, ret, RPC_TYPE_INVALID);
}
// Clears site-data stored by the plug-in
static NPError
g_NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge)
{
if (plugin_funcs.clearsitedata == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
D(bugiI("NPP_ClearSiteData site=%s, flags=%" G_GUINT64_FORMAT
", maxAge=%" G_GUINT64_FORMAT "\n",
site ? site : "<null>", flags, maxAge));
NPError ret = plugin_funcs.clearsitedata(site, flags, maxAge);
D(bugiD("NPP_ClearSiteData return: %d [%s]\n", ret, string_of_NPError(ret)));
return ret;
}
static int handle_NPP_ClearSiteData(rpc_connection_t *connection)
{
D(bug("handle_NPP_ClearSiteData\n"));
char *site = NULL;
uint64_t flags;
uint64_t maxAge;
int error = rpc_method_get_args(connection,
RPC_TYPE_STRING, &site,
RPC_TYPE_UINT64, &flags,
RPC_TYPE_UINT64, &maxAge,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_ClearSiteData() get args", error);
return error;
}
NPError ret = g_NPP_ClearSiteData(site, flags, maxAge);
if (site)
free(site);
return rpc_method_send_reply(connection, RPC_TYPE_INT32, ret, RPC_TYPE_INVALID);
}
// Get sites with data stored by the plug-in
static char **
g_NPP_GetSitesWithData(void)
{
if (plugin_funcs.getsiteswithdata == NULL)
return NULL;
D(bugiI("NPP_GetSitesWithData\n"));
char **ret = plugin_funcs.getsiteswithdata();
D(bugiD("NPP_GetSitesWithData return: %d sites\n",
ret ? g_strv_length(ret) : 0));
return ret;
}
static int handle_NPP_GetSitesWithData(rpc_connection_t *connection)
{
D(bug("handle_NPP_GetSitesWithData\n"));
int error = rpc_method_get_args(connection, RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetSitesWithData() get args", error);
return error;
}
char **sites = g_NPP_GetSitesWithData();
int ret = rpc_method_send_reply(connection,
RPC_TYPE_ARRAY, RPC_TYPE_STRING,
sites ? g_strv_length(sites) : 0, sites,
RPC_TYPE_INVALID);
if (sites) {
for (int i = 0; sites[i]; i++) {
NPN_MemFree(sites[i]);
}
NPN_MemFree(sites);
}
return ret;
}
/* ====================================================================== */
/* === Events processing === */
@ -4829,6 +4910,8 @@ static int do_main(int argc, char **argv, const char *connection_path)
{ RPC_METHOD_NPP_STREAM_AS_FILE, handle_NPP_StreamAsFile },
{ RPC_METHOD_NPP_PRINT, handle_NPP_Print },
{ RPC_METHOD_NPP_HANDLE_EVENT, handle_NPP_HandleEvent },
{ RPC_METHOD_NPP_CLEAR_SITE_DATA, handle_NPP_ClearSiteData },
{ RPC_METHOD_NPP_GET_SITES_WITH_DATA, handle_NPP_GetSitesWithData },
};
if (rpc_connection_add_method_descriptors(g_rpc_connection, vtable, sizeof(vtable) / sizeof(vtable[0])) < 0) {
npw_printf("ERROR: failed to setup NPP method callbacks\n");

View File

@ -2904,6 +2904,115 @@ static int16_t g_NPP_HandleEvent(NPP instance, void *event)
return ret;
}
// Clears site-data stored by the plug-in
static NPError
invoke_NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge)
{
if (PLUGIN_DIRECT_EXEC)
return plugin_funcs.clearsitedata(site, flags, maxAge);
npw_return_val_if_fail(rpc_method_invoke_possible(g_rpc_connection),
NPERR_GENERIC_ERROR);
int error = rpc_method_invoke(g_rpc_connection,
RPC_METHOD_NPP_CLEAR_SITE_DATA,
RPC_TYPE_STRING, site,
RPC_TYPE_UINT64, flags,
RPC_TYPE_UINT64, maxAge,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_ClearSiteData() invoke", error);
return NPERR_GENERIC_ERROR;
}
int32_t ret;
error = rpc_method_wait_for_reply(g_rpc_connection,
RPC_TYPE_INT32, &ret,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_ClearSiteData() wait for reply", error);
return NPERR_GENERIC_ERROR;
}
return ret;
}
static NPError
g_NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge)
{
D(bugiI("NPP_ClearSiteData site=%s, flags=%" G_GUINT64_FORMAT
", maxAge=%" G_GUINT64_FORMAT "\n",
site ? site : "<null>", flags, maxAge));
NPError ret = invoke_NPP_ClearSiteData(site, flags, maxAge);
D(bugiD("NPP_ClearSiteData return: %d [%s]\n", ret, string_of_NPError(ret)));
return ret;
}
// Get sites with data stored by the plug-in
static char **
invoke_NPP_GetSitesWithData(void)
{
if (PLUGIN_DIRECT_EXEC)
return plugin_funcs.getsiteswithdata();
npw_return_val_if_fail(rpc_method_invoke_possible(g_rpc_connection), NULL);
int error = rpc_method_invoke(g_rpc_connection,
RPC_METHOD_NPP_GET_SITES_WITH_DATA,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetSitesWithData() invoke", error);
return NULL;
}
char **sites = NULL;
uint32_t siteCount = 0;
error = rpc_method_wait_for_reply(g_rpc_connection,
RPC_TYPE_ARRAY, RPC_TYPE_STRING,
&siteCount, &sites,
RPC_TYPE_INVALID);
if (error != RPC_ERROR_NO_ERROR) {
npw_perror("NPP_GetSitesWithData() wait for reply", error);
return NULL;
}
// Convert this to the format NPAPI wants... ugh.
char **sites_ret = NULL;
if (siteCount > 0) {
sites_ret = NPN_MemAlloc(sizeof(char*) * (siteCount+1));
if (sites_ret) {
for (int i = 0; i < siteCount; i++) {
// Ignore allocation failures here.
NPW_ReallocData(sites[i], strlen(sites[i]), (void**)&sites_ret[i]);
}
sites_ret[siteCount] = NULL;
}
}
// Delete the other copy.
if (sites) {
for (int i = 0; i < siteCount; i++) {
free(sites[i]);
}
free(sites);
}
return sites_ret;
}
static char **
g_NPP_GetSitesWithData(void)
{
D(bugiI("NPP_GetSitesWithData\n"));
char **ret = invoke_NPP_GetSitesWithData();
D(bugiD("NPP_GetSitesWithData return: %d sites\n",
ret ? g_strv_length(ret) : 0));
return ret;
}
// Allows the browser to query the plug-in for information
static NPError
g_NP_GetValue(void *future, NPPVariable variable, void *value)

View File

@ -34,5 +34,5 @@ PLUGIN_FUNC(NPP_SetValue, setvalue)
// PLUGIN_FUNC(NPP_GotFocus, gotfocus)
// PLUGIN_FUNC(NPP_LostFocus, lostfocus)
// PLUGIN_FUNC(NPP_URLRedirectNotify, urlredirectnotify)
// PLUGIN_FUNC(NPP_ClearSiteData, clearsitedata)
// PLUGIN_FUNC(NPP_GetSitesWithData, getsiteswithdata)
PLUGIN_FUNC(NPP_ClearSiteData, clearsitedata)
PLUGIN_FUNC(NPP_GetSitesWithData, getsiteswithdata)