Beispiel #1
0
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 */
Beispiel #2
0
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);
}
Beispiel #3
0
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 */
Beispiel #4
0
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 */
Beispiel #5
0
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;
}
Beispiel #6
0
// 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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}