int32_t
ppb_url_loader_read_response_body(PP_Resource loader, void *buffer, int32_t bytes_to_read,
                                  struct PP_CompletionCallback callback)
{
    struct url_loader_read_task_s *rt;
    int32_t read_bytes = PP_ERROR_FAILED;
    struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER);
    if (!ul) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    if (ul->fd == -1) {
        trace_error("%s, fd==-1\n", __func__);
        pp_resource_release(loader);
        return PP_ERROR_FAILED;
    }

    if (ul->read_tasks) {
        // schedule task instead of immediate reading if there is another task
        // in the queue already
        goto schedule_read_task;
    }

    read_bytes = -1;
    off_t ofs = lseek(ul->fd, ul->read_pos, SEEK_SET);
    if (ofs != (off_t)-1)
        read_bytes = RETRY_ON_EINTR(read(ul->fd, buffer, bytes_to_read));

    if (read_bytes < 0)
        read_bytes = PP_ERROR_FAILED;
    else
        ul->read_pos += read_bytes;

    if (read_bytes == 0 && !ul->finished_loading) {
        // no data ready, schedule read task
        goto schedule_read_task;
    }

    pp_resource_release(loader);
    if (callback.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL)
        return read_bytes;

    ppb_message_loop_post_work_with_result(ppb_message_loop_get_current(), callback, 0, read_bytes,
                                           0, __func__);
    return PP_OK_COMPLETIONPENDING;

schedule_read_task:
    rt = g_slice_alloc(sizeof(*rt));
    rt->url_loader =    loader;
    rt->buffer =        buffer;
    rt->bytes_to_read = bytes_to_read;
    rt->ccb =           callback;
    rt->ccb_ml =        ppb_message_loop_get_current();

    ul->read_tasks = g_list_append(ul->read_tasks, rt);
    pp_resource_release(loader);
    return PP_OK_COMPLETIONPENDING;
}
PP_Resource
ppb_flash_menu_create(PP_Instance instance_id, const struct PP_Flash_Menu *menu_data)
{
    struct pp_instance_s *pp_i = tables_get_pp_instance(instance_id);
    if (!pp_i) {
        trace_error("%s, bad instance\n", __func__);
        return 0;
    }

    PP_Resource flash_menu = pp_resource_allocate(PP_RESOURCE_FLASH_MENU, pp_i);
    if (pp_resource_get_type(flash_menu) != PP_RESOURCE_FLASH_MENU) {
        trace_error("%s, resource allocation failure\n", __func__);
        return 0;
    }

    struct flash_menu_create_param_s *p = g_slice_alloc0(sizeof(*p));

    p->flash_menu = flash_menu;
    p->menu_data =  menu_data;
    p->m_loop =     ppb_message_loop_get_current();
    p->depth =      ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(flash_menu_create_comt, p), 0,
                                           PP_OK, p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    g_slice_free1(sizeof(*p), p);
    return flash_menu;
}
int32_t
ppb_host_resolver_resolve(PP_Resource host_resolver, const char *host, uint16_t port,
                          const struct PP_HostResolver_Private_Hint *hint,
                          struct PP_CompletionCallback callback)
{
    struct pp_host_resolver_s *hr = pp_resource_acquire(host_resolver, PP_RESOURCE_HOST_RESOLVER);
    if (!hr) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    hr->host = nullsafe_strdup(host);

    struct async_network_task_s *task = async_network_task_create();

    task->type =        ASYNC_NETWORK_HOST_RESOLVE;
    task->resource =    host_resolver;
    task->host =        nullsafe_strdup(host);
    task->port =        port;
    task->callback =    callback;
    task->callback_ml = ppb_message_loop_get_current();

    pp_resource_release(host_resolver);
    async_network_task_push(task);

    return PP_OK_COMPLETIONPENDING;
}
static
struct PP_Var
n2p_call(void *object, struct PP_Var method_name, uint32_t argc, struct PP_Var *argv,
         struct PP_Var *exception)
{
    if (method_name.type != PP_VARTYPE_STRING) {
        trace_error("%s, method_name is not a string\n", __func__);
        // TODO: fill exception
        return PP_MakeUndefined();
    }

    struct call_param_s *p = g_slice_alloc(sizeof(*p));
    p->object =         object;
    p->method_name =    method_name;
    p->argc =           argc;
    p->argv =           argv;
    p->exception =      exception;
    p->m_loop =         ppb_message_loop_get_current();
    p->depth =          ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(n2p_call_comt, p), 0, PP_OK,
                                           p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    struct PP_Var result = p->result;
    g_slice_free1(sizeof(*p), p);

    return result;
}
static
bool
n2p_has_property(void *object, struct PP_Var name, struct PP_Var *exception)
{
    if (name.type != PP_VARTYPE_STRING) {
        trace_error("%s, name is not a string\n", __func__);
        // TODO: fill exception
        return false;
    }

    struct has_property_param_s *p = g_slice_alloc(sizeof(*p));
    p->object =     object;
    p->name =       name;
    p->exception =  exception;
    p->m_loop =     ppb_message_loop_get_current();
    p->depth =      ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(n2p_has_property_comt, p), 0,
                                           PP_OK, p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    bool result = p->result;
    g_slice_free1(sizeof(*p), p);

    return result;
}
int32_t
ppb_flash_message_loop_run(PP_Resource flash_message_loop)
{
    struct pp_flash_message_loop_s *fml =
                        pp_resource_acquire(flash_message_loop, PP_RESOURCE_FLASH_MESSAGE_LOOP);
    if (!fml) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    PP_Resource message_loop = ppb_message_loop_get_current();
    fml->running = 1;
    fml->message_loop = message_loop;
    fml->depth = ppb_message_loop_get_depth(message_loop) + 1;

    pp_resource_ref(flash_message_loop);        // prevent destroy of running loop
    pp_resource_release(flash_message_loop);

    // launching nested loop without depth increase to prevent hang up of previously pushed tasks
    ppb_message_loop_run_int(message_loop, ML_NESTED);

    fml = pp_resource_acquire(flash_message_loop, PP_RESOURCE_FLASH_MESSAGE_LOOP);
    if (fml) {
        fml->running = 0;
        pp_resource_release(flash_message_loop);
    }

    pp_resource_unref(flash_message_loop);
    return PP_OK;
}
Esempio n. 7
0
struct PP_Var
ppb_instance_private_execute_script(PP_Instance instance, struct PP_Var script,
                                    struct PP_Var *exception)
{
    if (script.type != PP_VARTYPE_STRING) {
        trace_error("%s, 'script' is not a string\n", __func__);
        // TODO: fill exception
        return PP_MakeUndefined();
    }

    struct pp_instance_s *pp_i = tables_get_pp_instance(instance);
    if (!pp_i) {
        trace_error("%s, bad instance\n", __func__);
        return PP_MakeUndefined();
    }

    struct execute_script_param_s p;
    p.script =  script;
    p.pp_i =    pp_i;
    p.m_loop =  ppb_message_loop_get_current();
    p.depth =   ppb_message_loop_get_depth(p.m_loop) + 1;

    ppb_var_add_ref(script);
    ppb_message_loop_post_work(p.m_loop, PP_MakeCompletionCallback(_execute_script_comt, &p), 0);
    ppb_message_loop_run_int(p.m_loop, 1);
    ppb_var_release(script);

    return p.result;
}
TRACE_WRAPPER
PP_Resource
trace_ppb_message_loop_get_current(void)
{
    trace_info("[PPB] {full} %s\n", __func__+6);
    return ppb_message_loop_get_current();
}
static
void
n2p_deallocate(void *object)
{
    struct deallocate_param_s *p = g_slice_alloc(sizeof(*p));
    p->object = object;
    p->m_loop = ppb_message_loop_get_current();
    p->depth =  ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(n2p_deallocate_comt, p), 0, PP_OK,
                                           p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    g_slice_free1(sizeof(*p), p);
}
Esempio n. 10
0
struct PP_Var
ppb_flash_get_proxy_for_url(PP_Instance instance, const char *url)
{
    struct get_proxy_for_url_param_s *p = g_slice_alloc(sizeof(*p));
    p->instance_id =    instance;
    p->url =            url;
    p->m_loop =         ppb_message_loop_get_current();
    p->depth =          ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(get_proxy_for_url_comt, p), 0,
                                           PP_OK, p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    struct PP_Var result = p->result;
    g_slice_free1(sizeof(*p), p);

    return result;
}
static
struct PP_Var
n2p_construct(void *object, uint32_t argc, struct PP_Var *argv, struct PP_Var *exception)
{
    struct construct_param_s *p = g_slice_alloc(sizeof(*p));
    p->object =     object;
    p->argc =       argc;
    p->argv =       argv;
    p->exception =  exception;
    p->m_loop =     ppb_message_loop_get_current();
    p->depth =      ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(n2p_construct_comt, p), 0, PP_OK,
                                           p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    struct PP_Var result = p->result;
    g_slice_free1(sizeof(*p), p);

    return result;
}
Esempio n. 12
0
PP_Bool
ppb_flash_is_rect_topmost(PP_Instance instance, const struct PP_Rect *rect)
{
    if (!rect)
        return PP_FALSE;

    struct topmost_rect_param_s *p = g_slice_alloc(sizeof(*p));
    p->instance =       instance;
    p->rect =          *rect;
    p->m_loop =         ppb_message_loop_get_current();
    p->depth =          ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(topmost_rect_comt, p), 0, PP_OK,
                                           p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    PP_Bool result = p->result;
    g_slice_free1(sizeof(*p), p);

    return result;
}
Esempio n. 13
0
int32_t
ppb_url_loader_finish_streaming_to_file(PP_Resource loader, struct PP_CompletionCallback callback)
{
    struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER);
    if (!ul) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    if (!ul->stream_to_file) {
        trace_error("%s, not streaming to file\n", __func__);
        pp_resource_release(loader);
        return PP_ERROR_FAILED;
    }

    ul->stream_to_file_ccb = callback;
    ul->stream_to_file_ccb_ml = ppb_message_loop_get_current();
    // TODO: handle callback.func == NULL case

    pp_resource_release(loader);
    return PP_OK_COMPLETIONPENDING;
}
struct PP_Var
ppb_flash_clipboard_read_data(PP_Instance instance_id, PP_Flash_Clipboard_Type clipboard_type,
                              uint32_t format)
{
    if (!clipboard_type_and_format_are_supported(clipboard_type, format, __func__))
        return PP_MakeUndefined();

    struct clipboard_read_data_param_s *p = g_slice_alloc(sizeof(*p));
    p->clipboard_type = clipboard_type;
    p->format =         format;
    p->m_loop =         ppb_message_loop_get_current();
    p->depth =          ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(clipboard_read_data_comt, p), 0,
                                           PP_OK, p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);

    struct PP_Var result = p->result;
    g_slice_free1(sizeof(*p), p);

    return result;
}
Esempio n. 15
0
struct PP_Var
ppb_url_util_dev_get_document_url(PP_Instance instance, struct PP_URLComponents_Dev *components)
{
    reset_components(components);
    struct pp_instance_s *pp_i = tables_get_pp_instance(instance);
    if (!pp_i) {
        trace_error("%s, bad instance\n", __func__);
        return PP_MakeUndefined();
    }

    struct get_document_url_param_s p;
    p.npp = pp_i->npp;
    p.m_loop = ppb_message_loop_get_current();
    p.depth = ppb_message_loop_get_depth(p.m_loop) + 1;
    p.np_window_obj = pp_i->np_window_obj;

    ppb_message_loop_post_work(p.m_loop, PP_MakeCompletionCallback(_get_document_url_comt, &p), 0);
    ppb_message_loop_run_int(p.m_loop, 1);

    if (components)
        parse_url_string(ppb_var_var_to_utf8(p.result, NULL), components);

    return p.result;
}
Esempio n. 16
0
int32_t
ppb_url_loader_follow_redirect(PP_Resource loader, struct PP_CompletionCallback callback)
{
    struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER);
    if (!ul) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }
    char *new_url = nullsafe_strdup(ul->redirect_url);

    free_and_nullify(ul, url);
    free_and_nullify(ul, redirect_url);
    free_and_nullify(ul, status_line);
    free_and_nullify(ul, headers);
    free_and_nullify(ul, request_headers);

    if (ul->fd >= 0) {
        close(ul->fd);
        ul->fd = -1;
    }

    // abort further handling of the NPStream
    if (ul->np_stream) {
        ul->np_stream->pdata = NULL;
        ul->np_stream = NULL;
    }

    ul->fd = open_temporary_file();
    ul->url = new_url;
    ul->read_pos = 0;
    ul->method = PP_METHOD_GET;
    ul->ccb = callback;

    struct url_loader_open_param_s *p = g_slice_alloc(sizeof(*p));
    p->url =                ul->url;
    p->loader =             loader;
    p->instance_id =        ul->instance->id;
    p->method =             ul->method;
    p->request_headers =    ul->request_headers;
    p->custom_referrer_url = ul->custom_referrer_url;
    p->custom_content_transfer_encoding =  ul->custom_content_transfer_encoding;
    p->custom_user_agent =  ul->custom_user_agent;
    p->target =             NULL;
    p->post_len =           0;
    p->post_data =          NULL;
    p->m_loop =             ppb_message_loop_get_current();
    p->depth =              ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_message_loop_post_work(p->m_loop, PP_MakeCCB(_url_loader_open_comt, p), 0);
    ppb_message_loop_run_nested(p->m_loop);

    pp_resource_release(loader);

    int retval = p->retval;
    g_slice_free1(sizeof(*p), p);

    if (retval != NPERR_NO_ERROR)
        return PP_ERROR_FAILED;

    if (callback.func == NULL) {
        int done = 0;
        while (!done) {
            ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER);
            if (ul) {
                done = ul->finished_loading;
                pp_resource_release(loader);
            } else {
                break;
            }
            printf("waitin'\n");
            usleep(10000);
        }
        return PP_OK;
    }

    return PP_OK_COMPLETIONPENDING;
}
Esempio n. 17
0
int32_t
ppb_url_loader_open_target(PP_Resource loader, PP_Resource request_info,
                           struct PP_CompletionCallback callback, const char *target)
{
    struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER);
    if (!ul) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }
    struct pp_url_request_info_s *ri = pp_resource_acquire(request_info,
                                                           PP_RESOURCE_URL_REQUEST_INFO);
    if (!ri) {
        trace_error("%s, bad resource\n", __func__);
        pp_resource_release(loader);
        return PP_ERROR_BADRESOURCE;
    }
    struct PP_Var full_url;

    if (ri->is_immediate_javascript) {
        full_url = ppb_var_var_from_utf8_z(ri->url);
    } else {
        struct PP_Var rel_url = ppb_var_var_from_utf8_z(ri->url);
        full_url = ppb_url_util_dev_resolve_relative_to_document(ul->instance->id, rel_url, NULL);
        ppb_var_release(rel_url);
    }

    ul->url =              nullsafe_strdup(ppb_var_var_to_utf8(full_url, NULL));
    ul->method =           ri->method;
    ul->read_pos =         0;
    ul->request_headers =  nullsafe_strdup(ri->headers);
    ul->follow_redirects = ri->follow_redirects;
    ul->stream_to_file =   ri->stream_to_file;

    ul->record_download_progress =         ri->record_download_progress;
    ul->record_upload_progress =           ri->record_upload_progress;
    ul->custom_referrer_url =              nullsafe_strdup(ri->custom_referrer_url);
    ul->allow_cross_origin_requests =      ri->allow_cross_origin_requests;
    ul->allow_credentials =                ri->allow_credentials;
    ul->custom_content_transfer_encoding = nullsafe_strdup(ri->custom_content_transfer_encoding);
    ul->custom_user_agent =                nullsafe_strdup(ri->custom_user_agent);
    ul->target =                           nullsafe_strdup(target);

#define TRIM_NEWLINE(s)     s = trim_nl(s)

    TRIM_NEWLINE(ul->request_headers);
    TRIM_NEWLINE(ul->custom_referrer_url);
    TRIM_NEWLINE(ul->custom_content_transfer_encoding);
    TRIM_NEWLINE(ul->custom_user_agent);

    ul->post_len = ri->post_len;
    if (ri->post_len > 0) {
        ul->post_data = malloc(ri->post_len);
        memcpy(ul->post_data, ri->post_data, ri->post_len);
    }

    ul->fd = open_temporary_file();
    ul->ccb = callback;

    ppb_var_release(full_url);
    pp_resource_release(request_info);

    struct url_loader_open_param_s *p = g_slice_alloc(sizeof(*p));
    p->url =                ul->url;
    p->loader =             loader;
    p->instance_id =        ul->instance->id;
    p->method =             ul->method;
    p->request_headers =    ul->request_headers;
    p->custom_referrer_url = ul->custom_referrer_url;
    p->custom_content_transfer_encoding = ul->custom_content_transfer_encoding;
    p->custom_user_agent =  ul->custom_user_agent;
    p->target =         ul->target;
    p->post_len =       ul->post_len;
    p->post_data =      ul->post_data;
    p->m_loop =         ppb_message_loop_get_current();
    p->depth =          ppb_message_loop_get_depth(p->m_loop) + 1;

    ppb_core_add_ref_resource(loader);  // add ref to ensure data in ul remain accessible
    pp_resource_release(loader);

    ppb_message_loop_post_work(p->m_loop, PP_MakeCCB(_url_loader_open_comt, p), 0);
    ppb_message_loop_run_nested(p->m_loop);
    ppb_core_release_resource(loader);
    
    int retval = p->retval;
    g_slice_free1(sizeof(*p), p);

    if (retval != NPERR_NO_ERROR)
        return PP_ERROR_FAILED;

    if (callback.func == NULL) {
        int done = 0;
        while (!done) {
            ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER);
            if (ul) {
                done = ul->finished_loading;
                pp_resource_release(loader);
            } else {
                break;
            }
            printf("waitin'\n");
            usleep(10000);
        }
        return PP_OK;
    }

    return PP_OK_COMPLETIONPENDING;
}
Esempio n. 18
0
PP_Bool
ppb_core_is_main_thread(void)
{
    return ppb_message_loop_get_current() == ppb_message_loop_get_for_main_thread();
}
Esempio n. 19
0
static
uintptr_t
load_ppp_module()
{
    if (module_dl_handler) {
        // already loaded
        return 0;
    }

    // allocate auxiliary instance
    if (!aux_instance) {
        aux_instance = calloc(1, sizeof(*aux_instance));
        if (!aux_instance)
            return 1;

        aux_instance->id = tables_generate_new_pp_instance_id();
        tables_add_pp_instance(aux_instance->id, aux_instance);
    }

    // allocate message loop for browser thread
    if (ppb_message_loop_get_current() == 0) {
        PP_Resource message_loop = ppb_message_loop_create(aux_instance->id);
        ppb_message_loop_attach_to_current_thread(message_loop);
        ppb_message_loop_proclaim_this_thread_browser();
    }

    // allocate message loop for plugin thread (main thread)
    if (ppb_message_loop_get_for_main_thread() == 0) {
        pthread_barrier_init(&aux_instance->main_thread_barrier, NULL, 2);
        pthread_create(&aux_instance->main_thread, NULL, fresh_wrapper_main_thread, aux_instance);
        pthread_detach(aux_instance->main_thread);
        pthread_barrier_wait(&aux_instance->main_thread_barrier);
        pthread_barrier_destroy(&aux_instance->main_thread_barrier);
    }

    fpp_config_initialize();

    if (tried_files) {
        g_list_free_full(tried_files, g_free);
        tried_files = NULL;
    }

    if (fpp_config_get_plugin_path()) {
        const char *ptr = fpp_config_get_plugin_path();
        const char *last = strchr(ptr, ':');
        uintptr_t   ret;

        // parse ':'-separated list
        while (last != NULL) {
            // try entries one by one
            char *entry = strndup(ptr, last - ptr);
            ret = do_load_ppp_module(entry);
            free(entry);
            if (ret == 0)
                return 0;

            ptr = last + 1;
            last = strchr(ptr, ':');
        }

        // and the last entry
        ret = do_load_ppp_module(ptr);
        if (ret == 0)
            return 0;

        goto failure;
    }

    // try all paths
    const char **path_list = fpp_config_get_plugin_path_list();
    while (*path_list) {
        gchar *fname = g_strdup_printf("%s/%s", *path_list, fpp_config_get_plugin_file_name());
        uintptr_t ret = do_load_ppp_module(fname);
        g_free(fname);
        if (ret == 0)
            return 0;
        path_list ++;
    }

failure:
    config.quirks.plugin_missing = 1;
    use_fallback_version_strings();
    trace_error("%s, can't find %s\n", __func__, fpp_config_get_plugin_file_name());
    return 1;
}