summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/redirect-test.c191
-rw-r--r--tests/requester-test.c137
2 files changed, 303 insertions, 25 deletions
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index aa1fb544..cf294c4d 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -10,7 +10,11 @@
#include <string.h>
#include <glib.h>
+
+#define LIBSOUP_USE_UNSTABLE_REQUEST_API
#include <libsoup/soup.h>
+#include <libsoup/soup-requester.h>
+#include <libsoup/soup-request-http.h>
#include "test-utils.h"
@@ -26,6 +30,7 @@ typedef struct {
static struct {
TestRequest requests[3];
guint final_status;
+ guint request_api_final_status;
} tests[] = {
/* A redirecty response to a GET or HEAD should cause a redirect */
@@ -110,7 +115,7 @@ static struct {
/* Test behavior with irrecoverably-bad Location header */
{ { { "GET", "/bad-no-host", 302 },
- { NULL } }, SOUP_STATUS_MALFORMED },
+ { NULL } }, SOUP_STATUS_MALFORMED, 302 },
/* Test infinite redirection */
{ { { "GET", "/bad-recursive", 302, TRUE },
@@ -126,7 +131,7 @@ static const int n_tests = G_N_ELEMENTS (tests);
static void
got_headers (SoupMessage *msg, gpointer user_data)
{
- TestRequest **req = user_data;
+ TestRequest **treq = user_data;
const char *location;
debug_printf (2, " -> %d %s\n", msg->status_code,
@@ -136,12 +141,12 @@ got_headers (SoupMessage *msg, gpointer user_data)
if (location)
debug_printf (2, " Location: %s\n", location);
- if (!(*req)->method)
+ if (!(*treq)->method)
return;
- if (msg->status_code != (*req)->status_code) {
+ if (msg->status_code != (*treq)->status_code) {
debug_printf (1, " - Expected %d !\n",
- (*req)->status_code);
+ (*treq)->status_code);
errors++;
}
}
@@ -149,36 +154,36 @@ got_headers (SoupMessage *msg, gpointer user_data)
static void
restarted (SoupMessage *msg, gpointer user_data)
{
- TestRequest **req = user_data;
+ TestRequest **treq = user_data;
SoupURI *uri = soup_message_get_uri (msg);
debug_printf (2, " %s %s\n", msg->method, uri->path);
- if ((*req)->method && !(*req)->repeat)
- (*req)++;
+ if ((*treq)->method && !(*treq)->repeat)
+ (*treq)++;
- if (!(*req)->method) {
+ if (!(*treq)->method) {
debug_printf (1, " - Expected to be done!\n");
errors++;
return;
}
- if (strcmp (msg->method, (*req)->method) != 0) {
- debug_printf (1, " - Expected %s !\n", (*req)->method);
+ if (strcmp (msg->method, (*treq)->method) != 0) {
+ debug_printf (1, " - Expected %s !\n", (*treq)->method);
errors++;
}
- if (strcmp (uri->path, (*req)->path) != 0) {
- debug_printf (1, " - Expected %s !\n", (*req)->path);
+ if (strcmp (uri->path, (*treq)->path) != 0) {
+ debug_printf (1, " - Expected %s !\n", (*treq)->path);
errors++;
}
}
static void
-do_test (SoupSession *session, SoupURI *base_uri, int n)
+do_message_api_test (SoupSession *session, SoupURI *base_uri, int n)
{
SoupURI *uri;
SoupMessage *msg;
- TestRequest *req;
+ TestRequest *treq;
debug_printf (1, "%2d. %s %s\n", n + 1,
tests[n].requests[0].method,
@@ -195,11 +200,11 @@ do_test (SoupSession *session, SoupURI *base_uri, int n)
strlen ("post body"));
}
- req = &tests[n].requests[0];
+ treq = &tests[n].requests[0];
g_signal_connect (msg, "got_headers",
- G_CALLBACK (got_headers), &req);
+ G_CALLBACK (got_headers), &treq);
g_signal_connect (msg, "restarted",
- G_CALLBACK (restarted), &req);
+ G_CALLBACK (restarted), &treq);
soup_session_send_message (session, msg);
@@ -214,21 +219,159 @@ do_test (SoupSession *session, SoupURI *base_uri, int n)
}
static void
+async_callback (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ GAsyncResult **result_p = user_data;
+
+ *result_p = g_object_ref (result);
+}
+
+static void
+do_request_api_test (SoupSession *session, SoupURI *base_uri, int n)
+{
+ SoupRequester *requester = (SoupRequester *)soup_session_get_feature (session, SOUP_TYPE_REQUESTER);
+ SoupURI *uri;
+ SoupRequest *req;
+ SoupMessage *msg;
+ TestRequest *treq;
+ GInputStream *stream;
+ GAsyncResult *result;
+ GError *error = NULL;
+ guint final_status;
+
+ debug_printf (1, "%2d. %s %s\n", n + 1,
+ tests[n].requests[0].method,
+ tests[n].requests[0].path);
+
+ final_status = tests[n].request_api_final_status;
+ if (!final_status)
+ final_status = tests[n].final_status;
+
+ uri = soup_uri_new_with_base (base_uri, tests[n].requests[0].path);
+ req = soup_requester_request_uri (requester, uri, &error);
+ soup_uri_free (uri);
+ if (!req) {
+ debug_printf (1, " could not create request: %s\n",
+ error->message);
+ g_error_free (error);
+ errors++;
+ debug_printf (2, "\n");
+ return;
+ }
+
+ msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (req));
+ g_object_set (G_OBJECT (msg),
+ SOUP_MESSAGE_METHOD, tests[n].requests[0].method,
+ NULL);
+
+ if (msg->method == SOUP_METHOD_POST) {
+ soup_message_set_request (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "post body",
+ strlen ("post body"));
+ }
+
+ treq = &tests[n].requests[0];
+ g_signal_connect (msg, "got_headers",
+ G_CALLBACK (got_headers), &treq);
+ g_signal_connect (msg, "restarted",
+ G_CALLBACK (restarted), &treq);
+
+ if (SOUP_IS_SESSION_SYNC (session)) {
+ stream = soup_request_send (req, NULL, &error);
+ } else {
+ result = NULL;
+ soup_request_send_async (req, NULL, async_callback, &result);
+ while (!result)
+ g_main_context_iteration (NULL, TRUE);
+ stream = soup_request_send_finish (req, result, &error);
+ g_object_unref (result);
+ }
+
+ if (SOUP_STATUS_IS_TRANSPORT_ERROR (final_status)) {
+ if (stream) {
+ debug_printf (1, " expected failure (%s) but succeeded",
+ soup_status_get_phrase (final_status));
+ errors++;
+ g_object_unref (stream);
+ }
+ if (error->domain != SOUP_HTTP_ERROR ||
+ error->code != final_status) {
+ debug_printf (1, " expected '%s' but got '%s'",
+ soup_status_get_phrase (final_status),
+ error->message);
+ errors++;
+ }
+
+ g_error_free (error);
+ g_object_unref (req);
+ debug_printf (2, "\n");
+ return;
+ } else if (!stream) {
+ debug_printf (1, " could not send request: %s\n",
+ error->message);
+ g_error_free (error);
+ g_object_unref (req);
+ errors++;
+ debug_printf (2, "\n");
+ return;
+ }
+
+ if (SOUP_IS_SESSION_SYNC (session)) {
+ g_input_stream_close (stream, NULL, &error);
+ } else {
+ result = NULL;
+ g_input_stream_close_async (stream, G_PRIORITY_DEFAULT,
+ NULL, async_callback, &result);
+ while (!result)
+ g_main_context_iteration (NULL, TRUE);
+ g_input_stream_close_finish (stream, result, &error);
+ g_object_unref (result);
+ }
+ if (error) {
+ debug_printf (1, " could not close stream: %s\n",
+ error->message);
+ g_error_free (error);
+ errors++;
+ }
+
+ if (msg->status_code != final_status) {
+ debug_printf (1, " - Expected final status of %d, got %d !\n",
+ final_status, msg->status_code);
+ errors++;
+ }
+
+ g_object_unref (req);
+ debug_printf (2, "\n");
+}
+
+static void
do_redirect_tests (SoupURI *base_uri)
{
SoupSession *session;
int n;
- session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
- debug_printf (1, "Async session\n");
+ session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+ NULL);
+ debug_printf (1, "Async session, SoupMessage\n");
+ for (n = 0; n < n_tests; n++)
+ do_message_api_test (session, base_uri, n);
+ debug_printf (1, "\nAsync session, SoupRequest\n");
for (n = 0; n < n_tests; n++)
- do_test (session, base_uri, n);
+ do_request_api_test (session, base_uri, n);
soup_test_session_abort_unref (session);
- session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
- debug_printf (1, "\nSync session\n");
+ session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC,
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
+ NULL);
+ debug_printf (1, "\nSync session, SoupMessage\n");
+ for (n = 0; n < n_tests; n++)
+ do_message_api_test (session, base_uri, n);
+ debug_printf (1, "\nSync session, SoupRequest\n");
for (n = 0; n < n_tests; n++)
- do_test (session, base_uri, n);
+ do_request_api_test (session, base_uri, n);
soup_test_session_abort_unref (session);
}
diff --git a/tests/requester-test.c b/tests/requester-test.c
index 0c71d0b2..56c50f37 100644
--- a/tests/requester-test.c
+++ b/tests/requester-test.c
@@ -125,6 +125,7 @@ test_read_ready (GObject *source, GAsyncResult *res, gpointer user_data)
debug_printf (1, " read_async failed: %s", error->message);
g_error_free (error);
errors++;
+ g_input_stream_close (stream, NULL, NULL);
g_object_unref (stream);
g_main_loop_quit (loop);
return;
@@ -325,7 +326,9 @@ do_simple_test (const char *uri)
debug_printf (1, "Simple streaming test\n");
- session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+ session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+ NULL);
do_test_for_thread_and_context (session, uri);
soup_test_session_abort_unref (session);
}
@@ -341,6 +344,7 @@ do_test_with_context (const char *uri)
session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
SOUP_SESSION_ASYNC_CONTEXT, async_context,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
NULL);
do_test_for_thread_and_context (session, uri);
@@ -371,6 +375,135 @@ do_thread_test (const char *uri)
g_thread_join (thread);
}
+static void
+do_sync_request (SoupSession *session, SoupRequest *request,
+ guint expected_status, SoupBuffer *expected_response,
+ gboolean persistent)
+{
+ GInputStream *in;
+ SoupMessage *msg;
+ GError *error = NULL;
+ GString *body;
+ char buf[1024];
+ gssize nread;
+ guint started_id;
+ SoupSocket *socket = NULL;
+
+ started_id = g_signal_connect (session, "request-started",
+ G_CALLBACK (request_started),
+ &socket);
+
+ in = soup_request_send (request, NULL, &error);
+ g_signal_handler_disconnect (session, started_id);
+ if (!in) {
+ debug_printf (1, " soup_request_send failed: %s\n",
+ error->message);
+ g_clear_error (&error);
+ errors++;
+ return;
+ }
+
+ msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (request));
+ if (msg->status_code != expected_status) {
+ debug_printf (1, " GET failed: %d %s", msg->status_code,
+ msg->reason_phrase);
+ errors++;
+ return;
+ }
+ g_object_unref (msg);
+
+ body = g_string_new (NULL);
+ do {
+ nread = g_input_stream_read (in, buf, sizeof (buf),
+ NULL, &error);
+ if (nread == -1) {
+ debug_printf (1, " g_input_stream_read failed: %s\n",
+ error->message);
+ g_clear_error (&error);
+ errors++;
+ break;
+ }
+ g_string_append_len (body, buf, nread);
+ } while (nread > 0);
+
+ if (!g_input_stream_close (in, NULL, &error)) {
+ debug_printf (1, " g_input_stream_close failed: %s\n",
+ error->message);
+ g_clear_error (&error);
+ errors++;
+ }
+ g_object_unref (in);
+
+ if (body->len != expected_response->length) {
+ debug_printf (1, " body length mismatch: expected %d, got %d\n",
+ (int)expected_response->length, (int)body->len);
+ errors++;
+ } else if (memcmp (body->str, expected_response->data, body->len) != 0) {
+ debug_printf (1, " body data mismatch\n");
+ errors++;
+ }
+
+ if (persistent) {
+ if (!soup_socket_is_connected (socket)) {
+ debug_printf (1, " socket not still connected!\n");
+ errors++;
+ }
+ } else {
+ if (soup_socket_is_connected (socket)) {
+ debug_printf (1, " socket still connected!\n");
+ errors++;
+ }
+ }
+ g_object_unref (socket);
+
+ g_string_free (body, TRUE);
+}
+
+static void
+do_sync_test (const char *uri_string)
+{
+ SoupSession *session;
+ SoupRequester *requester;
+ SoupRequest *request;
+ SoupURI *uri;
+
+ debug_printf (1, "Sync streaming\n");
+
+ session = soup_test_session_new (SOUP_TYPE_SESSION_SYNC, NULL);
+ requester = soup_requester_new ();
+ soup_session_add_feature (session, SOUP_SESSION_FEATURE (requester));
+ g_object_unref (requester);
+
+ uri = soup_uri_new (uri_string);
+
+ debug_printf (1, " basic test\n");
+ request = soup_requester_request_uri (requester, uri, NULL);
+ do_sync_request (session, request, SOUP_STATUS_OK, response, TRUE);
+ g_object_unref (request);
+
+ debug_printf (1, " chunked test\n");
+ soup_uri_set_path (uri, "/chunked");
+ request = soup_requester_request_uri (requester, uri, NULL);
+ do_sync_request (session, request, SOUP_STATUS_OK, response, TRUE);
+ g_object_unref (request);
+
+ debug_printf (1, " auth test\n");
+ soup_uri_set_path (uri, "/auth");
+ request = soup_requester_request_uri (requester, uri, NULL);
+ do_sync_request (session, request, SOUP_STATUS_UNAUTHORIZED,
+ auth_response, TRUE);
+ g_object_unref (request);
+
+ debug_printf (1, " non-persistent test\n");
+ soup_uri_set_path (uri, "/non-persistent");
+ request = soup_requester_request_uri (requester, uri, NULL);
+ do_sync_request (session, request, SOUP_STATUS_OK, response, FALSE);
+ g_object_unref (request);
+
+ soup_test_session_abort_unref (session);
+ soup_uri_free (uri);
+}
+
int
main (int argc, char **argv)
{
@@ -387,9 +520,11 @@ main (int argc, char **argv)
do_simple_test (uri);
do_thread_test (uri);
do_context_test (uri);
+ do_sync_test (uri);
g_free (uri);
soup_buffer_free (response);
+ soup_buffer_free (auth_response);
soup_test_server_quit_unref (server);
test_cleanup ();