diff options
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | docs/reference/libsoup-2.4-sections.txt | 1 | ||||
-rw-r--r-- | libsoup/soup-request-file.c | 12 | ||||
-rw-r--r-- | libsoup/soup-uri.c | 13 | ||||
-rw-r--r-- | libsoup/soup-uri.h | 13 | ||||
-rw-r--r-- | tests/Makefile.am | 29 | ||||
-rw-r--r-- | tests/resource-test.c | 296 | ||||
-rw-r--r-- | tests/soup-tests.gresource.xml | 6 |
8 files changed, 355 insertions, 18 deletions
diff --git a/configure.ac b/configure.ac index f0945875..a6b2b708 100644 --- a/configure.ac +++ b/configure.ac @@ -307,6 +307,9 @@ else fi AM_CONDITIONAL(HAVE_CURL, test "$CURL" != no) +GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0` +AC_SUBST(GLIB_COMPILE_RESOURCES) + AC_SUBST(MISSING_REGRESSION_TEST_PACKAGES) AM_CONDITIONAL(MISSING_REGRESSION_TEST_PACKAGES, test -n "$MISSING_REGRESSION_TEST_PACKAGES") diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt index 6f819c32..961e4163 100644 --- a/docs/reference/libsoup-2.4-sections.txt +++ b/docs/reference/libsoup-2.4-sections.txt @@ -631,6 +631,7 @@ SOUP_URI_SCHEME_HTTPS SOUP_URI_SCHEME_DATA SOUP_URI_SCHEME_FILE SOUP_URI_SCHEME_FTP +SOUP_URI_SCHEME_RESOURCE soup_uri_uses_default_port SOUP_URI_IS_VALID SOUP_URI_VALID_FOR_HTTP diff --git a/libsoup/soup-request-file.c b/libsoup/soup-request-file.c index 0b5638d2..73d0cd8c 100644 --- a/libsoup/soup-request-file.c +++ b/libsoup/soup-request-file.c @@ -128,7 +128,15 @@ soup_request_file_ensure_file (SoupRequestFile *file, windowsify_file_uri_path (decoded_path); #endif - file->priv->gfile = g_file_new_for_path (decoded_path); + if (uri->scheme == SOUP_URI_SCHEME_RESOURCE) { + char *uri_str; + + uri_str = g_strdup_printf ("resource://%s", decoded_path); + file->priv->gfile = g_file_new_for_uri (uri_str); + g_free (uri_str); + } else + file->priv->gfile = g_file_new_for_path (decoded_path); + g_free (decoded_path); return TRUE; } @@ -250,7 +258,7 @@ soup_request_file_get_content_type (SoupRequest *request) return file->priv->mime_type; } -static const char *file_schemes[] = { "file", NULL }; +static const char *file_schemes[] = { "file", "resource", NULL }; static void soup_request_file_class_init (SoupRequestFileClass *request_file_class) diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c index 4be679d5..d19290b0 100644 --- a/libsoup/soup-uri.c +++ b/libsoup/soup-uri.c @@ -110,7 +110,7 @@ static char *uri_normalized_copy (const char *str, int length, const char *unesc gpointer _SOUP_URI_SCHEME_HTTP, _SOUP_URI_SCHEME_HTTPS; gpointer _SOUP_URI_SCHEME_FTP; -gpointer _SOUP_URI_SCHEME_FILE, _SOUP_URI_SCHEME_DATA; +gpointer _SOUP_URI_SCHEME_FILE, _SOUP_URI_SCHEME_DATA, _SOUP_URI_SCHEME_RESOURCE; static inline const char * soup_uri_parse_scheme (const char *scheme, int len) @@ -119,6 +119,8 @@ soup_uri_parse_scheme (const char *scheme, int len) return SOUP_URI_SCHEME_HTTP; } else if (len == 5 && !g_ascii_strncasecmp (scheme, "https", len)) { return SOUP_URI_SCHEME_HTTPS; + } else if (len == 8 && !g_ascii_strncasecmp (scheme, "resource", len)) { + return SOUP_URI_SCHEME_RESOURCE; } else { char *lower_scheme; @@ -815,6 +817,15 @@ soup_uri_uses_default_port (SoupURI *uri) **/ /** + * SOUP_URI_SCHEME_RESOURCE: + * + * "resource" as an interned string. This can be compared directly + * against the value of a #SoupURI's <structfield>scheme</structfield> + * + * Since: 2.42 + **/ + +/** * soup_uri_get_scheme: * @uri: a #SoupURI * diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h index b851dbec..e2195b16 100644 --- a/libsoup/soup-uri.h +++ b/libsoup/soup-uri.h @@ -31,14 +31,15 @@ struct _SoupURI { GType soup_uri_get_type (void); #define SOUP_TYPE_URI (soup_uri_get_type ()) -#define SOUP_URI_SCHEME_HTTP _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTP, "http") -#define SOUP_URI_SCHEME_HTTPS _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTPS, "https") -#define SOUP_URI_SCHEME_FTP _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_FTP, "ftp") -#define SOUP_URI_SCHEME_FILE _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_FILE, "file") -#define SOUP_URI_SCHEME_DATA _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_DATA, "data") +#define SOUP_URI_SCHEME_HTTP _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTP, "http") +#define SOUP_URI_SCHEME_HTTPS _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_HTTPS, "https") +#define SOUP_URI_SCHEME_FTP _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_FTP, "ftp") +#define SOUP_URI_SCHEME_FILE _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_FILE, "file") +#define SOUP_URI_SCHEME_DATA _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_DATA, "data") +#define SOUP_URI_SCHEME_RESOURCE _SOUP_ATOMIC_INTERN_STRING (_SOUP_URI_SCHEME_RESOURCE, "resource") extern gpointer _SOUP_URI_SCHEME_HTTP, _SOUP_URI_SCHEME_HTTPS; extern gpointer _SOUP_URI_SCHEME_FTP; -extern gpointer _SOUP_URI_SCHEME_FILE, _SOUP_URI_SCHEME_DATA; +extern gpointer _SOUP_URI_SCHEME_FILE, _SOUP_URI_SCHEME_DATA, _SOUP_URI_SCHEME_RESOURCE; SoupURI *soup_uri_new_with_base (SoupURI *base, const char *uri_string); diff --git a/tests/Makefile.am b/tests/Makefile.am index d2a1cd64..085a81b3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,6 +28,7 @@ noinst_PROGRAMS = \ ntlm-test \ redirect-test \ requester-test \ + resource-test \ simple-httpd \ simple-proxy \ sniffing-test \ @@ -41,6 +42,8 @@ noinst_PROGRAMS = \ $(APACHE_TESTS) \ $(XMLRPC_TESTS) +noinst_DATA = soup-tests.gresource + TEST_SRCS = test-utils.c test-utils.h auth_test_SOURCES = auth-test.c $(TEST_SRCS) @@ -66,6 +69,7 @@ pull_api_SOURCES = pull-api.c $(TEST_SRCS) range_test_SOURCES = range-test.c $(TEST_SRCS) redirect_test_SOURCES = redirect-test.c $(TEST_SRCS) requester_test_SOURCES = requester-test.c $(TEST_SRCS) +resource_test_SOURCES = resource-test.c $(TEST_SRCS) server_auth_test_SOURCES = server-auth-test.c $(TEST_SRCS) simple_httpd_SOURCES = simple-httpd.c simple_proxy_SOURCES = simple-proxy.c @@ -89,6 +93,9 @@ if HAVE_XMLRPC_EPI_PHP XMLRPC_TESTS = xmlrpc-test xmlrpc-server-test endif +soup-tests.gresource: soup-tests.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/soup-tests.gresource.xml) + $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) $< + TESTS = \ chunk-test \ coding-test \ @@ -103,6 +110,7 @@ TESTS = \ ntlm-test \ redirect-test \ requester-test \ + resource-test \ sniffing-test \ socket-test \ ssl-test \ @@ -127,17 +135,20 @@ RESOURCES = \ resources/test.html \ resources/text_binary.txt -EXTRA_DIST = \ - htdigest \ - htpasswd \ - httpd.conf.in \ - index.txt \ - libsoup.supp \ - test-cert.pem \ - test-key.pem \ - xmlrpc-server.php \ +EXTRA_DIST = \ + htdigest \ + htpasswd \ + httpd.conf.in \ + index.txt \ + libsoup.supp \ + soup-tests.gresource.xml \ + test-cert.pem \ + test-key.pem \ + xmlrpc-server.php \ $(RESOURCES) +DISTCLEANFILES = soup-tests.gresource + if MISSING_REGRESSION_TEST_PACKAGES check-local: check-TESTS @echo "" diff --git a/tests/resource-test.c b/tests/resource-test.c new file mode 100644 index 00000000..449820a4 --- /dev/null +++ b/tests/resource-test.c @@ -0,0 +1,296 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2012 Igalia S.L. + */ + +#include "test-utils.h" + +SoupBuffer *index_buffer; + +static void +get_index (void) +{ + char *contents; + gsize length; + GError *error = NULL; + + if (!g_file_get_contents (SRCDIR "/index.txt", &contents, &length, &error)) { + g_printerr ("Could not read index.txt: %s\n", + error->message); + exit (1); + } + + index_buffer = soup_buffer_new (SOUP_MEMORY_TAKE, contents, length); +} + +static void +register_gresource (void) +{ + GResource *resource; + GError *error = NULL; + + resource = g_resource_load ("soup-tests.gresource", &error); + if (!resource) { + g_printerr ("Could not load resource soup-tests.gresource: %s\n", + error->message); + exit (1); + } + g_resources_register (resource); + g_resource_unref (resource); +} + +static void +check_results (GString *body) +{ + if (body->len != index_buffer->length) { + debug_printf (1, " body length mismatch: expected %d, got %d\n", + (int)index_buffer->length, (int)body->len); + errors++; + } else if (memcmp (body->str, index_buffer->data, body->len) != 0) { + debug_printf (1, " body data mismatch\n"); + errors++; + } +} + +typedef struct { + GString *body; + char buffer[1024]; + GMainLoop *loop; +} AsyncRequestData; + +static void +stream_closed (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GInputStream *in = G_INPUT_STREAM (source); + AsyncRequestData *data = user_data; + GError *error = NULL; + + if (!g_input_stream_close_finish (in, result, &error)) { + debug_printf (1, " close failed: %s\n", error->message); + g_error_free (error); + errors++; + } + g_main_loop_quit (data->loop); + g_object_unref (in); +} + +static void +test_read_ready (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GInputStream *in = G_INPUT_STREAM (source); + AsyncRequestData *data = user_data; + gssize nread; + GError *error = NULL; + + nread = g_input_stream_read_finish (in, result, &error); + if (nread == -1) { + debug_printf (1, " g_input_stream_read failed: %s\n", + error->message); + g_clear_error (&error); + g_input_stream_close (in, NULL, NULL); + g_object_unref (in); + errors++; + return; + } else if (nread == 0) { + g_input_stream_close_async (in, G_PRIORITY_DEFAULT, NULL, + stream_closed, data); + return; + } + + g_string_append_len (data->body, data->buffer, nread); + g_input_stream_read_async (in, data->buffer, sizeof (data->buffer), + G_PRIORITY_DEFAULT, NULL, + test_read_ready, data); +} + +static void +async_request_sent (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GInputStream *in; + AsyncRequestData *data = user_data; + GError *error = NULL; + + in = soup_request_send_finish (SOUP_REQUEST (source), result, &error); + if (!in) { + debug_printf (1, " soup_request_send_async failed: %s\n", + error->message); + g_clear_error (&error); + errors++; + return; + } + + g_input_stream_read_async (in, data->buffer, sizeof (data->buffer), + G_PRIORITY_DEFAULT, NULL, + test_read_ready, data); +} + +static void +do_async_request (SoupRequest *request) +{ + AsyncRequestData data; + + data.body = g_string_new (NULL); + soup_request_send_async (request, NULL, async_request_sent, &data); + + data.loop = g_main_loop_new (soup_session_get_async_context (soup_request_get_session (request)), TRUE); + g_main_loop_run (data.loop); + g_main_loop_unref (data.loop); + + check_results (data.body); + g_string_free (data.body, TRUE); +} + +static void +do_sync_request (SoupRequest *request) +{ + GInputStream *in; + GString *body; + char buffer[1024]; + gssize nread; + GError *error = NULL; + + in = soup_request_send (request, NULL, &error); + if (!in) { + debug_printf (1, " soup_request_send failed: %s\n", + error->message); + g_clear_error (&error); + errors++; + return; + } + + body = g_string_new (NULL); + do { + nread = g_input_stream_read (in, buffer, sizeof (buffer), + 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, buffer, 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); + + check_results (body); + g_string_free (body, TRUE); +} + +static void +do_request_file_test (SoupRequester *requester, + gboolean async) +{ + SoupRequest *request; + GFile *index; + char *uri_string; + SoupURI *uri; + + index = g_file_new_for_path (SRCDIR "/index.txt"); + uri_string = g_file_get_uri (index); + g_object_unref (index); + + uri = soup_uri_new (uri_string); + g_free (uri_string); + + request = soup_requester_request_uri (requester, uri, NULL); + if (async) + do_async_request (request); + else + do_sync_request (request); + g_object_unref (request); + + soup_uri_free (uri); +} + +static void +do_request_data_test (SoupRequester *requester, + gboolean async) +{ + SoupRequest *request; + gchar *base64; + char *uri_string; + SoupURI *uri; + + base64 = g_base64_encode ((const guchar *)index_buffer->data, index_buffer->length); + uri_string = g_strdup_printf ("data:text/plain;charset=utf8;base64,%s", base64); + g_free (base64); + + uri = soup_uri_new (uri_string); + g_free (uri_string); + + request = soup_requester_request_uri (requester, uri, NULL); + if (async) + do_async_request (request); + else + do_sync_request (request); + g_object_unref (request); + + soup_uri_free (uri); +} + +static void +do_request_gresource_test (SoupRequester *requester, + gboolean async) +{ + SoupRequest *request; + SoupURI *uri; + + uri = soup_uri_new ("resource:///org/gnome/libsoup/tests/index.txt"); + request = soup_requester_request_uri (requester, uri, NULL); + if (async) + do_async_request (request); + else + do_sync_request (request); + g_object_unref (request); + + soup_uri_free (uri); +} + +int +main (int argc, char **argv) +{ + SoupSession *session; + SoupRequester *requester; + + test_init (argc, argv, NULL); + + get_index (); + register_gresource (); + + /* Sync tests */ + 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); + + do_request_file_test (requester, FALSE); + do_request_data_test (requester, FALSE); + do_request_gresource_test (requester, FALSE); + + soup_test_session_abort_unref (session); + + /* Async tests */ + session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, + SOUP_SESSION_USE_THREAD_CONTEXT, TRUE, + NULL); + requester = soup_requester_new (); + soup_session_add_feature (session, SOUP_SESSION_FEATURE (requester)); + g_object_unref (requester); + + do_request_file_test (requester, TRUE); + do_request_data_test (requester, TRUE); + do_request_gresource_test (requester, TRUE); + + soup_test_session_abort_unref (session); + + test_cleanup (); + return errors != 0; +} diff --git a/tests/soup-tests.gresource.xml b/tests/soup-tests.gresource.xml new file mode 100644 index 00000000..969a6bfe --- /dev/null +++ b/tests/soup-tests.gresource.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/org/gnome/libsoup/tests"> + <file>index.txt</file> + </gresource> +</gresources>
\ No newline at end of file |