From c2709bd5318e6e5915fc913e5c410d5b635b7313 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Mon, 29 Jun 2015 11:34:02 +0200 Subject: [PATCH] ZakCgiMain::parse_stdin now works also with non-data form. --- src/main.c | 299 ++++++++++++++++++++++------------------ src/main.h | 2 +- tests/env.c | 112 +++++++-------- tests/provapostcgi.html | 3 +- tests/querystring.c | 4 +- tests/redirect.c | 4 +- 6 files changed, 230 insertions(+), 194 deletions(-) diff --git a/src/main.c b/src/main.c index 880ddf8..a0ed5d5 100644 --- a/src/main.c +++ b/src/main.c @@ -312,11 +312,12 @@ gchar /** * zak_cgi_main_get_parameters: + * @query_string: * * Returns: */ GHashTable -*zak_cgi_main_get_parameters (void) +*zak_cgi_main_get_parameters (const gchar *query_string) { GHashTable *ht; @@ -327,15 +328,30 @@ GHashTable guint i; guint l; + GValue *gval; + ht = g_hash_table_new (g_str_hash, g_str_equal); - qstring = g_getenv ("QUERY_STRING"); + if (query_string == NULL) + { + qstring = g_getenv ("QUERY_STRING"); + } + else + { + qstring = query_string; + } params = g_strsplit (qstring, "&", -1); l = g_strv_length (params); for (i = 0; i < l; i++) { + gval = g_new0 (GValue, 1); + parts = g_strsplit (params[i], "=", 2); - g_hash_table_replace (ht, g_strdup (parts[0]), g_strdup (parts[1])); + + g_value_init (gval, G_TYPE_STRING); + g_value_set_string (gval, g_strdup (parts[1] == NULL ? "" : parts[1])); + + g_hash_table_replace (ht, g_strdup (parts[0]), gval); g_strfreev (parts); } @@ -386,8 +402,6 @@ gchar { syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "error reading stdin: %s", error->message); } - - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "stdin: %s", ret); } } @@ -451,172 +465,191 @@ GHashTable ht = NULL; - content_type = (gchar *)g_getenv ("CONTENT_TYPE"); - gchar **splitted = g_strsplit (content_type, ";", -1); - if (g_strv_length (splitted) > 1 - && boundary == NULL) - { - gchar **boundary_splitted = g_strsplit (splitted[1], "=", 2); - _boundary = g_strdup_printf ("--%s", boundary_splitted[1]); - g_strfreev (boundary_splitted); - } - else - { - if (boundary != NULL) - { - _boundary = g_strdup_printf ("--%s", boundary); - } - } - g_strfreev (splitted); - env = g_getenv ("CONTENT_LENGTH"); if (env != NULL) { l = strtol (env, NULL, 10); - if (l > 0) + if (l < 1) { - ht = g_hash_table_new (g_str_hash, g_str_equal); + return ht; + } + } + else + { + return ht; + } - i = 0; - do + content_type = (gchar *)g_getenv ("CONTENT_TYPE"); + if (content_type == NULL) + { + return ht; + } + + gchar **splitted = g_strsplit (content_type, ";", -1); + if (g_strcmp0 (content_type, "") == 0 + || g_strcmp0 (splitted[0], "application/x-www-form-urlencoded") == 0) + { + return zak_cgi_main_get_parameters (buf); + } + else if (g_strcmp0 (splitted[0], "multipart/form-data") == 0) + { + if (g_strv_length (splitted) > 1 + && boundary == NULL) + { + gchar **boundary_splitted = g_strsplit (splitted[1], "=", 2); + _boundary = g_strdup_printf ("--%s", boundary_splitted[1]); + g_strfreev (boundary_splitted); + } + else + { + if (boundary != NULL) { - /* read line */ - line = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "boundary: %s %d", line, bytesread); - if (g_strcmp0 (line, _boundary) == 0) - { - /* content-disposition */ - gchar **v_content; - gchar **parts; - guint l_v_content; + _boundary = g_strdup_printf ("--%s", boundary); + } + } + g_strfreev (splitted); + + ht = g_hash_table_new (g_str_hash, g_str_equal); + + i = 0; + do + { + /* read line */ + line = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "boundary: %s %d", line, bytesread); + if (g_strcmp0 (line, _boundary) == 0) + { + /* content-disposition */ + gchar **v_content; + gchar **parts; + guint l_v_content; + + gchar *param_name; + gchar *param_name_file; + gchar *param_value; + guint file_l; - gchar *param_name; - gchar *param_name_file; - gchar *param_value; - guint file_l; + GValue *gval; - GValue *gval; + content_disposition = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "content_disposition: %s", content_disposition); - content_disposition = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "content_disposition: %s", content_disposition); + v_content = g_strsplit (content_disposition, ";", -1); + l_v_content = g_strv_length (v_content); - v_content = g_strsplit (content_disposition, ";", -1); - l_v_content = g_strv_length (v_content); + parts = g_strsplit (v_content[1], "=", 2); + param_name = g_strndup (parts[1] + 1, strlen (parts[1]) - 2); + param_name[strlen (parts[1]) - 2] = '\0'; + g_strfreev (parts); - parts = g_strsplit (v_content[1], "=", 2); - param_name = g_strndup (parts[1] + 1, strlen (parts[1]) - 2); - param_name[strlen (parts[1]) - 2] = '\0'; + if (l_v_content == 3) + { + parts = g_strsplit (v_content[2], "=", 2); + param_name_file = g_strndup (parts[1] + 1, strlen (parts[1]) - 2); + param_name_file[strlen (parts[1]) - 2] = '\0'; + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "param_name_file: %s", param_name_file); g_strfreev (parts); - if (l_v_content == 3) - { - parts = g_strsplit (v_content[2], "=", 2); - param_name_file = g_strndup (parts[1] + 1, strlen (parts[1]) - 2); - param_name_file[strlen (parts[1]) - 2] = '\0'; - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "param_name_file: %s", param_name_file); - g_strfreev (parts); - - /* content-type */ - content_type = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "content_type: %s", content_type); - g_free (content_type); - } + /* content-type */ + content_type = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "content_type: %s", content_type); + g_free (content_type); + } - g_strfreev (v_content); - g_free (content_disposition); + g_strfreev (v_content); + g_free (content_disposition); - /* empty */ - g_free (zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread)); + /* empty */ + g_free (zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread)); - if (l_v_content == 3) + if (l_v_content == 3) + { + param_value = (gchar *)g_malloc (1); + if (g_strcmp0 (param_name_file, "") != 0) { - param_value = (gchar *)g_malloc (1); - if (g_strcmp0 (param_name_file, "") != 0) + gboolean exit; + + exit = FALSE; + file_l = 0; + do { - gboolean exit; + tmp = zak_cgi_main_read_line (buf, l, &i, FALSE, &bytesread); + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "tmp: %s %d", tmp, bytesread); - exit = FALSE; - file_l = 0; - do + if (memcmp (tmp, _boundary, strlen (_boundary)) == 0) { - tmp = zak_cgi_main_read_line (buf, l, &i, FALSE, &bytesread); - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "tmp: %s %d", tmp, bytesread); - - if (memcmp (tmp, _boundary, strlen (_boundary)) == 0) - { - i -= bytesread; - exit = TRUE; - } - else - { - param_value = g_realloc (param_value, file_l + bytesread); - memmove (param_value + file_l, tmp, bytesread); - file_l += bytesread; - } - - g_free (tmp); - } while (!exit); - } - else - { - /* empty */ - g_free (zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread)); + i -= bytesread; + exit = TRUE; + } + else + { + param_value = g_realloc (param_value, file_l + bytesread); + memmove (param_value + file_l, tmp, bytesread); + file_l += bytesread; + } - file_l = 3; - param_value[0] = '\0'; - } + g_free (tmp); + } while (!exit); } else { - param_value = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); - syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "param_value: %s", param_value); + /* empty */ + g_free (zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread)); + + file_l = 3; + param_value[0] = '\0'; } + } + else + { + param_value = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread); + syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "param_value: %s", param_value); + } - gval = g_new0 (GValue, 1); + gval = g_new0 (GValue, 1); - if (l_v_content == 3) - { - GPtrArray *ar; + if (l_v_content == 3) + { + GPtrArray *ar; - ar = g_ptr_array_new (); - g_ptr_array_add (ar, g_strdup (param_name_file)); - g_ptr_array_add (ar, g_memdup (param_value, file_l - 2)); - g_ptr_array_add (ar, GSIZE_TO_POINTER (file_l - 2)); + ar = g_ptr_array_new (); + g_ptr_array_add (ar, g_strdup (param_name_file)); + g_ptr_array_add (ar, g_memdup (param_value, file_l - 2)); + g_ptr_array_add (ar, GSIZE_TO_POINTER (file_l - 2)); - g_value_init (gval, G_TYPE_PTR_ARRAY); - g_value_take_boxed (gval, ar); - } - else - { - g_value_init (gval, G_TYPE_STRING); - g_value_set_string (gval, g_strdup (param_value)); - } + g_value_init (gval, G_TYPE_PTR_ARRAY); + g_value_take_boxed (gval, ar); + } + else + { + g_value_init (gval, G_TYPE_STRING); + g_value_set_string (gval, g_strdup (param_value)); + } - g_hash_table_replace (ht, g_strdup (param_name), gval); + g_hash_table_replace (ht, g_strdup (param_name), gval); - g_free (param_name); - g_free (param_value); - if (l_v_content == 3) - { - g_free (param_name_file); - } + g_free (param_name); + g_free (param_value); + if (l_v_content == 3) + { + g_free (param_name_file); } - else + } + else + { + tmp = g_strdup_printf ("%s--", _boundary); + if (g_strcmp0 (line, tmp) == 0) { - tmp = g_strdup_printf ("%s--", _boundary); - if (g_strcmp0 (line, tmp) == 0) - { - g_free (tmp); - break; - } g_free (tmp); + break; } + g_free (tmp); + } - g_free (line); - } while (i < l); + g_free (line); + } while (i < l); - g_free (_boundary); - } + g_free (_boundary); } return ht; diff --git a/src/main.h b/src/main.h index c3c6cde..c262210 100644 --- a/src/main.h +++ b/src/main.h @@ -70,7 +70,7 @@ gchar *zak_cgi_main_set_cookie (const gchar *name, gboolean secure, gboolean http_only); -GHashTable *zak_cgi_main_get_parameters (void); +GHashTable *zak_cgi_main_get_parameters (const gchar *query_string); gchar *zak_cgi_main_get_stdin (void); diff --git a/tests/env.c b/tests/env.c index a4bb7dd..4b934f2 100644 --- a/tests/env.c +++ b/tests/env.c @@ -33,8 +33,8 @@ main (int argc, char *argv[]) env = zak_cgi_main_dump_env (); str = g_string_new ("\n" - "Environment variables\n" - "\n"); + "Environment variables\n" + "\n"); g_string_append_printf (str, "%s\n", env); g_free (env); @@ -43,71 +43,73 @@ main (int argc, char *argv[]) /*syslog (LOG_MAKEPRI(LOG_SYSLOG, LOG_DEBUG), "stdin: %s", env);*/ if (env != NULL) { - g_string_append_printf (str, - "

\n" - "%s", - env); + GHashTableIter iter; - const gchar *content_type = g_getenv ("CONTENT_TYPE"); - gchar **splitted = g_strsplit (content_type, ";", -1); - if (g_strv_length (splitted) == 2) - { - gchar **boundary = g_strsplit (splitted[1], "=", 2); + gpointer key; + gpointer value; - /*ht = zak_cgi_main_parse_stdin (env, boundary[1]);*/ - ht = zak_cgi_main_parse_stdin (env, NULL); + g_string_append_printf (str, + "

\n" + "%s", + env); - GHashTableIter iter; + ht = zak_cgi_main_parse_stdin (env, NULL); - gpointer key; - gpointer value; + if (g_hash_table_size (ht) > 0) + { + g_string_append_printf (str, "

\n\n"); - if (g_hash_table_size (ht) > 0) + g_hash_table_iter_init (&iter, ht); + while (g_hash_table_iter_next (&iter, &key, &value)) { - g_string_append_printf (str, "

\n
\n"); - - g_hash_table_iter_init (&iter, ht); - while (g_hash_table_iter_next (&iter, &key, &value)) + if (G_VALUE_HOLDS (value, G_TYPE_BOXED)) { - if (G_VALUE_HOLDS (value, G_TYPE_BOXED)) - { - GPtrArray *ar = (GPtrArray *)g_value_get_boxed ((GValue *)value); - - g_string_append_printf (str, "\n", - (gchar *)key, (gchar *)g_ptr_array_index (ar, 0)); - - if (g_strcmp0 ((gchar *)g_ptr_array_index (ar, 0), "") != 0) - { - /* save the file to tmp */ - GFile *gfile; - GFileIOStream *iostream; - GOutputStream *ostream; - - iostream = NULL; - gfile = g_file_new_tmp (g_strdup_printf ("cgi-XXXXXX-%s", (gchar *)g_ptr_array_index (ar, 0)), - &iostream, - NULL); - - ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); - g_output_stream_write (ostream, - g_ptr_array_index (ar, 1), - GPOINTER_TO_SIZE (g_ptr_array_index (ar, 2)), - NULL, - NULL); - g_output_stream_close (ostream, NULL, NULL); - } - } - else + GPtrArray *ar = (GPtrArray *)g_value_get_boxed ((GValue *)value); + + g_string_append_printf (str, + "\n", + (gchar *)key, (gchar *)g_ptr_array_index (ar, 0)); + + if (g_strcmp0 ((gchar *)g_ptr_array_index (ar, 0), "") != 0) { - g_string_append_printf (str, "\n", - (gchar *)key, (gchar *)g_value_get_string ((GValue *)value)); + /* save the file to tmp */ + GFile *gfile; + GFileIOStream *iostream; + GOutputStream *ostream; + + iostream = NULL; + gfile = g_file_new_tmp (g_strdup_printf ("cgi-XXXXXX-%s", (gchar *)g_ptr_array_index (ar, 0)), + &iostream, + NULL); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream)); + g_output_stream_write (ostream, + g_ptr_array_index (ar, 1), + GPOINTER_TO_SIZE (g_ptr_array_index (ar, 2)), + NULL, + NULL); + g_output_stream_close (ostream, NULL, NULL); + + g_object_unref (ostream); + g_object_unref (gfile); } } - - g_string_append_printf (str, "
%s%s
%s%s
%s%s
\n"); + else if (G_VALUE_HOLDS (value, G_TYPE_STRING)) + { + g_string_append_printf (str, + "%s%s\n", + (gchar *)key, (gchar *)g_value_get_string ((GValue *)value)); + } + else + { + g_string_append_printf (str, + "%s%s\n", + (gchar *)key, "value of unknown type"); + } } + + g_string_append_printf (str, "\n"); } - g_strfreev (splitted); g_free (env); } diff --git a/tests/provapostcgi.html b/tests/provapostcgi.html index 230155d..7eb4d39 100644 --- a/tests/provapostcgi.html +++ b/tests/provapostcgi.html @@ -1,7 +1,8 @@ -
+ + diff --git a/tests/querystring.c b/tests/querystring.c index e433401..6048445 100644 --- a/tests/querystring.c +++ b/tests/querystring.c @@ -28,7 +28,7 @@ main (int argc, char *argv[]) gpointer key; gpointer value; - ht_env = zak_cgi_main_get_parameters (); + ht_env = zak_cgi_main_get_parameters (NULL); str = g_string_new ("\n" "Query string\n" @@ -42,7 +42,7 @@ main (int argc, char *argv[]) while (g_hash_table_iter_next (&iter, &key, &value)) { g_string_append_printf (str, "%s%s\n", - (gchar *)key, (gchar *)value); + (gchar *)key, (gchar *)g_value_get_string ((GValue *)value)); } g_string_append_printf (str, "\n"); diff --git a/tests/redirect.c b/tests/redirect.c index ca02c77..890dc5b 100644 --- a/tests/redirect.c +++ b/tests/redirect.c @@ -23,9 +23,9 @@ main (int argc, char *argv[]) { GHashTable *ht_env; - ht_env = zak_cgi_main_get_parameters (); + ht_env = zak_cgi_main_get_parameters (NULL); - zak_cgi_main_redirect ((const gchar *)g_hash_table_lookup (ht_env, "redirectto")); + zak_cgi_main_redirect ((gchar *)g_value_get_string ((GValue *)(const gchar *)g_hash_table_lookup (ht_env, "redirectto"))); g_hash_table_destroy (ht_env); -- 2.49.0