UhmServer

UhmServer — mock HTTP(S) server

Stability Level

Unstable, unless otherwise indicated

Synopsis

#include <libuhttpmock/uhm-server.h>

                    UhmServer;
                    UhmServerClass;
enum                UhmServerError;
UhmServer *         uhm_server_new                      (void);
void                uhm_server_run                      (UhmServer *self);
void                uhm_server_stop                     (UhmServer *self);
void                uhm_server_start_trace              (UhmServer *self,
                                                         const gchar *trace_name,
                                                         GError **error);
void                uhm_server_start_trace_full         (UhmServer *self,
                                                         GFile *trace_file,
                                                         GError **error);
void                uhm_server_end_trace                (UhmServer *self);
void                uhm_server_load_trace               (UhmServer *self,
                                                         GFile *trace_file,
                                                         GCancellable *cancellable,
                                                         GError **error);
void                uhm_server_load_trace_async         (UhmServer *self,
                                                         GFile *trace_file,
                                                         GCancellable *cancellable,
                                                         GAsyncReadyCallback callback,
                                                         gpointer user_data);
void                uhm_server_load_trace_finish        (UhmServer *self,
                                                         GAsyncResult *result,
                                                         GError **error);
void                uhm_server_unload_trace             (UhmServer *self);
void                uhm_server_received_message_chunk   (UhmServer *self,
                                                         const gchar *message_chunk,
                                                         goffset message_chunk_length,
                                                         GError **error);
void                uhm_server_received_message_chunk_with_direction
                                                        (UhmServer *self,
                                                         char direction,
                                                         const gchar *data,
                                                         goffset data_length,
                                                         GError **error);
void                uhm_server_received_message_chunk_from_soup
                                                        (SoupLogger *logger,
                                                         SoupLoggerLogLevel level,
                                                         char direction,
                                                         const char *data,
                                                         gpointer user_data);
gboolean            uhm_server_get_enable_logging       (UhmServer *self);
void                uhm_server_set_enable_logging       (UhmServer *self,
                                                         gboolean enable_logging);
gboolean            uhm_server_get_enable_online        (UhmServer *self);
void                uhm_server_set_enable_online        (UhmServer *self,
                                                         gboolean enable_online);
GFile *             uhm_server_get_trace_directory      (UhmServer *self);
void                uhm_server_set_trace_directory      (UhmServer *self,
                                                         GFile *trace_directory);
GTlsCertificate *   uhm_server_get_tls_certificate      (UhmServer *self);
void                uhm_server_set_tls_certificate      (UhmServer *self,
                                                         GTlsCertificate *tls_certificate);
GTlsCertificate *   uhm_server_set_default_tls_certificate
                                                        (UhmServer *self);
void                uhm_server_set_expected_domain_names
                                                        (UhmServer *self,
                                                         const gchar * const *domain_names);
const gchar *       uhm_server_get_address              (UhmServer *self);
guint               uhm_server_get_port                 (UhmServer *self);
UhmResolver *       uhm_server_get_resolver             (UhmServer *self);

Object Hierarchy

  GObject
   +----UhmServer

Properties

  "address"                  gchar*                : Read
  "enable-logging"           gboolean              : Read / Write
  "enable-online"            gboolean              : Read / Write
  "port"                     guint                 : Read
  "resolver"                 UhmResolver*          : Read
  "tls-certificate"          GTlsCertificate*      : Read / Write
  "trace-directory"          GFile*                : Read / Write

Signals

  "compare-messages"                               : Run Last
  "handle-message"                                 : Run Last

Description

This is a mock HTTPS server which can be used to run unit tests of network client code on a loopback interface rather than on the real Internet. At its core, it's a simple HTTPS server which runs on a loopback address on an arbitrary port. The code under test must be modified to send its requests to this port, although UhmResolver may be used to transparently redirect all IP addresses to the mock server. A convenience layer on the mock server provides loading of and recording to trace files, which are sequences of request–response HTTPS message pairs where each request is expected by the server (in order). On receiving an expected request, the mock server will return the relevant response and move to expecting the next request in the trace file.

The mock server currently only operates on a single network interface, on HTTPS only. This may change in future. A dummy TLS certificate is used to authenticate the server. This certificate is not signed by a CA, so the "ssl-strict" property must be set to FALSE in client code during (and only during!) testing.

The server can operate in three modes: logging, testing, and comparing. These are set by "enable-logging" and "enable-online". • Logging mode ("enable-logging": TRUE, "enable-online": TRUE): Requests are sent to the real server online, and the request–response pairs recorded to a log file. • Testing mode ("enable-logging": FALSE, "enable-online": FALSE): Requests are sent to the mock server, which responds from the trace file. • Comparing mode ("enable-logging": FALSE, "enable-online": TRUE): Requests are sent to the real server online, and the request–response pairs are compared against those in an existing log file to see if the log file is up-to-date.

Details

UhmServer

typedef struct _UhmServer UhmServer;

All the fields in the UhmServer structure are private and should never be accessed directly.

Since 0.1.0


UhmServerClass

typedef struct {
	gboolean (*handle_message) (UhmServer *self, SoupMessage *message, SoupClientContext *client);
	gboolean (*compare_messages) (UhmServer *self, SoupMessage *expected_message, SoupMessage *actual_message, SoupClientContext *actual_client);
} UhmServerClass;

Most of the fields in the UhmServerClass structure are private and should never be accessed directly.

handle_message ()

Class handler for the "handle-message" signal. Subclasses may implement this to override the default handler for the signal. The default handler should always return TRUE to indicate that it has handled the message from client by setting an appropriate response on the SoupMessage.

compare_messages ()

Class handler for the "compare-messages" signal. Subclasses may implement this to override the default handler for the signal. The handler should return TRUE if expected_message and actual_message compare equal, and FALSE otherwise.

Since 0.1.0


enum UhmServerError

typedef enum {
	UHM_SERVER_ERROR_MESSAGE_MISMATCH = 1,
} UhmServerError;

Error codes for UhmServer operations.

UHM_SERVER_ERROR_MESSAGE_MISMATCH

In comparison mode, a message received from the client did not match the next message in the current trace file.

uhm_server_new ()

UhmServer *         uhm_server_new                      (void);

Creates a new UhmServer with default properties.

Returns :

a new UhmServer; unref with g_object_unref(). [transfer full]

Since 0.1.0


uhm_server_run ()

void                uhm_server_run                      (UhmServer *self);

Runs the mock server, binding to a loopback TCP/IP interface and preparing a HTTPS server which is ready to accept requests. The TCP/IP address and port number are chosen randomly out of the loopback addresses, and are exposed as "address" and "port" once this function has returned. A UhmResolver (exposed as "resolver") is set as the default GResolver while the server is running.

The server is started in a worker thread, so this function returns immediately and the server continues to run in the background. Use uhm_server_stop() to shut it down.

This function always succeeds.

self :

a UhmServer

Since 0.1.0


uhm_server_stop ()

void                uhm_server_stop                     (UhmServer *self);

Stops a mock server started by calling uhm_server_run(). This shuts down the server's worker thread and unbinds it from its TCP/IP socket.

This unloads any trace file loaded by calling uhm_server_load_trace() (or its asynchronous counterpart). It also resets the set of domain names loaded into the "resolver".

This function always succeeds.

self :

a UhmServer

Since 0.1.0


uhm_server_start_trace ()

void                uhm_server_start_trace              (UhmServer *self,
                                                         const gchar *trace_name,
                                                         GError **error);

Starts a mock server which follows the trace file of filename trace_name in the "trace-directory" directory. See uhm_server_start_trace_full() for further documentation.

This function has undefined behaviour if "trace-directory" is NULL.

On failure, error will be set and the UhmServer state will remain unchanged. See uhm_server_start_trace_full() for details of the error domains used.

self :

a UhmServer

trace_name :

name of the trace

error :

return location for a GError, or NULL. [allow-none]

Since 0.1.0


uhm_server_start_trace_full ()

void                uhm_server_start_trace_full         (UhmServer *self,
                                                         GFile *trace_file,
                                                         GError **error);

Convenience function to start logging to or reading from the given trace_file, depending on the values of "enable-logging" and "enable-online".

If "enable-logging" is TRUE, a log handler will be set up to redirect all client network activity into the given trace_file. If trace_file already exists, it will be overwritten.

If "enable-online" is FALSE, the given trace_file is loaded using uhm_server_load_trace() and then a mock server is started using uhm_server_run().

On failure, error will be set and the UhmServer state will remain unchanged. A GIOError will be set if logging is enabled ("enable-logging") and there is a problem writing to the trace file; or if a trace needs to be loaded and there is a problem reading from the trace file.

self :

a UhmServer

trace_file :

a trace file to load

error :

return location for a GError, or NULL. [allow-none]

Since 0.1.0


uhm_server_end_trace ()

void                uhm_server_end_trace                (UhmServer *self);

Convenience function to finish logging to or reading from a trace file previously passed to uhm_server_start_trace() or uhm_server_start_trace_full().

If "enable-online" is FALSE, this will shut down the mock server (as if uhm_server_stop() had been called).

self :

a UhmServer

Since 0.1.0


uhm_server_load_trace ()

void                uhm_server_load_trace               (UhmServer *self,
                                                         GFile *trace_file,
                                                         GCancellable *cancellable,
                                                         GError **error);

Synchronously loads the given trace_file of network messages, ready to simulate a network conversation by matching requests against the file and returning the associated responses. Call uhm_server_run() to start the mock server afterwards.

Loading the trace file may be cancelled from another thread using cancellable.

On error, error will be set and the state of the UhmServer will not change. A GIOError will be set if there is a problem reading the trace file.

self :

a UhmServer

trace_file :

trace file to load

cancellable :

a GCancellable, or NULL. [allow-none]

error :

return location for a GError, or NULL. [allow-none]

Since 0.1.0


uhm_server_load_trace_async ()

void                uhm_server_load_trace_async         (UhmServer *self,
                                                         GFile *trace_file,
                                                         GCancellable *cancellable,
                                                         GAsyncReadyCallback callback,
                                                         gpointer user_data);

Asynchronous version of uhm_server_load_trace(). In callback, call uhm_server_load_trace_finish() to complete the operation.

self :

a UhmServer

trace_file :

trace file to load

cancellable :

a GCancellable, or NULL. [allow-none]

callback :

function to call once the async operation is complete

user_data :

user data to pass to callback, or NULL. [allow-none]

Since 0.1.0


uhm_server_load_trace_finish ()

void                uhm_server_load_trace_finish        (UhmServer *self,
                                                         GAsyncResult *result,
                                                         GError **error);

Finishes an asynchronous operation started by uhm_server_load_trace_async().

On error, error will be set and the state of the UhmServer will not change. See uhm_server_load_trace() for details on the error domains used.

self :

a UhmServer

result :

asynchronous operation result passed to the callback

error :

return location for a GError, or NULL. [allow-none]

Since 0.1.0


uhm_server_unload_trace ()

void                uhm_server_unload_trace             (UhmServer *self);

Unloads the current trace file of network messages, as loaded by uhm_server_load_trace() or uhm_server_load_trace_async().

self :

a UhmServer

Since 0.1.0


uhm_server_received_message_chunk ()

void                uhm_server_received_message_chunk   (UhmServer *self,
                                                         const gchar *message_chunk,
                                                         goffset message_chunk_length,
                                                         GError **error);

Indicates to the mock server that a single new line of a message was received from the real server. The message line may be appended to the current trace file if logging is enabled ("enable-logging" is TRUE), adding a newline character at the end. If logging is disabled but online mode is enabled ("enable-online" is TRUE), the message line will be compared to the next expected line in the existing trace file. Otherwise, this function is a no-op.

On failure, error will be set and the UhmServer state will remain unchanged apart from the parse state machine, which will remain in the state reached after parsing message_chunk. A G_IO_ERROR will be returned if writing to the trace file failed. If in comparison mode and the received message chunk corresponds to an unexpected message in the trace file, a UHM_SERVER_ERROR will be returned.

Note

In common cases where message log data only needs to be passed to a UhmServer and not (for example) logged to an application-specific file or the command line as well, it is simpler to use uhm_server_received_message_chunk_from_soup(), passing it directly to soup_logger_set_printer(). See the documentation for uhm_server_received_message_chunk_from_soup() for details.

self :

a UhmServer

message_chunk :

single line of a message which was received

message_chunk_length :

length of message_chunk in bytes

error :

return location for a GError, or NULL. [allow-none]

Since 0.1.0


uhm_server_received_message_chunk_with_direction ()

void                uhm_server_received_message_chunk_with_direction
                                                        (UhmServer *self,
                                                         char direction,
                                                         const gchar *data,
                                                         goffset data_length,
                                                         GError **error);

Convenience version of uhm_server_received_message_chunk() which takes the message direction and data separately, as provided by libsoup in a SoupLoggerPrinter callback.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24