Commit b0cda4e0 authored by Philip Withnall's avatar Philip Withnall

lib: Add a uhm_server_set_expected_domain_names() convenience function

This makes setting up the records in a UhmResolver a lot easier: instead
of connecting to notify::resolver on the UhmServer, and then calling
uhm_resolver_add_A() for each expected domain, now it’s just necessary
to call uhm_server_set_expected_domain_names().
parent 3109d7c4
......@@ -33,6 +33,7 @@ uhm_server_set_trace_directory
......@@ -18,6 +18,7 @@ uhm_server_set_enable_logging
......@@ -65,6 +65,7 @@ uhm_server_error_quark (void)
static void uhm_server_dispose (GObject *object);
static void uhm_server_finalize (GObject *object);
static void uhm_server_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void uhm_server_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
......@@ -78,6 +79,8 @@ static void load_file_iteration_thread_cb (GTask *task, gpointer source_object,
static GFileInputStream *load_file_stream (GFile *trace_file, GCancellable *cancellable, GError **error);
static SoupMessage *load_file_iteration (GFileInputStream *input_stream, SoupURI *base_uri, GCancellable *cancellable, GError **error);
static void apply_expected_domain_names (UhmServer *self);
struct _UhmServerPrivate {
/* UhmServer is based around HTTP/HTTPS, and cannot be extended to support other application-layer protocols.
* If libuhttpmock is extended to support other protocols (e.g. IMAP) in future, a new UhmImapServer should be
......@@ -94,6 +97,9 @@ struct _UhmServerPrivate {
SoupAddress *address; /* unowned */
guint port;
/* Expected resolver domain names. */
gchar **expected_domain_names;
GFile *trace_file;
GFileInputStream *input_stream;
GFileOutputStream *output_stream;
......@@ -144,6 +150,7 @@ uhm_server_class_init (UhmServerClass *klass)
gobject_class->get_property = uhm_server_get_property;
gobject_class->set_property = uhm_server_set_property;
gobject_class->dispose = uhm_server_dispose;
gobject_class->finalize = uhm_server_finalize;
klass->handle_message = real_handle_message;
klass->compare_messages = real_compare_messages;
......@@ -338,6 +345,17 @@ uhm_server_dispose (GObject *object)
G_OBJECT_CLASS (uhm_server_parent_class)->dispose (object);
static void
uhm_server_finalize (GObject *object)
UhmServerPrivate *priv = UHM_SERVER (object)->priv;
g_strfreev (priv->expected_domain_names);
/* Chain up to the parent class */
G_OBJECT_CLASS (uhm_server_parent_class)->finalize (object);
static void
uhm_server_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
......@@ -1310,10 +1328,13 @@ uhm_server_run (UhmServer *self)
/* Set up the resolver. It is expected that callers will grab the resolver (by calling uhm_server_get_resolver())
* immediately after this function returns, and add some expected hostnames by calling uhm_resolver_add_A() one or
* more times, before starting the next test. */
* more times, before starting the next test.Or they could call uhm_server_set_expected_domain_names() any time. */
priv->resolver = uhm_resolver_new ();
g_resolver_set_default (G_RESOLVER (priv->resolver));
/* Note: This must be called before notify::resolver, so the user can add extra domain names in that callback if desired. */
apply_expected_domain_names (self);
g_object_freeze_notify (G_OBJECT (self));
g_object_notify (G_OBJECT (self), "address");
g_object_notify (G_OBJECT (self), "port");
......@@ -1908,3 +1929,59 @@ uhm_server_set_default_tls_certificate (UhmServer *self)
return cert;
static void
apply_expected_domain_names (UhmServer *self)
UhmServerPrivate *priv = self->priv;
const gchar *ip_address;
guint i;
if (priv->resolver == NULL) {
uhm_resolver_reset (priv->resolver);
if (priv->expected_domain_names == NULL) {
ip_address = uhm_server_get_address (self);
g_assert (ip_address != NULL);
for (i = 0; priv->expected_domain_names[i] != NULL; i++) {
uhm_resolver_add_A (priv->resolver, priv->expected_domain_names[i], ip_address);
* uhm_server_set_expected_domain_names:
* @self: a #UhmServer
* @domain_names: (array zero-terminated=1) (allow-none) (element-type utf8): %NULL-terminated array of domain names to expect, or %NULL to not expect any
* Set the domain names which are expected to have requests made of them by the client code interacting with this #UhmServer.
* This is a convenience method which calls uhm_resolver_add_A() on the server’s #UhmResolver for each of the domain names
* listed in @domain_names. It associates them with the server’s current IP address, and automatically updates the mappings
* if the IP address or resolver change.
* Note that this will reset all records on the server’s #UhmResolver, replacing all of them with the provided @domain_names.
* It is safe to add further domain names to the #UhmResolver in a callback for the #GObject::notify signal for #UhmServer:resolver;
* that signal is emitted after the resolver is cleared and these @domain_names are added.
uhm_server_set_expected_domain_names (UhmServer *self, const gchar * const *domain_names)
gchar **new_domain_names;
g_return_if_fail (UHM_IS_SERVER (self));
new_domain_names = g_strdupv ((gchar **) domain_names); /* may be NULL */
g_strfreev (self->priv->expected_domain_names);
self->priv->expected_domain_names = new_domain_names;
apply_expected_domain_names (self);
......@@ -124,6 +124,8 @@ void uhm_server_set_tls_certificate (UhmServer *self, GTlsCertificate *tls_certi
GTlsCertificate *uhm_server_set_default_tls_certificate (UhmServer *self) G_GNUC_MALLOC;
void uhm_server_set_expected_domain_names (UhmServer *self, const gchar * const *domain_names);
#endif /* !UHM_SERVER_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment