Commit 42178551 authored by Patrick Griffis's avatar Patrick Griffis 💬
Browse files

Remove XMLRPC support

This feature does not appear to be used by any maintained project
and in general XMLRPC usage on the internet has gone down.

Removing it just reduces complexity and maintainance burden.
parent c8a211c0
......@@ -12,8 +12,6 @@ RUN dnf update -y \
make \
meson \
mod_ssl \
php \
php-xmlrpc \
redhat-rpm-config \
samba-winbind-clients \
which \
......
......@@ -259,8 +259,7 @@ request headers and body of the message:
(Although this is a bad example, because
<application>libsoup</application> actually has convenience methods
for dealing with <link linkend="libsoup-2.4-HTML-Form-Support">HTML
forms</link>, as well as <link
linkend="libsoup-2.4-XMLRPC-Support">XML-RPC</link>.)
forms</link>.)
</para>
<para>
......
......@@ -63,7 +63,6 @@
<chapter>
<title>Web Services APIs</title>
<xi:include href="xml/soup-form.xml"/>
<xi:include href="xml/soup-xmlrpc.xml"/>
<xi:include href="xml/soup-websocket.xml"/>
</chapter>
......
......@@ -671,34 +671,6 @@ soup_form_request_new_from_hash
soup_form_request_new_from_multipart
</SECTION>
<SECTION>
<FILE>soup-xmlrpc</FILE>
<TITLE>XMLRPC Support</TITLE>
<SUBSECTION>
SOUP_XMLRPC_ERROR
SoupXMLRPCError
SOUP_XMLRPC_FAULT
SoupXMLRPCFault
<SUBSECTION>
soup_xmlrpc_build_request
soup_xmlrpc_message_new
soup_xmlrpc_parse_response
soup_xmlrpc_variant_new_datetime
soup_xmlrpc_variant_get_datetime
<SUBSECTION>
SoupXMLRPCParams
soup_xmlrpc_params_free
soup_xmlrpc_params_parse
soup_xmlrpc_parse_request
soup_xmlrpc_build_response
soup_xmlrpc_build_fault
soup_xmlrpc_message_set_response
soup_xmlrpc_message_set_fault
<SUBSECTION Private>
soup_xmlrpc_error_quark
soup_xmlrpc_fault_quark
</SECTION>
<SECTION>
<FILE>soup-logger</FILE>
<TITLE>SoupLogger</TITLE>
......
......@@ -40,7 +40,6 @@ ignore_headers = [
'soup-socket-private.h',
'soup-value-utils.h',
'soup-websocket-extension-manager-private.h',
'soup-xmlrpc-old.h'
]
mkdb_args = [
......
......@@ -5,9 +5,6 @@ AuthDomain
form_* parent="Soup.Form" name="form_(.+)"
form_encode_datalist.form_data_set type_arguments="string"
form_request_new_from_datalist.form_data_set type_arguments="string"
xmlrpc_* parent="Soup.XMLRPC" name="xmlrpc_(.+)"
XMLRPCFault errordomain parent="Soup.XMLRPC" name="Fault"
XMLRPCError parent="Soup.XMLRPC" name="Error"
HTTPVersion.http_* name="http_(.+)"
// Report upstream
......@@ -36,7 +33,6 @@ Session*.new_with_options skip=false
URI
.set_query_from_fields skip=false
// uri_host_*.* type="Soup.URI"
xmlrpc_* skip=false
// Not enough GIR information
Buffer.data type="uint8[]" array_length_field="length"
......@@ -44,7 +40,6 @@ MessageBody.data type="uint8[]" array_length_field="length"
Date
.new_from_time_t.when type="time_t"
.to_time_t type="time_t"
xmlrpc_build_fault printf_format
// Simplify memory management
Buffer
......
......@@ -55,7 +55,6 @@ extern "C" {
#include <libsoup/soup-websocket-extension.h>
#include <libsoup/soup-websocket-extension-deflate.h>
#include <libsoup/soup-websocket-extension-manager.h>
#include <libsoup/soup-xmlrpc.h>
#undef __SOUP_H_INSIDE__
......
......@@ -46,8 +46,6 @@ soup_sources = [
'websocket/soup-websocket-extension-deflate.c',
'websocket/soup-websocket-extension-manager.c',
'xmlrpc/soup-xmlrpc.c',
'soup-body-input-stream.c',
'soup-body-output-stream.c',
'soup-client-input-stream.c',
......@@ -123,8 +121,6 @@ soup_introspection_headers = [
'websocket/soup-websocket-extension-deflate.h',
'websocket/soup-websocket-extension-manager.h',
'xmlrpc/soup-xmlrpc.h',
'soup-date.h',
'soup-form.h',
'soup-headers.h',
......
......@@ -57,7 +57,6 @@ extern "C" {
#include "websocket/soup-websocket-extension.h"
#include "websocket/soup-websocket-extension-deflate.h"
#include "websocket/soup-websocket-extension-manager.h"
#include "xmlrpc/soup-xmlrpc.h"
#undef __SOUP_H_INSIDE__
......
This diff is collapsed.
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright 2015 - Collabora Ltd.
*/
#pragma once
#include "soup-types.h"
G_BEGIN_DECLS
/* XML-RPC client */
SOUP_AVAILABLE_IN_2_52
char *soup_xmlrpc_build_request (const char *method_name,
GVariant *params,
GError **error);
SOUP_AVAILABLE_IN_2_52
SoupMessage *soup_xmlrpc_message_new (const char *uri,
const char *method_name,
GVariant *params,
GError **error);
SOUP_AVAILABLE_IN_2_52
GVariant *soup_xmlrpc_parse_response (const char *method_response,
int length,
const char *signature,
GError **error);
/* XML-RPC server */
typedef struct _SoupXMLRPCParams SoupXMLRPCParams;
SOUP_AVAILABLE_IN_2_52
void soup_xmlrpc_params_free (SoupXMLRPCParams *self);
SOUP_AVAILABLE_IN_2_52
GVariant *soup_xmlrpc_params_parse (SoupXMLRPCParams *self,
const char *signature,
GError **error);
SOUP_AVAILABLE_IN_2_52
char *soup_xmlrpc_parse_request (const char *method_call,
int length,
SoupXMLRPCParams **params,
GError **error);
SOUP_AVAILABLE_IN_2_52
char *soup_xmlrpc_build_response (GVariant *value,
GError **error);
SOUP_AVAILABLE_IN_2_4
char *soup_xmlrpc_build_fault (int fault_code,
const char *fault_format,
...) G_GNUC_PRINTF (2, 3);
SOUP_AVAILABLE_IN_2_52
gboolean soup_xmlrpc_message_set_response (SoupMessage *msg,
GVariant *value,
GError **error);
SOUP_AVAILABLE_IN_2_52
void soup_xmlrpc_message_set_fault (SoupMessage *msg,
int fault_code,
const char *fault_format,
...) G_GNUC_PRINTF (3, 4);
/* Utils */
SOUP_AVAILABLE_IN_2_52
GVariant *soup_xmlrpc_variant_new_datetime (SoupDate *date);
SOUP_AVAILABLE_IN_2_52
SoupDate *soup_xmlrpc_variant_get_datetime (GVariant *variant,
GError **error);
/* Errors */
#define SOUP_XMLRPC_ERROR soup_xmlrpc_error_quark()
SOUP_AVAILABLE_IN_2_4
GQuark soup_xmlrpc_error_quark (void);
typedef enum {
SOUP_XMLRPC_ERROR_ARGUMENTS,
SOUP_XMLRPC_ERROR_RETVAL
} SoupXMLRPCError;
#define SOUP_XMLRPC_FAULT soup_xmlrpc_fault_quark()
SOUP_AVAILABLE_IN_2_4
GQuark soup_xmlrpc_fault_quark (void);
typedef enum {
SOUP_XMLRPC_FAULT_PARSE_ERROR_NOT_WELL_FORMED = -32700,
SOUP_XMLRPC_FAULT_PARSE_ERROR_UNSUPPORTED_ENCODING = -32701,
SOUP_XMLRPC_FAULT_PARSE_ERROR_INVALID_CHARACTER_FOR_ENCODING = -32702,
SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_XML_RPC = -32600,
SOUP_XMLRPC_FAULT_SERVER_ERROR_REQUESTED_METHOD_NOT_FOUND = -32601,
SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS = -32602,
SOUP_XMLRPC_FAULT_SERVER_ERROR_INTERNAL_XML_RPC_ERROR = -32603,
SOUP_XMLRPC_FAULT_APPLICATION_ERROR = -32500,
SOUP_XMLRPC_FAULT_SYSTEM_ERROR = -32400,
SOUP_XMLRPC_FAULT_TRANSPORT_ERROR = -32300
} SoupXMLRPCFault;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SoupXMLRPCParams, soup_xmlrpc_params_free)
G_END_DECLS
......@@ -266,28 +266,7 @@ if have_apache
endif
endif
have_php = false
have_php_xmlrpc = false
if have_apache
php = find_program('php', required : false)
message(cdata.get('APACHE_PHP_MODULE_FILE'))
if php.found() and cdata.get('APACHE_PHP_MODULE_FILE') != ''
have_php = true
php_xmlrpc = run_command(php, '-d', 'extension=xmlrpc', '-r', 'exit(function_exists("xmlrpc_server_create")?0:1);')
if php_xmlrpc.returncode() == 0
message('php-xmlrpc found')
have_php_xmlrpc = true
cdata.set('HAVE_PHP_XMLRPC', '1')
else
message('php-xmlrpc not found')
endif
endif
cdata.set('IF_HAVE_PHP', have_php ? '' : '#')
cdata.set('IF_HAVE_PHP_XMLRPC', have_php_xmlrpc ? '' : ';')
endif
tests_ready = have_apache and have_php and have_php_xmlrpc
if not tests_ready
if not have_apache
warning('Some regression tests will not be compiled due to missing libraries or modules. Please check the logs for more details.')
endif
......
......@@ -24,15 +24,12 @@ LoadModule authz_host_module @APACHE_MODULE_DIR@/mod_authz_host.so
LoadModule authz_user_module @APACHE_MODULE_DIR@/mod_authz_user.so
LoadModule dir_module @APACHE_MODULE_DIR@/mod_dir.so
LoadModule mime_module @APACHE_MODULE_DIR@/mod_mime.so
@IF_HAVE_PHP@LoadModule php7_module @APACHE_PHP_MODULE_FILE@
LoadModule proxy_module @APACHE_MODULE_DIR@/mod_proxy.so
LoadModule proxy_http_module @APACHE_MODULE_DIR@/mod_proxy_http.so
LoadModule proxy_connect_module @APACHE_MODULE_DIR@/mod_proxy_connect.so
LoadModule ssl_module @APACHE_SSL_MODULE_DIR@/mod_ssl.so
@IF_HAVE_MOD_UNIXD@LoadModule unixd_module @APACHE_SSL_MODULE_DIR@/mod_unixd.so
@IF_HAVE_PHP@PHPIniDir .
DirectoryIndex index.txt
TypesConfig /dev/null
AddType application/x-httpd-php .php
......
......@@ -122,33 +122,6 @@ if have_apache
endif
endif
if have_php
configure_file(output : 'php.ini',
input : 'php.ini.in',
configuration : cdata,
install : installed_tests_enabled,
install_dir : installed_tests_execdir,
)
endif
if have_php_xmlrpc
tests += [
['xmlrpc-server', true, []],
['xmlrpc', false, []]
]
configure_file(input : 'xmlrpc-server.php',
output : 'xmlrpc-server.php',
copy : true)
if installed_tests_enabled
install_data(
'xmlrpc-server.php',
install_dir : installed_tests_execdir,
)
endif
endif
env = environment()
env.set('G_TEST_SRCDIR', meson.current_source_dir())
env.set('G_TEST_BUILDDIR', meson.current_build_dir())
......
@IF_HAVE_PHP_XMLRPC@extension=xmlrpc
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright 2008 Red Hat, Inc.
* Copyright 2015, Collabora ltd.
*/
#include "test-utils.h"
static char *uri;
static GVariant *
parse_params (SoupMessage *msg, SoupXMLRPCParams *params, const char *signature)
{
GVariant *args;
GError *error = NULL;
args = soup_xmlrpc_params_parse (params, signature, &error);
if (!args) {
soup_xmlrpc_message_set_fault (msg,
SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS,
"Wrong method signature: expected %s: %s",
signature, error->message);
}
return args;
}
static void
do_sum (SoupMessage *msg, SoupXMLRPCParams *params)
{
GVariant *args;
GVariant *child;
GVariantIter iter;
double sum = 0.0, val;
if (!(args = parse_params (msg, params, "(ad)")))
return;
child = g_variant_get_child_value (args, 0);
g_variant_iter_init (&iter, child);
while (g_variant_iter_loop (&iter, "d", &val))
sum += val;
soup_xmlrpc_message_set_response (msg, g_variant_new_double (sum), NULL);
g_variant_unref (args);
g_variant_unref (child);
}
static void
do_countBools (SoupMessage *msg, SoupXMLRPCParams *params)
{
GVariant *args;
GVariant *child;
GVariantIter iter;
gboolean val;
int trues = 0, falses = 0;
GVariantDict dict;
if (!(args = parse_params (msg, params, "(ab)")))
return;
child = g_variant_get_child_value (args, 0);
g_variant_iter_init (&iter, child);
while (g_variant_iter_loop (&iter, "b", &val)) {
if (val)
trues++;
else
falses++;
}
g_variant_dict_init (&dict, NULL);
g_variant_dict_insert (&dict, "true", "i", trues);
g_variant_dict_insert (&dict, "false", "i", falses);
soup_xmlrpc_message_set_response (msg, g_variant_dict_end (&dict), NULL);
g_variant_unref (args);
g_variant_unref (child);
}
static void
do_md5sum (SoupMessage *msg, SoupXMLRPCParams *params)
{
GVariant *args;
GVariant *child;
GChecksum *checksum;
GByteArray *digest;
gsize digest_len = 16;
if (!(args = parse_params (msg, params, "(ay)")))
return;
child = g_variant_get_child_value (args, 0);
checksum = g_checksum_new (G_CHECKSUM_MD5);
g_checksum_update (checksum,
g_variant_get_data (child),
g_variant_get_size (child));
digest = g_byte_array_new ();
g_byte_array_set_size (digest, digest_len);
g_checksum_get_digest (checksum, digest->data, &digest_len);
g_checksum_free (checksum);
soup_xmlrpc_message_set_response (msg,
g_variant_new_from_data (G_VARIANT_TYPE_BYTESTRING,
digest->data, digest_len,
TRUE, NULL, NULL),
NULL);
g_byte_array_free (digest, TRUE);
g_variant_unref (child);
g_variant_unref (args);
}
static void
do_dateChange (SoupMessage *msg, SoupXMLRPCParams *params)
{
GVariant *args;
GVariant *timestamp;
SoupDate *date;
GVariant *arg;
int val;
GError *error = NULL;
if (!(args = parse_params (msg, params, "(va{si})")))
return;
g_variant_get (args, "(v@a{si})", &timestamp, &arg);
date = soup_xmlrpc_variant_get_datetime (timestamp, &error);
if (!date) {
soup_xmlrpc_message_set_fault (msg,
SOUP_XMLRPC_FAULT_SERVER_ERROR_INVALID_METHOD_PARAMETERS,
"%s", error->message);
g_clear_error (&error);
goto fail;
}
if (g_variant_lookup (arg, "tm_year", "i", &val))
date->year = val + 1900;
if (g_variant_lookup (arg, "tm_mon", "i", &val))
date->month = val + 1;
if (g_variant_lookup (arg, "tm_mday", "i", &val))
date->day = val;
if (g_variant_lookup (arg, "tm_hour", "i", &val))
date->hour = val;
if (g_variant_lookup (arg, "tm_min", "i", &val))
date->minute = val;
if (g_variant_lookup (arg, "tm_sec", "i", &val))
date->second = val;
soup_xmlrpc_message_set_response (msg,
soup_xmlrpc_variant_new_datetime (date),
NULL);
soup_date_free (date);
fail:
g_variant_unref (args);
g_variant_unref (arg);
g_variant_unref (timestamp);
}
static void
do_echo (SoupMessage *msg, SoupXMLRPCParams *params)
{
GVariant *args;
GVariant *child;
if (!(args = parse_params (msg, params, "(as)")))
return;
child = g_variant_get_child_value (args, 0);
soup_xmlrpc_message_set_response (msg, child, NULL);
g_variant_unref (args);
g_variant_unref (child);
}
static void
do_ping (SoupMessage *msg, SoupXMLRPCParams *params)
{
GVariant *args;
if (!(args = parse_params (msg, params, "()")))
return;
soup_xmlrpc_message_set_response (msg, g_variant_new_string ("pong"), NULL);
g_variant_unref (args);
}
static void
server_callback (SoupServer *server, SoupMessage *msg,
const char *path, GHashTable *query,
SoupClientContext *context, gpointer data)
{
char *method_name;
SoupXMLRPCParams *params;
GError *error = NULL;
if (msg->method != SOUP_METHOD_POST) {
soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
return;
}
soup_message_set_status (msg, SOUP_STATUS_OK);
method_name = soup_xmlrpc_parse_request (msg->request_body->data,
msg->request_body->length,
&params, &error);
if (!method_name) {
soup_xmlrpc_message_set_fault (msg, SOUP_XMLRPC_FAULT_PARSE_ERROR_NOT_WELL_FORMED,
"Could not parse method call: %s", error->message);
g_clear_error (&error);
return;
}
if (!strcmp (method_name, "sum"))
do_sum (msg, params);
else if (!strcmp (method_name, "countBools"))
do_countBools (msg, params);
else if (!strcmp (method_name, "md5sum"))
do_md5sum (msg, params);
else if (!strcmp (method_name, "dateChange"))
do_dateChange (msg, params);
else if (!strcmp (method_name, "echo"))
do_echo (msg, params);
else if (!strcmp (method_name, "ping"))
do_ping (msg, params);
else {
soup_xmlrpc_message_set_fault (msg, SOUP_XMLRPC_FAULT_SERVER_ERROR_REQUESTED_METHOD_NOT_FOUND,
"Unknown method %s", method_name);
}
g_free (method_name);
soup_xmlrpc_params_free (params);
}
static gboolean
run_xmlrpc_test (char **argv,
char **stdout_out,
char **stderr_out,
GError **error)
{
gboolean ok;
int status;
argv[0] = g_test_build_filename (G_TEST_BUILT, "xmlrpc-test", NULL);
ok = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL,
stdout_out, stderr_out, &status,
error);
g_free (argv[0]);
if (!ok)
return FALSE;
return g_spawn_check_exit_status (status, error);
}
static void
do_one_xmlrpc_test (gconstpointer data)
{
const char *path = data;
char *argv[12];
char *stdout_out, *stderr_out;
GError *error = NULL;
int arg;
argv[0] = NULL;
argv[1] = "-S";
argv[2] = "-U";
argv[3] = uri;
argv[4] = "-q";
argv[5] = "-p";
argv[6] = (char *) path;
for (arg = 0; arg < debug_level && arg < 3; arg++)
argv[arg + 7] = "-d";
argv[arg + 7] = NULL;
run_xmlrpc_test (argv, &stdout_out, &stderr_out, &error);
if (stdout_out) {
g_print ("%s", stdout_out);
g_free (stdout_out);
}
if (stderr_out) {
g_printerr ("%s", stderr_out);
g_free (stderr_out);
}
if ( g_error_matches (error, G_SPAWN_EXIT_ERROR, 1)
|| g_error_matches (error, G_SPAWN_EXIT_ERROR, 77))
g_test_fail ();
else
g_assert_no_error (error);
g_clear_error (&error);
}
gboolean run_tests = TRUE;
static GOptionEntry no_test_entry[] = {
{ "no-tests", 'n', G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &run_tests,
"Don't run tests, just run the test server", NULL },
{ NULL }
};
int