Blame tests/requester-test.c

Packit Service ca3877
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
Packit Service ca3877
/*
Packit Service ca3877
 * Copyright (C) 2011 Red Hat, Inc.
Packit Service ca3877
 */
Packit Service ca3877
Packit Service ca3877
/* Kill SoupRequester-related deprecation warnings */
Packit Service ca3877
#define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_2_40
Packit Service ca3877
Packit Service ca3877
#include "test-utils.h"
Packit Service ca3877
Packit Service ca3877
SoupServer *server;
Packit Service ca3877
GMainLoop *loop;
Packit Service ca3877
char buf[1024];
Packit Service ca3877
Packit Service ca3877
SoupBuffer *response, *auth_response;
Packit Service ca3877
Packit Service ca3877
#define REDIRECT_HTML_BODY "<html><body>Try again</body></html>\r\n"
Packit Service ca3877
#define AUTH_HTML_BODY "<html><body>Unauthorized</body></html>\r\n"
Packit Service ca3877
Packit Service ca3877
typedef enum {
Packit Service ca3877
	NO_CANCEL,
Packit Service ca3877
	SYNC_CANCEL,
Packit Service ca3877
	PAUSE_AND_CANCEL_ON_IDLE
Packit Service ca3877
} CancelPolicy;
Packit Service ca3877
Packit Service ca3877
static gboolean
Packit Service ca3877
slow_finish_message (gpointer msg)
Packit Service ca3877
{
Packit Service ca3877
	SoupServer *server = g_object_get_data (G_OBJECT (msg), "server");
Packit Service ca3877
Packit Service ca3877
	soup_server_unpause_message (server, msg);
Packit Service ca3877
	return FALSE;
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
slow_pause_message (SoupMessage *msg, gpointer server)
Packit Service ca3877
{
Packit Service ca3877
	soup_server_pause_message (server, msg);
Packit Service ca3877
	soup_add_timeout (soup_server_get_async_context (server),
Packit Service ca3877
			  1000, slow_finish_message, msg);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
server_callback (SoupServer *server, SoupMessage *msg,
Packit Service ca3877
		 const char *path, GHashTable *query,
Packit Service ca3877
		 SoupClientContext *context, gpointer data)
Packit Service ca3877
{
Packit Service ca3877
	gboolean chunked = FALSE;
Packit Service ca3877
	int i;
Packit Service ca3877
Packit Service ca3877
	if (strcmp (path, "/auth") == 0) {
Packit Service ca3877
		soup_message_set_status (msg, SOUP_STATUS_UNAUTHORIZED);
Packit Service ca3877
		soup_message_set_response (msg, "text/html",
Packit Service ca3877
					   SOUP_MEMORY_STATIC,
Packit Service ca3877
					   AUTH_HTML_BODY,
Packit Service ca3877
					   strlen (AUTH_HTML_BODY));
Packit Service ca3877
		soup_message_headers_append (msg->response_headers,
Packit Service ca3877
					     "WWW-Authenticate",
Packit Service ca3877
					     "Basic: realm=\"requester-test\"");
Packit Service ca3877
		return;
Packit Service ca3877
	} else if (strcmp (path, "/foo") == 0) {
Packit Service ca3877
		soup_message_set_redirect (msg, SOUP_STATUS_FOUND, "/");
Packit Service ca3877
		/* Make the response HTML so if we sniff that instead of the
Packit Service ca3877
		 * real body, we'll notice.
Packit Service ca3877
		 */
Packit Service ca3877
		soup_message_set_response (msg, "text/html",
Packit Service ca3877
					   SOUP_MEMORY_STATIC,
Packit Service ca3877
					   REDIRECT_HTML_BODY,
Packit Service ca3877
					   strlen (REDIRECT_HTML_BODY));
Packit Service ca3877
		return;
Packit Service ca3877
	} else if (strcmp (path, "/chunked") == 0) {
Packit Service ca3877
		chunked = TRUE;
Packit Service ca3877
	} else if (strcmp (path, "/non-persistent") == 0) {
Packit Service ca3877
		soup_message_headers_append (msg->response_headers,
Packit Service ca3877
					     "Connection", "close");
Packit Service ca3877
	} else if (!strcmp (path, "/slow")) {
Packit Service ca3877
		g_object_set_data (G_OBJECT (msg), "server", server);
Packit Service ca3877
		g_signal_connect (msg, "wrote-headers",
Packit Service ca3877
				  G_CALLBACK (slow_pause_message), server);
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	soup_message_set_status (msg, SOUP_STATUS_OK);
Packit Service ca3877
Packit Service ca3877
	if (chunked) {
Packit Service ca3877
		soup_message_headers_set_encoding (msg->response_headers,
Packit Service ca3877
						   SOUP_ENCODING_CHUNKED);
Packit Service ca3877
Packit Service ca3877
		for (i = 0; i < response->length; i += 8192) {
Packit Service ca3877
			SoupBuffer *tmp;
Packit Service ca3877
Packit Service ca3877
			tmp = soup_buffer_new_subbuffer (response, i,
Packit Service ca3877
							 MIN (8192, response->length - i));
Packit Service ca3877
			soup_message_body_append_buffer (msg->response_body, tmp);
Packit Service ca3877
			soup_buffer_free (tmp);
Packit Service ca3877
		}
Packit Service ca3877
		soup_message_body_complete (msg->response_body);
Packit Service ca3877
	} else
Packit Service ca3877
		soup_message_body_append_buffer (msg->response_body, response);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
typedef struct {
Packit Service ca3877
	GString *body;
Packit Service ca3877
	gboolean cancel;
Packit Service ca3877
} RequestData;
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
stream_closed (GObject *source, GAsyncResult *res, gpointer user_data)
Packit Service ca3877
{
Packit Service ca3877
	GInputStream *stream = G_INPUT_STREAM (source);
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
Packit Service ca3877
	g_input_stream_close_finish (stream, res, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	g_main_loop_quit (loop);
Packit Service ca3877
	g_object_unref (stream);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
test_read_ready (GObject *source, GAsyncResult *res, gpointer user_data)
Packit Service ca3877
{
Packit Service ca3877
	GInputStream *stream = G_INPUT_STREAM (source);
Packit Service ca3877
	RequestData *data = user_data;
Packit Service ca3877
	GString *body = data->body;
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
	gsize nread;
Packit Service ca3877
Packit Service ca3877
	nread = g_input_stream_read_finish (stream, res, &error);
Packit Service ca3877
	if (nread == -1) {
Packit Service ca3877
		g_assert_no_error (error);
Packit Service ca3877
		g_error_free (error);
Packit Service ca3877
		g_input_stream_close (stream, NULL, NULL);
Packit Service ca3877
		g_object_unref (stream);
Packit Service ca3877
		g_main_loop_quit (loop);
Packit Service ca3877
		return;
Packit Service ca3877
	} else if (nread == 0) {
Packit Service ca3877
		g_input_stream_close_async (stream,
Packit Service ca3877
					    G_PRIORITY_DEFAULT, NULL,
Packit Service ca3877
					    stream_closed, NULL);
Packit Service ca3877
		return;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	g_string_append_len (body, buf, nread);
Packit Service ca3877
	g_input_stream_read_async (stream, buf, sizeof (buf),
Packit Service ca3877
				   G_PRIORITY_DEFAULT, NULL,
Packit Service ca3877
				   test_read_ready, data);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
auth_test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
Packit Service ca3877
{
Packit Service ca3877
	RequestData *data = user_data;
Packit Service ca3877
	GInputStream *stream;
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
	SoupMessage *msg;
Packit Service ca3877
	const char *content_type;
Packit Service ca3877
Packit Service ca3877
	stream = soup_request_send_finish (SOUP_REQUEST (source), res, &error);
Packit Service ca3877
	if (!stream) {
Packit Service ca3877
		g_assert_no_error (error);
Packit Service ca3877
		g_clear_error (&error);
Packit Service ca3877
		g_main_loop_quit (loop);
Packit Service ca3877
		return;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (source));
Packit Service ca3877
	soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
Packit Service ca3877
	g_object_unref (msg);
Packit Service ca3877
Packit Service ca3877
	content_type = soup_request_get_content_type (SOUP_REQUEST (source));
Packit Service ca3877
	g_assert_cmpstr (content_type, ==, "text/html");
Packit Service ca3877
Packit Service ca3877
	g_input_stream_read_async (stream, buf, sizeof (buf),
Packit Service ca3877
				   G_PRIORITY_DEFAULT, NULL,
Packit Service ca3877
				   test_read_ready, data);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
test_sent (GObject *source, GAsyncResult *res, gpointer user_data)
Packit Service ca3877
{
Packit Service ca3877
	RequestData *data = user_data;
Packit Service ca3877
	GInputStream *stream;
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
	const char *content_type;
Packit Service ca3877
Packit Service ca3877
	stream = soup_request_send_finish (SOUP_REQUEST (source), res, &error);
Packit Service ca3877
	if (data->cancel) {
Packit Service ca3877
		g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
Packit Service ca3877
		g_clear_error (&error);
Packit Service ca3877
		g_main_loop_quit (loop);
Packit Service ca3877
		return;
Packit Service ca3877
	} else {
Packit Service ca3877
		g_assert_no_error (error);
Packit Service ca3877
		if (!stream) {
Packit Service ca3877
			g_main_loop_quit (loop);
Packit Service ca3877
			g_clear_error (&error);
Packit Service ca3877
			return;
Packit Service ca3877
		}
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	content_type = soup_request_get_content_type (SOUP_REQUEST (source));
Packit Service ca3877
	g_assert_cmpstr (content_type, ==, "text/plain");
Packit Service ca3877
Packit Service ca3877
	g_input_stream_read_async (stream, buf, sizeof (buf),
Packit Service ca3877
				   G_PRIORITY_DEFAULT, NULL,
Packit Service ca3877
				   test_read_ready, data);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
cancel_message (SoupMessage *msg, gpointer session)
Packit Service ca3877
{
Packit Service ca3877
	soup_session_cancel_message (session, msg, SOUP_STATUS_FORBIDDEN);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
typedef struct {
Packit Service ca3877
	SoupMessage *msg;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
} CancelData;
Packit Service ca3877
Packit Service ca3877
static gboolean
Packit Service ca3877
cancel_message_idle (CancelData *data)
Packit Service ca3877
{
Packit Service ca3877
	cancel_message (data->msg, data->session);
Packit Service ca3877
	return FALSE;
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
pause_and_cancel_message (SoupMessage *msg, gpointer session)
Packit Service ca3877
{
Packit Service ca3877
	CancelData *data = g_new (CancelData, 1);
Packit Service ca3877
	GSource *source = g_idle_source_new ();
Packit Service ca3877
Packit Service ca3877
	soup_session_pause_message (session, msg);
Packit Service ca3877
	data->msg = msg;
Packit Service ca3877
	data->session = session;
Packit Service ca3877
	g_source_set_callback (source, (GSourceFunc)cancel_message_idle, data, g_free);
Packit Service ca3877
	g_source_attach (source, soup_session_get_async_context (session));
Packit Service ca3877
	g_source_unref (source);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
request_started (SoupSession *session, SoupMessage *msg,
Packit Service ca3877
		 SoupSocket *socket, gpointer user_data)
Packit Service ca3877
{
Packit Service ca3877
	SoupSocket **save_socket = user_data;
Packit Service ca3877
Packit Service ca3877
	g_clear_object (save_socket);
Packit Service ca3877
	*save_socket = g_object_ref (socket);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_async_test (SoupSession *session, SoupURI *uri,
Packit Service ca3877
	       GAsyncReadyCallback callback, guint expected_status,
Packit Service ca3877
	       SoupBuffer *expected_response,
Packit Service ca3877
	       gboolean persistent, CancelPolicy cancel_policy)
Packit Service ca3877
{
Packit Service ca3877
	SoupRequester *requester;
Packit Service ca3877
	SoupRequest *request;
Packit Service ca3877
	guint started_id;
Packit Service ca3877
	SoupSocket *socket = NULL;
Packit Service ca3877
	SoupMessage *msg;
Packit Service ca3877
	RequestData data;
Packit Service ca3877
Packit Service ca3877
	if (SOUP_IS_SESSION_ASYNC (session))
Packit Service ca3877
		requester = SOUP_REQUESTER (soup_session_get_feature (session, SOUP_TYPE_REQUESTER));
Packit Service ca3877
	else
Packit Service ca3877
		requester = NULL;
Packit Service ca3877
Packit Service ca3877
	data.body = g_string_new (NULL);
Packit Service ca3877
	data.cancel = cancel_policy != NO_CANCEL;
Packit Service ca3877
	if (requester)
Packit Service ca3877
		request = soup_requester_request_uri (requester, uri, NULL);
Packit Service ca3877
	else
Packit Service ca3877
		request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
Packit Service ca3877
Packit Service ca3877
	switch (cancel_policy) {
Packit Service ca3877
	case SYNC_CANCEL:
Packit Service ca3877
		g_signal_connect (msg, "got-headers",
Packit Service ca3877
				  G_CALLBACK (cancel_message), session);
Packit Service ca3877
		break;
Packit Service ca3877
	case PAUSE_AND_CANCEL_ON_IDLE:
Packit Service ca3877
		g_signal_connect (msg, "got-headers",
Packit Service ca3877
				  G_CALLBACK (pause_and_cancel_message), session);
Packit Service ca3877
		break;
Packit Service ca3877
	case NO_CANCEL:
Packit Service ca3877
		break;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	started_id = g_signal_connect (session, "request-started",
Packit Service ca3877
				       G_CALLBACK (request_started),
Packit Service ca3877
				       &socket);
Packit Service ca3877
Packit Service ca3877
	soup_request_send_async (request, NULL, callback, &data);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
	loop = g_main_loop_new (soup_session_get_async_context (session), TRUE);
Packit Service ca3877
	g_main_loop_run (loop);
Packit Service ca3877
	g_main_loop_unref (loop);
Packit Service ca3877
Packit Service ca3877
	g_signal_handler_disconnect (session, started_id);
Packit Service ca3877
Packit Service ca3877
	soup_test_assert_message_status (msg, expected_status);
Packit Service ca3877
	g_object_unref (msg);
Packit Service ca3877
Packit Service ca3877
	if (expected_response) {
Packit Service ca3877
		soup_assert_cmpmem (data.body->str, data.body->len,
Packit Service ca3877
				    expected_response->data, expected_response->length);
Packit Service ca3877
	} else
Packit Service ca3877
		g_assert_cmpint (data.body->len, ==, 0);
Packit Service ca3877
Packit Service ca3877
	if (persistent)
Packit Service ca3877
		g_assert_true (soup_socket_is_connected (socket));
Packit Service ca3877
	else
Packit Service ca3877
		g_assert_false (soup_socket_is_connected (socket));
Packit Service ca3877
Packit Service ca3877
	g_object_unref (socket);
Packit Service ca3877
Packit Service ca3877
	g_string_free (data.body, TRUE);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_test_for_thread_and_context (SoupSession *session, SoupURI *base_uri)
Packit Service ca3877
{
Packit Service ca3877
	SoupRequester *requester;
Packit Service ca3877
	SoupURI *uri;
Packit Service ca3877
Packit Service ca3877
	if (SOUP_IS_SESSION_ASYNC (session)) {
Packit Service ca3877
		requester = soup_requester_new ();
Packit Service ca3877
		soup_session_add_feature (session, SOUP_SESSION_FEATURE (requester));
Packit Service ca3877
		g_object_unref (requester);
Packit Service ca3877
	}
Packit Service ca3877
	soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_SNIFFER);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    basic test\n");
Packit Service ca3877
	do_async_test (session, base_uri, test_sent,
Packit Service ca3877
		       SOUP_STATUS_OK, response,
Packit Service ca3877
		       TRUE, NO_CANCEL);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    chunked test\n");
Packit Service ca3877
	uri = soup_uri_new_with_base (base_uri, "/chunked");
Packit Service ca3877
	do_async_test (session, uri, test_sent,
Packit Service ca3877
		       SOUP_STATUS_OK, response,
Packit Service ca3877
		       TRUE, NO_CANCEL);
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    auth test\n");
Packit Service ca3877
	uri = soup_uri_new_with_base (base_uri, "/auth");
Packit Service ca3877
	do_async_test (session, uri, auth_test_sent,
Packit Service ca3877
		       SOUP_STATUS_UNAUTHORIZED, auth_response,
Packit Service ca3877
		       TRUE, NO_CANCEL);
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    non-persistent test\n");
Packit Service ca3877
	uri = soup_uri_new_with_base (base_uri, "/non-persistent");
Packit Service ca3877
	do_async_test (session, uri, test_sent,
Packit Service ca3877
		       SOUP_STATUS_OK, response,
Packit Service ca3877
		       FALSE, NO_CANCEL);
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    cancellation test\n");
Packit Service ca3877
	uri = soup_uri_new_with_base (base_uri, "/");
Packit Service ca3877
	do_async_test (session, uri, test_sent,
Packit Service ca3877
		       SOUP_STATUS_FORBIDDEN, NULL,
Packit Service ca3877
		       FALSE, SYNC_CANCEL);
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    cancellation after paused test\n");
Packit Service ca3877
	uri = soup_uri_new_with_base (base_uri, "/");
Packit Service ca3877
	do_async_test (session, uri, test_sent,
Packit Service ca3877
		       SOUP_STATUS_FORBIDDEN, NULL,
Packit Service ca3877
		       FALSE, PAUSE_AND_CANCEL_ON_IDLE);
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_simple_plain_test (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
Packit Service ca3877
	g_test_bug ("653707");
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
Packit Service ca3877
	do_test_for_thread_and_context (session, uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_simple_async_test (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
Packit Service ca3877
	g_test_bug ("653707");
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
Packit Service ca3877
					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
Packit Service ca3877
					 NULL);
Packit Service ca3877
	do_test_for_thread_and_context (session, uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_test_with_context_and_type (SoupURI *uri, gboolean plain_session)
Packit Service ca3877
{
Packit Service ca3877
	GMainContext *async_context;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
Packit Service ca3877
	g_test_bug ("653707");
Packit Service ca3877
Packit Service ca3877
	async_context = g_main_context_new ();
Packit Service ca3877
	g_main_context_push_thread_default (async_context);
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (plain_session ? SOUP_TYPE_SESSION : SOUP_TYPE_SESSION_ASYNC,
Packit Service ca3877
					 SOUP_SESSION_ASYNC_CONTEXT, async_context,
Packit Service ca3877
					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
Packit Service ca3877
					 NULL);
Packit Service ca3877
Packit Service ca3877
	do_test_for_thread_and_context (session, uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
Packit Service ca3877
	g_main_context_pop_thread_default (async_context);
Packit Service ca3877
	g_main_context_unref (async_context);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_async_test_with_context (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
Packit Service ca3877
	do_test_with_context_and_type (uri, FALSE);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_plain_test_with_context (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
Packit Service ca3877
	do_test_with_context_and_type (uri, TRUE);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static gpointer
Packit Service ca3877
async_test_thread (gpointer uri)
Packit Service ca3877
{
Packit Service ca3877
	do_test_with_context_and_type (uri, TRUE);
Packit Service ca3877
	return NULL;
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static gpointer
Packit Service ca3877
plain_test_thread (gpointer uri)
Packit Service ca3877
{
Packit Service ca3877
	do_test_with_context_and_type (uri, FALSE);
Packit Service ca3877
	return NULL;
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_async_test_in_thread (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	GThread *thread;
Packit Service ca3877
Packit Service ca3877
	thread = g_thread_new ("do_async_test_in_thread",
Packit Service ca3877
			       async_test_thread,
Packit Service ca3877
			       (gpointer)uri);
Packit Service ca3877
	g_thread_join (thread);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_plain_test_in_thread (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	GThread *thread;
Packit Service ca3877
Packit Service ca3877
	thread = g_thread_new ("do_plain_test_in_thread",
Packit Service ca3877
			       plain_test_thread,
Packit Service ca3877
			       (gpointer)uri);
Packit Service ca3877
	g_thread_join (thread);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_sync_request (SoupSession *session, SoupRequest *request,
Packit Service ca3877
		 guint expected_status, SoupBuffer *expected_response,
Packit Service ca3877
		 gboolean persistent, CancelPolicy cancel_policy)
Packit Service ca3877
{
Packit Service ca3877
	GInputStream *in;
Packit Service ca3877
	SoupMessage *msg;
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
	GString *body;
Packit Service ca3877
	char buf[1024];
Packit Service ca3877
	gssize nread;
Packit Service ca3877
	guint started_id;
Packit Service ca3877
	SoupSocket *socket = NULL;
Packit Service ca3877
Packit Service ca3877
	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
Packit Service ca3877
	if (cancel_policy == SYNC_CANCEL) {
Packit Service ca3877
		g_signal_connect (msg, "got-headers",
Packit Service ca3877
				  G_CALLBACK (cancel_message), session);
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	started_id = g_signal_connect (session, "request-started",
Packit Service ca3877
				       G_CALLBACK (request_started),
Packit Service ca3877
				       &socket);
Packit Service ca3877
Packit Service ca3877
	in = soup_request_send (request, NULL, &error);
Packit Service ca3877
	g_signal_handler_disconnect (session, started_id);
Packit Service ca3877
	if (cancel_policy == SYNC_CANCEL) {
Packit Service ca3877
		g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
Packit Service ca3877
		g_clear_error (&error);
Packit Service ca3877
		g_object_unref (msg);
Packit Service ca3877
		g_object_unref (socket);
Packit Service ca3877
		return;
Packit Service ca3877
	} else if (!in) {
Packit Service ca3877
		g_assert_no_error (error);
Packit Service ca3877
		g_clear_error (&error);
Packit Service ca3877
		g_object_unref (msg);
Packit Service ca3877
		g_object_unref (socket);
Packit Service ca3877
		return;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	soup_test_assert_message_status (msg, expected_status);
Packit Service ca3877
	g_object_unref (msg);
Packit Service ca3877
Packit Service ca3877
	body = g_string_new (NULL);
Packit Service ca3877
	do {
Packit Service ca3877
		nread = g_input_stream_read (in, buf, sizeof (buf),
Packit Service ca3877
					     NULL, &error);
Packit Service ca3877
		g_assert_no_error (error);
Packit Service ca3877
		if (nread == -1) {
Packit Service ca3877
			g_clear_error (&error);
Packit Service ca3877
			break;
Packit Service ca3877
		}
Packit Service ca3877
		g_string_append_len (body, buf, nread);
Packit Service ca3877
	} while (nread > 0);
Packit Service ca3877
Packit Service ca3877
	g_input_stream_close (in, NULL, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	g_clear_error (&error);
Packit Service ca3877
	g_object_unref (in);
Packit Service ca3877
Packit Service ca3877
	if (expected_response) {
Packit Service ca3877
		soup_assert_cmpmem (body->str, body->len,
Packit Service ca3877
				    expected_response->data, expected_response->length);
Packit Service ca3877
	} else
Packit Service ca3877
		g_assert_cmpint (body->len, ==, 0);
Packit Service ca3877
Packit Service ca3877
	if (persistent)
Packit Service ca3877
		g_assert_true (soup_socket_is_connected (socket));
Packit Service ca3877
	else
Packit Service ca3877
		g_assert_false (soup_socket_is_connected (socket));
Packit Service ca3877
	g_object_unref (socket);
Packit Service ca3877
Packit Service ca3877
	g_string_free (body, TRUE);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_sync_tests_for_session (SoupSession *session, SoupURI *base_uri)
Packit Service ca3877
{
Packit Service ca3877
	SoupRequester *requester;
Packit Service ca3877
	SoupRequest *request;
Packit Service ca3877
	SoupURI *uri;
Packit Service ca3877
Packit Service ca3877
	requester = SOUP_REQUESTER (soup_session_get_feature (session, SOUP_TYPE_REQUESTER));
Packit Service ca3877
Packit Service ca3877
	uri = soup_uri_copy (base_uri);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    basic test\n");
Packit Service ca3877
	if (requester)
Packit Service ca3877
		request = soup_requester_request_uri (requester, uri, NULL);
Packit Service ca3877
	else
Packit Service ca3877
		request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	do_sync_request (session, request,
Packit Service ca3877
			 SOUP_STATUS_OK, response,
Packit Service ca3877
			 TRUE, NO_CANCEL);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    chunked test\n");
Packit Service ca3877
	soup_uri_set_path (uri, "/chunked");
Packit Service ca3877
	if (requester)
Packit Service ca3877
		request = soup_requester_request_uri (requester, uri, NULL);
Packit Service ca3877
	else
Packit Service ca3877
		request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	do_sync_request (session, request,
Packit Service ca3877
			 SOUP_STATUS_OK, response,
Packit Service ca3877
			 TRUE, NO_CANCEL);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    auth test\n");
Packit Service ca3877
	soup_uri_set_path (uri, "/auth");
Packit Service ca3877
	if (requester)
Packit Service ca3877
		request = soup_requester_request_uri (requester, uri, NULL);
Packit Service ca3877
	else
Packit Service ca3877
		request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	do_sync_request (session, request,
Packit Service ca3877
			 SOUP_STATUS_UNAUTHORIZED, auth_response,
Packit Service ca3877
			 TRUE, NO_CANCEL);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    non-persistent test\n");
Packit Service ca3877
	soup_uri_set_path (uri, "/non-persistent");
Packit Service ca3877
	if (requester)
Packit Service ca3877
		request = soup_requester_request_uri (requester, uri, NULL);
Packit Service ca3877
	else
Packit Service ca3877
		request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	do_sync_request (session, request,
Packit Service ca3877
			 SOUP_STATUS_OK, response,
Packit Service ca3877
			 FALSE, NO_CANCEL);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    cancel test\n");
Packit Service ca3877
	soup_uri_set_path (uri, "/");
Packit Service ca3877
	if (requester)
Packit Service ca3877
		request = soup_requester_request_uri (requester, uri, NULL);
Packit Service ca3877
	else
Packit Service ca3877
		request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	do_sync_request (session, request,
Packit Service ca3877
			 SOUP_STATUS_FORBIDDEN, NULL,
Packit Service ca3877
			 TRUE, SYNC_CANCEL);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_plain_sync_test (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
Packit Service ca3877
	do_sync_tests_for_session (session, uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_sync_sync_test (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
	SoupRequester *requester;
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
Packit Service ca3877
	requester = soup_requester_new ();
Packit Service ca3877
	soup_session_add_feature (session, SOUP_SESSION_FEATURE (requester));
Packit Service ca3877
	g_object_unref (requester);
Packit Service ca3877
	do_sync_tests_for_session (session, uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_null_char_request (SoupSession *session, const char *encoded_data,
Packit Service ca3877
		      const char *expected_data, int expected_len)
Packit Service ca3877
{
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
	GInputStream *stream;
Packit Service ca3877
	SoupRequest *request;
Packit Service ca3877
	SoupURI *uri;
Packit Service ca3877
	char *uri_string, buf[256];
Packit Service ca3877
	gsize nread;
Packit Service ca3877
Packit Service ca3877
	uri_string = g_strdup_printf ("data:text/html,%s", encoded_data);
Packit Service ca3877
	uri = soup_uri_new (uri_string);
Packit Service ca3877
	g_free (uri_string);
Packit Service ca3877
Packit Service ca3877
	request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	stream = soup_test_request_send (request, NULL, 0, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	if (error) {
Packit Service ca3877
		g_error_free (error);
Packit Service ca3877
		g_object_unref (request);
Packit Service ca3877
		soup_uri_free (uri);
Packit Service ca3877
		return;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	g_input_stream_read_all (stream, buf, sizeof (buf), &nread, NULL, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	g_clear_error (&error);
Packit Service ca3877
Packit Service ca3877
	soup_test_request_close_stream (request, stream, NULL, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	g_clear_error (&error);
Packit Service ca3877
Packit Service ca3877
	soup_assert_cmpmem (buf, nread, expected_data, expected_len);
Packit Service ca3877
Packit Service ca3877
	g_object_unref (stream);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_null_char_test_for_session (SoupSession *session)
Packit Service ca3877
{
Packit Service ca3877
	static struct {
Packit Service ca3877
		const char *encoded_data;
Packit Service ca3877
		const char *expected_data;
Packit Service ca3877
		int expected_len;
Packit Service ca3877
	} test_cases[] = {
Packit Service ca3877
		{ "%3Cscript%3Ea%3D'%00'%3C%2Fscript%3E", "<script>a='\0'</script>", 22 },
Packit Service ca3877
		{ "%00%3Cscript%3Ea%3D42%3C%2Fscript%3E", "\0<script>a=42</script>", 22 },
Packit Service ca3877
		{ "%3Cscript%3E%00%3Cbr%2F%3E%3C%2Fscript%3E%00", "<script>\0
</script>\0", 24 },
Packit Service ca3877
	};
Packit Service ca3877
	static int num_test_cases = G_N_ELEMENTS(test_cases);
Packit Service ca3877
	int i;
Packit Service ca3877
Packit Service ca3877
	for (i = 0; i < num_test_cases; i++) {
Packit Service ca3877
		do_null_char_request (session, test_cases[i].encoded_data,
Packit Service ca3877
				      test_cases[i].expected_data, test_cases[i].expected_len);
Packit Service ca3877
	}
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_plain_null_char_test (void)
Packit Service ca3877
{
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
Packit Service ca3877
	do_null_char_test_for_session (session);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_async_null_char_test (void)
Packit Service ca3877
{
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
Packit Service ca3877
					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
Packit Service ca3877
					 NULL);
Packit Service ca3877
	do_null_char_test_for_session (session);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
close_test_msg_finished (SoupMessage *msg,
Packit Service ca3877
			 gpointer     user_data)
Packit Service ca3877
{
Packit Service ca3877
	gboolean *finished = user_data;
Packit Service ca3877
Packit Service ca3877
	*finished = TRUE;
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_close_test_for_session (SoupSession *session,
Packit Service ca3877
			   SoupURI     *uri)
Packit Service ca3877
{
Packit Service ca3877
	GError *error = NULL;
Packit Service ca3877
	GInputStream *stream;
Packit Service ca3877
	SoupRequest *request;
Packit Service ca3877
	guint64 start, end;
Packit Service ca3877
	GCancellable *cancellable;
Packit Service ca3877
	SoupMessage *msg;
Packit Service ca3877
	gboolean finished = FALSE;
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    normal close\n");
Packit Service ca3877
Packit Service ca3877
	request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	stream = soup_test_request_send (request, NULL, 0, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	if (error) {
Packit Service ca3877
		g_error_free (error);
Packit Service ca3877
		g_object_unref (request);
Packit Service ca3877
		return;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	start = g_get_monotonic_time ();
Packit Service ca3877
	soup_test_request_close_stream (request, stream, NULL, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	g_clear_error (&error);
Packit Service ca3877
	end = g_get_monotonic_time ();
Packit Service ca3877
Packit Service ca3877
	g_assert_cmpint (end - start, <=, 500000);
Packit Service ca3877
Packit Service ca3877
	g_object_unref (stream);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
Packit Service ca3877
Packit Service ca3877
	debug_printf (1, "    error close\n");
Packit Service ca3877
Packit Service ca3877
	request = soup_session_request_uri (session, uri, NULL);
Packit Service ca3877
	msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
Packit Service ca3877
	g_signal_connect (msg, "finished", G_CALLBACK (close_test_msg_finished), &finished);
Packit Service ca3877
	g_object_unref (msg);
Packit Service ca3877
Packit Service ca3877
	stream = soup_test_request_send (request, NULL, 0, &error);
Packit Service ca3877
	g_assert_no_error (error);
Packit Service ca3877
	if (error) {
Packit Service ca3877
		g_error_free (error);
Packit Service ca3877
		g_object_unref (request);
Packit Service ca3877
		return;
Packit Service ca3877
	}
Packit Service ca3877
Packit Service ca3877
	cancellable = g_cancellable_new ();
Packit Service ca3877
	g_cancellable_cancel (cancellable);
Packit Service ca3877
	soup_test_request_close_stream (request, stream, cancellable, &error);
Packit Service ca3877
	if (error)
Packit Service ca3877
		g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
Packit Service ca3877
	g_clear_error (&error);
Packit Service ca3877
	g_object_unref (cancellable);
Packit Service ca3877
Packit Service ca3877
	g_assert_true (finished);
Packit Service ca3877
Packit Service ca3877
	g_object_unref (stream);
Packit Service ca3877
	g_object_unref (request);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_async_close_test (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
	SoupURI *slow_uri;
Packit Service ca3877
Packit Service ca3877
	g_test_bug ("695652");
Packit Service ca3877
	g_test_bug ("711260");
Packit Service ca3877
Packit Service ca3877
	slow_uri = soup_uri_new_with_base ((SoupURI *)uri, "/slow");
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
Packit Service ca3877
					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
Packit Service ca3877
					 NULL);
Packit Service ca3877
	do_close_test_for_session (session, slow_uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
Packit Service ca3877
	soup_uri_free (slow_uri);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
static void
Packit Service ca3877
do_sync_close_test (gconstpointer data)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri = (SoupURI *)data;
Packit Service ca3877
	SoupSession *session;
Packit Service ca3877
	SoupURI *slow_uri;
Packit Service ca3877
Packit Service ca3877
	g_test_bug ("695652");
Packit Service ca3877
	g_test_bug ("711260");
Packit Service ca3877
Packit Service ca3877
	slow_uri = soup_uri_new_with_base ((SoupURI *)uri, "/slow");
Packit Service ca3877
Packit Service ca3877
	session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
Packit Service ca3877
					 SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
Packit Service ca3877
					 NULL);
Packit Service ca3877
	do_close_test_for_session (session, slow_uri);
Packit Service ca3877
	soup_test_session_abort_unref (session);
Packit Service ca3877
Packit Service ca3877
	soup_uri_free (slow_uri);
Packit Service ca3877
}
Packit Service ca3877
Packit Service ca3877
int
Packit Service ca3877
main (int argc, char **argv)
Packit Service ca3877
{
Packit Service ca3877
	SoupURI *uri;
Packit Service ca3877
	int ret;
Packit Service ca3877
Packit Service ca3877
	test_init (argc, argv, NULL);
Packit Service ca3877
Packit Service ca3877
	response = soup_test_get_index ();
Packit Service ca3877
	auth_response = soup_buffer_new (SOUP_MEMORY_STATIC,
Packit Service ca3877
					 AUTH_HTML_BODY,
Packit Service ca3877
					 strlen (AUTH_HTML_BODY));
Packit Service ca3877
Packit Service ca3877
	server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
Packit Service ca3877
	soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
Packit Service ca3877
Packit Service ca3877
	uri = soup_test_server_get_uri (server, "http", NULL);
Packit Service ca3877
	soup_uri_set_path (uri, "/foo");
Packit Service ca3877
Packit Service ca3877
	g_test_add_data_func ("/requester/simple/SoupSession", uri, do_simple_plain_test);
Packit Service ca3877
	g_test_add_data_func ("/requester/simple/SoupSessionAsync", uri, do_simple_async_test);
Packit Service ca3877
	g_test_add_data_func ("/requester/threaded/SoupSession", uri, do_plain_test_in_thread);
Packit Service ca3877
	g_test_add_data_func ("/requester/threaded/SoupSessionAsync", uri, do_async_test_in_thread);
Packit Service ca3877
	g_test_add_data_func ("/requester/context/SoupSession", uri, do_plain_test_with_context);
Packit Service ca3877
	g_test_add_data_func ("/requester/context/SoupSessionAsync", uri, do_async_test_with_context);
Packit Service ca3877
	g_test_add_data_func ("/requester/sync/SoupSession", uri, do_plain_sync_test);
Packit Service ca3877
	g_test_add_data_func ("/requester/sync/SoupSessionSync", uri, do_sync_sync_test);
Packit Service ca3877
	g_test_add_func ("/requester/null-char/SoupSession", do_plain_null_char_test);
Packit Service ca3877
	g_test_add_func ("/requester/null-char/SoupSessionAsync", do_async_null_char_test);
Packit Service ca3877
	g_test_add_data_func ("/requester/close/SoupSessionAsync", uri, do_async_close_test);
Packit Service ca3877
	g_test_add_data_func ("/requester/close/SoupSessionSync", uri, do_sync_close_test);
Packit Service ca3877
Packit Service ca3877
	ret = g_test_run ();
Packit Service ca3877
Packit Service ca3877
	soup_uri_free (uri);
Packit Service ca3877
	soup_buffer_free (auth_response);
Packit Service ca3877
	soup_test_server_quit_unref (server);
Packit Service ca3877
Packit Service ca3877
	test_cleanup ();
Packit Service ca3877
	return ret;
Packit Service ca3877
}