/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ /* * Copyright (C) 2007, 2008 Red Hat, Inc. */ #include "test-utils.h" static struct { const char *title, *name; const char *result; } tests[] = { /* Both fields must be filled in */ { NULL, "Name", "" }, { "Mr.", NULL, "" }, /* Filled-in but empty is OK */ { "", "", "Hello, " }, { "", "Name", "Hello, Name" }, { "Mr.", "", "Hello, MR. " }, /* Simple */ { "Mr.", "Name", "Hello, MR. Name" }, /* Encoding of spaces */ { "Mr.", "Full Name", "Hello, MR. Full Name" }, { "Mr. and Mrs.", "Full Name", "Hello, MR. AND MRS. Full Name" }, /* Encoding of "+" */ { "Mr.+Mrs.", "Full Name", "Hello, MR.+MRS. Full Name" }, /* Encoding of non-ASCII. */ { "Se\xC3\xB1or", "Nombre", "Hello, SE\xC3\xB1OR Nombre" }, /* Encoding of '%' */ { "Mr.", "Foo %2f Bar", "Hello, MR. Foo %2f Bar" }, }; static void do_hello_test_curl (int n, gboolean extra, const char *uri) { GPtrArray *args; char *title_arg = NULL, *name_arg = NULL; char *str_stdout = NULL; GError *error = NULL; debug_printf (1, "%2d. '%s' '%s'%s: \n", n * 2 + (extra ? 2 : 1), tests[n].title ? tests[n].title : "(null)", tests[n].name ? tests[n].name : "(null)", extra ? " + extra" : ""); args = g_ptr_array_new (); g_ptr_array_add (args, "curl"); g_ptr_array_add (args, "--noproxy"); g_ptr_array_add (args, "*"); g_ptr_array_add (args, "-G"); if (tests[n].title) { title_arg = soup_form_encode ("title", tests[n].title, NULL); g_ptr_array_add (args, "-d"); g_ptr_array_add (args, title_arg); } if (tests[n].name) { name_arg = soup_form_encode ("n@me", tests[n].name, NULL); g_ptr_array_add (args, "-d"); g_ptr_array_add (args, name_arg); } if (extra) { g_ptr_array_add (args, "-d"); g_ptr_array_add (args, "extra=something"); } g_ptr_array_add (args, (char *)uri); g_ptr_array_add (args, NULL); if (g_spawn_sync (NULL, (char **)args->pdata, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, &str_stdout, NULL, NULL, &error)) { g_assert_cmpstr (str_stdout, ==, tests[n].result); g_free (str_stdout); } else { g_assert_no_error (error); g_error_free (error); } g_ptr_array_free (args, TRUE); g_free (title_arg); g_free (name_arg); } static void do_hello_tests_curl (gconstpointer uri) { int n; if (!have_curl()) { g_test_skip ("curl is not available"); return; } for (n = 0; n < G_N_ELEMENTS (tests); n++) { do_hello_test_curl (n, FALSE, uri); do_hello_test_curl (n, TRUE, uri); } } static void do_hello_test_libsoup (int n, gboolean extra, const char *uri) { SoupSession *session; SoupMessage *msg; GData *data; GBytes *body; char *encoded; debug_printf (1, "%2d. '%s' '%s'%s: \n", n * 2 + (extra ? 2 : 1), tests[n].title ? tests[n].title : "(null)", tests[n].name ? tests[n].name : "(null)", extra ? " + extra" : ""); g_datalist_init (&data); if (tests[n].title) g_datalist_set_data (&data, "title", (gpointer)tests[n].title); if (tests[n].name) g_datalist_set_data (&data, "n@me", (gpointer)tests[n].name); if (extra) g_datalist_set_data (&data, "extra", (gpointer)"something"); session = soup_test_session_new (NULL); encoded = soup_form_encode_datalist (&data); msg = soup_message_new_from_encoded_form ("GET", uri, encoded); g_free (encoded); g_datalist_clear (&data); body = soup_session_send_and_read (session, msg, NULL, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_cmpmem (tests[n].result, strlen (tests[n].result), g_bytes_get_data (body, NULL), g_bytes_get_size (body)); g_bytes_unref (body); g_object_unref (msg); soup_test_session_abort_unref (session); } static void do_hello_tests_libsoup (gconstpointer uri) { int n; for (n = 0; n < G_N_ELEMENTS (tests); n++) { do_hello_test_libsoup (n, FALSE, uri); do_hello_test_libsoup (n, TRUE, uri); } } #define MD5_TEST_FILE (g_test_get_filename (G_TEST_DIST, "index.txt", NULL)) #define MD5_TEST_FILE_BASENAME "index.txt" #define MD5_TEST_FILE_MIME_TYPE "text/plain" static char * get_md5_data (char **contents, gsize *length) { char *my_contents, *md5; gsize my_length; GError *error = NULL; if (!g_file_get_contents (MD5_TEST_FILE, &my_contents, &my_length, &error)) { g_assert_no_error (error); g_error_free (error); return NULL; } md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, my_contents, my_length); if (contents) *contents = my_contents; else g_free (my_contents); if (length) *length = my_length; return md5; } static void do_md5_test_curl (gconstpointer data) { const char *uri = data; char *md5; GPtrArray *args; char *file_arg, *str_stdout; GError *error = NULL; if (!have_curl()) { g_test_skip ("curl is not available"); return; } md5 = get_md5_data (NULL, NULL); if (!md5) return; args = g_ptr_array_new (); g_ptr_array_add (args, "curl"); g_ptr_array_add (args, "--noproxy"); g_ptr_array_add (args, "*"); g_ptr_array_add (args, "-L"); g_ptr_array_add (args, "-F"); file_arg = g_strdup_printf ("file=@%s", MD5_TEST_FILE); g_ptr_array_add (args, file_arg); g_ptr_array_add (args, "-F"); g_ptr_array_add (args, "fmt=txt"); g_ptr_array_add (args, (char *)uri); g_ptr_array_add (args, NULL); if (g_spawn_sync (NULL, (char **)args->pdata, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, &str_stdout, NULL, NULL, NULL)) { g_assert_cmpstr (str_stdout, ==, md5); g_free (str_stdout); } else { g_assert_no_error (error); g_error_free (error); } g_ptr_array_free (args, TRUE); g_free (file_arg); g_free (md5); } static void do_md5_test_libsoup (gconstpointer data) { const char *uri = data; char *contents, *md5; gsize length; SoupMultipart *multipart; GBytes *buffer; SoupMessage *msg; SoupSession *session; GBytes *body; g_test_bug ("601640"); md5 = get_md5_data (&contents, &length); if (!md5) return; multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART); buffer = g_bytes_new (contents, length); soup_multipart_append_form_file (multipart, "file", MD5_TEST_FILE_BASENAME, MD5_TEST_FILE_MIME_TYPE, buffer); g_bytes_unref (buffer); soup_multipart_append_form_string (multipart, "fmt", "text"); msg = soup_message_new_from_multipart (uri, multipart); soup_multipart_free (multipart); session = soup_test_session_new (NULL); body = soup_session_send_and_read (session, msg, NULL, NULL); soup_test_assert_message_status (msg, SOUP_STATUS_OK); g_assert_cmpmem (md5, strlen (md5), g_bytes_get_data (body, NULL), g_bytes_get_size (body)); g_bytes_unref (body); g_object_unref (msg); soup_test_session_abort_unref (session); g_free (contents); g_free (md5); } static void do_form_decode_test (void) { GHashTable *table; const gchar *value; gchar *tmp; if (!have_curl()) { g_test_skip ("curl is not available"); return; } /* Test that the code handles multiple values with the same key. */ table = soup_form_decode ("foo=first&foo=second&foo=third"); /* Allocate some memory. We do this to test for a bug in * soup_form_decode() that resulted in values from the hash * table pointing to memory that is already released. */ tmp = g_strdup ("other"); value = g_hash_table_lookup (table, "foo"); g_assert_cmpstr (value, ==, "third"); g_free (tmp); g_hash_table_destroy (table); } static void hello_callback (SoupServer *server, SoupServerMessage *msg, const char *path, GHashTable *query, gpointer data) { char *title, *name, *fmt; const char *content_type; GString *buf; const char *method; method = soup_server_message_get_method (msg); if (method != SOUP_METHOD_GET && method != SOUP_METHOD_HEAD) { soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL); return; } if (query) { title = g_hash_table_lookup (query, "title"); name = g_hash_table_lookup (query, "n@me"); fmt = g_hash_table_lookup (query, "fmt"); } else title = name = fmt = NULL; buf = g_string_new (NULL); if (!query || (fmt && !strcmp (fmt, "html"))) { content_type = "text/html"; g_string_append (buf, "
Hello, %s %s
\r\n", title, name); } g_string_append (buf, "\r\n"); g_string_append (buf, "\r\n"); } else { content_type = "text/plain"; if (title && name) { char *uptitle = g_ascii_strup (title, -1); g_string_append_printf (buf, "Hello, %s %s", uptitle, name); g_free (uptitle); } } soup_server_message_set_response (msg, content_type, SOUP_MEMORY_TAKE, buf->str, buf->len); g_string_free (buf, FALSE); soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); } static void md5_get_callback (SoupServer *server, SoupServerMessage *msg, const char *path, GHashTable *query, gpointer data) { const char *file = NULL, *md5sum = NULL, *fmt; const char *content_type; GString *buf; if (query) { file = g_hash_table_lookup (query, "file"); md5sum = g_hash_table_lookup (query, "md5sum"); fmt = g_hash_table_lookup (query, "fmt"); } else fmt = "html"; buf = g_string_new (NULL); if (!strcmp (fmt, "html")) { content_type = "text/html"; g_string_append (buf, "File: %s
MD5: %s