static void soup_default_callback(SoupServerContext *context, SoupMessage *msg, gpointer data) { soup_message_add_header (msg->response_headers, "Server", "Red Carpet Daemon/"VERSION); soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); } /* default_callback */
void http_client_request(const char *url, const char *post_data, const struct http_client_handler *handler, void *ctx) { SoupMessage *msg; struct http_request *request; if (post_data) { msg = soup_message_new(SOUP_METHOD_POST, url); #ifdef HAVE_SOUP_24 soup_message_set_request (msg, "application/x-www-form-urlencoded", SOUP_MEMORY_COPY, post_data, strlen(post_data)); soup_message_headers_append(msg->request_headers, "User-Agent", "mpdscribble/" VERSION); soup_message_headers_append(msg->request_headers, "Pragma", "no-cache"); soup_message_headers_append(msg->request_headers, "Accept", "*/*"); #else soup_message_set_request (msg, "application/x-www-form-urlencoded", SOUP_BUFFER_SYSTEM_OWNED, g_strdup(post_data), strlen(post_data)); soup_message_add_header(msg->request_headers, "User-Agent", "mpdscribble/" VERSION); soup_message_add_header(msg->request_headers, "Pragma", "no-cache"); soup_message_add_header(msg->request_headers, "Accept", "*/*"); #endif } else { msg = soup_message_new(SOUP_METHOD_GET, url); } soup_message_set_flags(msg, SOUP_MESSAGE_NO_REDIRECT); request = g_new(struct http_request, 1); request->handler = handler; request->handler_ctx = ctx; soup_session_queue_message(http_client.session, msg, http_client_soup_callback, request); }
static void soup_rpc_callback (SoupServerContext *context, SoupMessage *msg, gpointer data) { xmlrpc_env env; xmlrpc_mem_block *output; const char *username; RCDIdentity *identity = NULL; RCDRPCMethodData *method_data; xmlrpc_env_init (&env); method_data = g_new0 (RCDRPCMethodData, 1); /* Get the username from the auth context and get its identity */ username = soup_server_auth_get_user (context->auth); if (strcmp (username, rcd_prefs_get_mid ()) == 0) { identity = rcd_identity_new (); identity->username = g_strdup ("server"); identity->privileges = rcd_privileges_from_string ("superuser"); } else identity = rcd_identity_lookup (username); g_assert (identity != NULL); method_data->host = soup_server_context_get_client_host (context); method_data->identity = identity; output = process_rpc_call ( &env, msg->request.body, msg->request.length, method_data); rcd_identity_free (method_data->identity); g_free (method_data); soup_message_add_header (msg->response_headers, "Server", "Red Carpet Daemon/"VERSION); if (env.fault_occurred) { soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); return; } /* Let Soup free the data for us */ msg->response.owner = SOUP_BUFFER_SYSTEM_OWNED; msg->response.length = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); msg->response.body = g_memdup( XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), msg->response.length); soup_message_set_status (msg, SOUP_STATUS_OK); xmlrpc_mem_block_free(output); } /* soup_rpc_callback */
static gboolean soup_auth_callback (SoupServerAuthContext *auth_ctx, SoupServerAuth *auth, SoupMessage *msg, gpointer user_data) { const char *username; RCDIdentity *identity; soup_message_add_header (msg->response_headers, "Server", "Red Carpet Daemon/"VERSION); /* * If there wasn't any authentication data passed back, we have to fail * the call. */ if (!auth) return FALSE; username = soup_server_auth_get_user (auth); /* * Getting the MID as the username is special; it means that the * server is connecting to us and telling us to do something. */ if (strcmp (username, rcd_prefs_get_mid ()) == 0) { char *pw, *password; gboolean matched; password = g_strdup_printf ("%s:Express:%s", rcd_prefs_get_mid (), rcd_prefs_get_secret ()); pw = rc_md5_digest_from_string (password); g_free (password); /* * Yes, we have to hash this twice; the first is to generate the * secret, which is a hash of the string above, and the second is * because all passwords are hashed before they are sent for wire * safety. */ password = rc_md5_digest_from_string (pw); g_free (pw); matched = soup_server_auth_check_passwd (auth, password); g_free (password); if (matched) return TRUE; } identity = rcd_identity_lookup (username); if (!rcd_identity_password_file_is_secure () || !identity || !soup_server_auth_check_passwd (auth, identity->password)) { rc_debug (RC_DEBUG_LEVEL_WARNING, "Couldn't authenticate %s", username); rcd_identity_free (identity); return FALSE; } rcd_identity_free (identity); return TRUE; } /* auth_callback */
gboolean net_queue_dispatcher(void) { STNET *_stnet; guint qlen = g_queue_get_length(rf->stqueue); d("que len:%d workers:%d\n", g_queue_get_length(rf->stqueue), net_queue_run_count); #if EVOLUTION_VERSION < 30304 if (qlen && net_queue_run_count < gconf_client_get_int ( rss_gconf, GCONF_KEY_DOWNLOAD_QUEUE_SIZE, NULL)) { #else if (qlen && net_queue_run_count < g_settings_get_int ( settings, CONF_DOWNLOAD_QUEUE_SIZE)) { #endif net_queue_run_count++; _stnet = g_queue_pop_head(rf->stqueue); soup_session_queue_message ( _stnet->ss, _stnet->sm, _stnet->cb2, _stnet->cbdata2); g_free(_stnet); return TRUE; } net_qid = 0; return FALSE; } GString* net_post_blocking(gchar *url, GSList *headers, GString *post, NetStatusCallback cb, gpointer data, GError **err) { #if LIBSOUP_VERSION < 2003000 SoupUri *suri = NULL; #else SoupURI *suri = NULL; #endif SoupMessage *req = NULL; GString *response = NULL; CallbackInfo info = { cb, data, 0, 0 }; SoupSession *soup_sess = NULL; gchar *agstr; if (!rf->b_session) rf->b_session = soup_sess = soup_session_sync_new_with_options( SOUP_SESSION_TIMEOUT, SS_TIMEOUT, NULL); else soup_sess = rf->b_session; g_signal_connect (soup_sess, "authenticate", G_CALLBACK (authenticate), (gpointer)url); #if LIBSOUP_VERSION < 2003000 g_signal_connect (soup_sess, "reauthenticate", G_CALLBACK (reauthenticate), (gpointer)url); #endif req = soup_message_new(SOUP_METHOD_GET, url); if (!req) { g_set_error(err, NET_ERROR, NET_ERROR_GENERIC, "%s", soup_status_get_phrase(2)); //invalid url goto out; } d("request ok :%d\n", req->status_code); g_signal_connect(G_OBJECT(req), "got-chunk", G_CALLBACK(got_chunk_blocking_cb), &info); for (; headers; headers = headers->next) { char *header = headers->data; /* soup wants the key and value separate, so we have to munge this * a bit. */ char *colonpos = strchr(header, ':'); *colonpos = 0; #if LIBSOUP_VERSION < 2003000 soup_message_add_header( req->request_headers, header, colonpos+1); #else soup_message_headers_append( req->request_headers, header, colonpos+1); #endif *colonpos = ':'; } agstr = g_strdup_printf("Evolution/%s; Evolution-RSS/%s", EVOLUTION_VERSION_STRING, VERSION); #if LIBSOUP_VERSION < 2003000 soup_message_add_header ( req->request_headers, "User-Agent", agstr); #else soup_message_headers_append ( req->request_headers, "User-Agent", agstr); #endif g_free(agstr); #if (DATASERVER_VERSION >= 2023001) proxify_session(proxy, soup_sess, url); #endif rf->b_session = soup_sess; rf->b_msg_session = req; soup_session_send_message(soup_sess, req); if (req->status_code != SOUP_STATUS_OK) { //might not be a good ideea soup_session_abort(soup_sess); g_object_unref(soup_sess); rf->b_session = NULL; g_set_error(err, NET_ERROR, NET_ERROR_GENERIC, "%s", soup_status_get_phrase(req->status_code)); goto out; } #if LIBSOUP_VERSION < 2003000 response = g_string_new_len( req->response.body, req->response.length); #else response = g_string_new_len( req->response_body->data, req->response_body->length); #endif out: if (suri) soup_uri_free(suri); if (req) g_object_unref(G_OBJECT(req)); return response; }
// same stuff as net_get_* but without accumulating headers // push all donwloads to a customizable length queue gboolean download_unblocking( gchar *url, NetStatusCallback cb, gpointer data, gpointer cb2, gpointer cbdata2, guint track, GError **err) { SoupMessage *msg; CallbackInfo *info = NULL; SoupSession *soup_sess; gchar *agstr; STNET *stnet; soup_sess = soup_session_async_new(); #if LIBSOUP_VERSION > 2024000 if (rss_soup_jar) { soup_session_add_feature(soup_sess, SOUP_SESSION_FEATURE(rss_soup_jar)); } #endif if (cb && data) { info = g_new0(CallbackInfo, 1); info->user_cb = cb; info->user_data = data; info->current = 0; info->total = 0; info->ss = soup_sess; } g_signal_connect (soup_sess, "authenticate", G_CALLBACK (authenticate), (gpointer)url); #if LIBSOUP_VERSION < 2003000 g_signal_connect (soup_sess, "reauthenticate", G_CALLBACK (reauthenticate), (gpointer)url); #endif /* Queue an async HTTP request */ msg = soup_message_new ("GET", url); if (!msg) { g_free(info); g_set_error(err, NET_ERROR, NET_ERROR_GENERIC, "%s", soup_status_get_phrase(2)); //invalid url return FALSE; } if (track) { //we want to be able to abort this session by calling //abort_all_soup g_hash_table_insert(rf->session, soup_sess, msg); g_hash_table_insert(rf->abort_session, soup_sess, msg); g_hash_table_insert(rf->key_session, data, soup_sess); } agstr = g_strdup_printf("Evolution/%s; Evolution-RSS/%s", EVOLUTION_VERSION_STRING, VERSION); #if LIBSOUP_VERSION < 2003000 soup_message_add_header (msg->request_headers, "User-Agent", agstr); #else soup_message_headers_append (msg->request_headers, "User-Agent", agstr); #endif g_free(agstr); if (info) { g_signal_connect(G_OBJECT(msg), "got_chunk", G_CALLBACK(got_chunk_cb), info); //FIXME Find a way to free this maybe weak_ref soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); soup_message_add_header_handler (msg, "got_body", "Location", G_CALLBACK (redirect_handler), info); } soup_message_body_set_accumulate (msg->response_body, FALSE); stnet = g_new0(STNET, 1); stnet->ss = soup_sess; stnet->sm = msg; stnet->cb2 = cb2; stnet->cbdata2 = cbdata2; stnet->url = url; stnet->callback = idle_callback; stnet->data = stnet; if (!net_qid) net_qid = g_idle_add((GSourceFunc)net_queue_dispatcher, NULL); stnet->callback(stnet->data); //// g_object_add_weak_pointer (G_OBJECT(msg), (gpointer)info); g_object_weak_ref (G_OBJECT(msg), unblock_free, soup_sess); // g_object_weak_ref (G_OBJECT(soup_sess), unblock_free, soup_sess); // GMainLoop *mainloop = g_main_loop_new (g_main_context_default (), FALSE); // g_timeout_add (10 * 1000, &conn_mainloop_quit, mainloop); return TRUE; }
gboolean net_get_unblocking(gchar *url, NetStatusCallback cb, gpointer data, gpointer cb2, gpointer cbdata2, guint track, GError **err) { SoupMessage *msg; CallbackInfo *info = NULL; SoupSession *soup_sess; gchar *agstr; gchar *mainurl = NULL; gchar **res; STNET *stnet; soup_sess = soup_session_async_new(); #if LIBSOUP_VERSION > 2024000 if (rss_soup_jar) { soup_session_add_feature( soup_sess, SOUP_SESSION_FEATURE(rss_soup_jar)); } #endif if (cb && data) { info = g_new0(CallbackInfo, 1); info->user_cb = cb; info->user_data = data; info->current = 0; info->total = 0; info->ss = soup_sess; } /*try to find upstream url to supply a password*/ if (data) { res = g_strsplit(data, ";COMMENT-", 0); if (res[0] && g_str_has_prefix(res[0], "RSS-")) { mainurl = g_strdup(res[0]+4); g_strfreev(res); } } g_signal_connect (soup_sess, "authenticate", G_CALLBACK (authenticate), (gpointer)mainurl?mainurl:g_strdup(url)); #if LIBSOUP_VERSION < 2003000 g_signal_connect (soup_sess, "reauthenticate", G_CALLBACK (reauthenticate), (gpointer)mainurl?mainurl:g_strdup(url)); #endif /* Queue an async HTTP request */ msg = soup_message_new ("GET", url); if (!msg) { if (info) g_free(info); g_set_error(err, NET_ERROR, NET_ERROR_GENERIC, "%s", soup_status_get_phrase(2)); //invalid url return FALSE; } if (track) { //we want to be able to abort this session by calling //abort_all_soup g_hash_table_insert(rf->session, soup_sess, msg); g_hash_table_insert(rf->abort_session, soup_sess, msg); g_hash_table_insert(rf->key_session, data, soup_sess); } agstr = g_strdup_printf("Evolution/%s; Evolution-RSS/%s", EVOLUTION_VERSION_STRING, VERSION); #if LIBSOUP_VERSION < 2003000 soup_message_add_header (msg->request_headers, "User-Agent", agstr); #else soup_message_headers_append (msg->request_headers, "User-Agent", agstr); #endif g_free(agstr); if (info) { g_signal_connect(G_OBJECT(msg), "got_chunk", G_CALLBACK(got_chunk_cb), info); //FIXME Find a way to free this maybe weak_ref soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); soup_message_add_header_handler (msg, "got_body", "Location", G_CALLBACK (redirect_handler), info); } stnet = g_new0(STNET, 1); stnet->ss = soup_sess; stnet->sm = msg; stnet->cb2 = cb2; stnet->cbdata2 = cbdata2; stnet->url = g_strdup(url); stnet->callback = queue_callback; stnet->data = stnet; proxify_session_async(proxy, stnet); //free stnet //// g_object_add_weak_pointer (G_OBJECT(msg), (gpointer)info); g_object_weak_ref (G_OBJECT(msg), unblock_free, soup_sess); // g_object_weak_ref (G_OBJECT(soup_sess), unblock_free, soup_sess); return TRUE; }
guint net_get_status(const char *url, GError **err) { #if LIBSOUP_VERSION < 2003000 SoupUri *suri = NULL; #else SoupURI *suri = NULL; #endif SoupMessage *req = NULL; guint response = 0; SoupSession *soup_sess = NULL; GSList *headers = NULL; gchar *agstr; if (!rf->b_session) rf->b_session = soup_sess = soup_session_sync_new_with_options( SOUP_SESSION_TIMEOUT, SS_TIMEOUT, NULL); else soup_sess = rf->b_session; req = soup_message_new(SOUP_METHOD_GET, url); if (!req) { g_set_error(err, NET_ERROR, NET_ERROR_GENERIC, "%s", soup_status_get_phrase(2)); //invalid url goto out; } for (; headers; headers = headers->next) { char *header = headers->data; /* soup wants the key and value separate, so we have to munge this * a bit. */ char *colonpos = strchr(header, ':'); *colonpos = 0; #if LIBSOUP_VERSION < 2003000 soup_message_add_header( req->request_headers, header, colonpos+1); #else soup_message_headers_append( req->request_headers, header, colonpos+1); #endif *colonpos = ':'; } agstr = g_strdup_printf("Evolution/%s; Evolution-RSS/%s", EVOLUTION_VERSION_STRING, VERSION); #if LIBSOUP_VERSION < 2003000 soup_message_add_header (req->request_headers, "User-Agent", agstr); #else soup_message_headers_append (req->request_headers, "User-Agent", agstr); #endif g_free(agstr); rf->b_session = soup_sess; rf->b_msg_session = req; soup_session_send_message(soup_sess, req); if (req->status_code != SOUP_STATUS_OK) { //might not be a good ideea soup_session_abort(soup_sess); g_object_unref(soup_sess); rf->b_session = NULL; g_set_error(err, NET_ERROR, NET_ERROR_GENERIC, "%s", soup_status_get_phrase(req->status_code)); goto out; } out: if (suri) soup_uri_free(suri); response = req->status_code; if (req) g_object_unref(G_OBJECT(req)); return response; }