summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/server-test.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/tests/server-test.c b/tests/server-test.c
index c6ba3ef8..e00af693 100644
--- a/tests/server-test.c
+++ b/tests/server-test.c
@@ -58,6 +58,17 @@ server_add_handler (ServerData *sd,
}
static void
+server_add_early_handler (ServerData *sd,
+ const char *path,
+ SoupServerCallback callback,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ soup_server_add_early_handler (sd->server, path, callback, user_data, destroy);
+ sd->handlers = g_slist_prepend (sd->handlers, g_strdup (path));
+}
+
+static void
server_setup (ServerData *sd, gconstpointer test_data)
{
server_setup_nohandler (sd, test_data);
@@ -854,6 +865,194 @@ do_fail_500_test (ServerData *sd, gconstpointer pause)
soup_test_session_abort_unref (session);
}
+static void
+stream_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer user_data)
+{
+ GChecksum *checksum = user_data;
+
+ g_checksum_update (checksum, (const guchar *)chunk->data, chunk->length);
+}
+
+static void
+stream_got_body (SoupMessage *msg, gpointer user_data)
+{
+ GChecksum *checksum = user_data;
+ const char *md5 = g_checksum_get_string (checksum);
+
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY,
+ md5, strlen (md5));
+ g_checksum_free (checksum);
+}
+
+static void
+early_stream_callback (SoupServer *server, SoupMessage *msg,
+ const char *path, GHashTable *query,
+ SoupClientContext *context, gpointer data)
+{
+ GChecksum *checksum;
+
+ if (msg->method != SOUP_METHOD_POST) {
+ soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
+ return;
+ }
+
+ checksum = g_checksum_new (G_CHECKSUM_MD5);
+ g_signal_connect (msg, "got-chunk",
+ G_CALLBACK (stream_got_chunk), checksum);
+ g_signal_connect (msg, "got-body",
+ G_CALLBACK (stream_got_body), checksum);
+
+ soup_message_body_set_accumulate (msg->request_body, TRUE);
+}
+
+static void
+do_early_stream_test (ServerData *sd, gconstpointer test_data)
+{
+ SoupSession *session;
+ SoupMessage *msg;
+ SoupBuffer *index;
+ char *md5;
+
+ server_add_early_handler (sd, NULL, early_stream_callback, NULL, NULL);
+
+ session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
+
+ msg = soup_message_new_from_uri ("POST", sd->base_uri);
+
+ index = soup_test_get_index ();
+ soup_message_body_append (msg->request_body, SOUP_MEMORY_COPY,
+ index->data, index->length);
+ soup_session_send_message (session, msg);
+
+ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+
+ md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5,
+ (guchar *) index->data, index->length);
+ g_assert_cmpstr (md5, ==, msg->response_body->data);
+ g_free (md5);
+
+ g_object_unref (msg);
+ soup_test_session_abort_unref (session);
+}
+
+static void
+early_respond_callback (SoupServer *server, SoupMessage *msg,
+ const char *path, GHashTable *query,
+ SoupClientContext *context, gpointer data)
+{
+ if (!strcmp (path, "/"))
+ soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+}
+
+static void
+do_early_respond_test (ServerData *sd, gconstpointer test_data)
+{
+ SoupSession *session;
+ SoupMessage *msg;
+ SoupURI *uri2;
+
+ server_add_early_handler (sd, NULL, early_respond_callback, NULL, NULL);
+
+ session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
+
+ /* The early handler will intercept, and the normal handler will be skipped */
+ msg = soup_message_new_from_uri ("GET", sd->base_uri);
+ soup_session_send_message (session, msg);
+ soup_test_assert_message_status (msg, SOUP_STATUS_FORBIDDEN);
+ g_assert_cmpint (msg->response_body->length, ==, 0);
+ g_object_unref (msg);
+
+ /* The early handler will ignore this one */
+ uri2 = soup_uri_new_with_base (sd->base_uri, "/subdir");
+ msg = soup_message_new_from_uri ("GET", uri2);
+ soup_session_send_message (session, msg);
+ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+ g_assert_cmpstr (msg->response_body->data, ==, "index");
+ g_object_unref (msg);
+ soup_uri_free (uri2);
+
+ soup_test_session_abort_unref (session);
+}
+
+static void
+early_multi_callback (SoupServer *server, SoupMessage *msg,
+ const char *path, GHashTable *query,
+ SoupClientContext *context, gpointer data)
+{
+ soup_message_headers_append (msg->response_headers, "X-Early", "yes");
+}
+
+static void
+do_early_multi_test (ServerData *sd, gconstpointer test_data)
+{
+ SoupSession *session;
+ SoupMessage *msg;
+ SoupURI *uri;
+ struct {
+ const char *path;
+ gboolean expect_normal, expect_early;
+ } multi_tests[] = {
+ { "/", FALSE, FALSE },
+ { "/normal", TRUE, FALSE },
+ { "/normal/subdir", TRUE, FALSE },
+ { "/normal/early", FALSE, TRUE },
+ { "/normal/early/subdir", FALSE, TRUE },
+ { "/early", FALSE, TRUE },
+ { "/early/subdir", FALSE, TRUE },
+ { "/early/normal", TRUE, FALSE },
+ { "/early/normal/subdir", TRUE, FALSE },
+ { "/both", TRUE, TRUE },
+ { "/both/subdir", TRUE, TRUE }
+ };
+ int i;
+ const char *header;
+
+ server_add_handler (sd, "/normal", server_callback, NULL, NULL);
+ server_add_early_handler (sd, "/normal/early", early_multi_callback, NULL, NULL);
+ server_add_early_handler (sd, "/early", early_multi_callback, NULL, NULL);
+ server_add_handler (sd, "/early/normal", server_callback, NULL, NULL);
+ server_add_handler (sd, "/both", server_callback, NULL, NULL);
+ server_add_early_handler (sd, "/both", early_multi_callback, NULL, NULL);
+
+ session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
+
+ for (i = 0; i < G_N_ELEMENTS (multi_tests); i++) {
+ uri = soup_uri_new_with_base (sd->base_uri, multi_tests[i].path);
+ msg = soup_message_new_from_uri ("GET", uri);
+ soup_uri_free (uri);
+
+ soup_session_send_message (session, msg);
+
+ /* The normal handler sets status to OK. The early handler doesn't
+ * touch status, meaning that if it runs and the normal handler doesn't,
+ * then SoupServer will set the status to INTERNAL_SERVER_ERROR
+ * (since a handler ran, but didn't set the status). If neither handler
+ * runs then SoupServer will set the status to NOT_FOUND.
+ */
+ if (multi_tests[i].expect_normal)
+ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+ else if (multi_tests[i].expect_early)
+ soup_test_assert_message_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ else
+ soup_test_assert_message_status (msg, SOUP_STATUS_NOT_FOUND);
+
+ header = soup_message_headers_get_one (msg->response_headers, "X-Early");
+ if (multi_tests[i].expect_early)
+ g_assert_cmpstr (header, ==, "yes");
+ else
+ g_assert_cmpstr (header, ==, NULL);
+ if (multi_tests[i].expect_normal)
+ g_assert_cmpstr (msg->response_body->data, ==, "index");
+ else
+ g_assert_cmpint (msg->response_body->length, ==, 0);
+
+ g_object_unref (msg);
+ }
+
+ soup_test_session_abort_unref (session);
+}
+
int
main (int argc, char **argv)
{
@@ -884,6 +1083,12 @@ main (int argc, char **argv)
server_setup_nohandler, do_fail_500_test, server_teardown);
g_test_add ("/server/fail/500-pause", ServerData, GINT_TO_POINTER (TRUE),
server_setup_nohandler, do_fail_500_test, server_teardown);
+ g_test_add ("/server/early/stream", ServerData, NULL,
+ server_setup_nohandler, do_early_stream_test, server_teardown);
+ g_test_add ("/server/early/respond", ServerData, NULL,
+ server_setup, do_early_respond_test, server_teardown);
+ g_test_add ("/server/early/multi", ServerData, NULL,
+ server_setup_nohandler, do_early_multi_test, server_teardown);
ret = g_test_run ();