/*
- * Copyright (C) 2015-2016 Andrea Zagli <azagli@libero.it>
+ * Copyright (C) 2015-2017 Andrea Zagli <azagli@libero.it>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <locale.h>
#include <glib/gprintf.h>
+#include <glib/gstdio.h>
#include <gio/gunixinputstream.h>
#include "main.h"
static void zak_cgi_main_init (ZakCgiMain *zak_cgi_main);
static void zak_cgi_main_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
static void zak_cgi_main_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
static void zak_cgi_main_dispose (GObject *gobject);
static void zak_cgi_main_finalize (GObject *gobject);
&error);
if (l != bytesread)
{
- g_warning ("Error reading stdin: bytes read differ from content length");
+ g_warning ("Error reading stdin: bytes read (%d) differ from content length (%d).", bytesread, l);
}
if (error != NULL)
{
g_warning ("Error reading stdin: %s", error->message);
}
+
+ FILE *fout;
+ fout = fopen("/tmp/pippo.txt", "wb");
+ fwrite(ret, bytesread, 1, fout);
+ fclose(fout);
}
}
if (zakcgimain != NULL)
{
- priv->stdin = g_strdup (ret);
+ priv->stdin = g_memdup (ret, bytesread);
}
return ret;
}
-static gchar
-*zak_cgi_main_read_line (const gchar *buf, guint l, guint *i,
- gboolean no_new_line_but_null_terminated,
- guint *bytesread)
+typedef struct
{
- gchar *line;
- guint line_start;
- guint count;
+ gchar *data;
+ gsize length;
+} Block;
+
+static GPtrArray
+*zak_cgi_main_split_content (const gchar *buf,
+ guint l,
+ const gchar *delimiter)
+{
+ guint i;
+ guint l_delimiter;
+ guint start;
+
+ gchar *_delimiter;
+
+ GPtrArray *ar;
+
+ gsize length;
+
+ _delimiter = g_strdup_printf ("%s%c%c", delimiter, 13, 10);
+
+ ar = g_ptr_array_new ();
- for (line_start = *i, count = 1; *i < l - 1; (*i)++, count++)
+ l_delimiter = strlen (_delimiter);
+
+ FILE *fout;
+ fout = fopen ("/tmp/buf.txt", "wb");
+ fwrite (buf, l, 1, fout);
+ fclose (fout);
+
+ start = 0;
+ for (i = 0; i < (l - (l_delimiter + 2)); i++)
{
- if (buf[*i] == 13 && buf[*i + 1] == 10)
+ /* start to control if delimiter is reached */
+ if (i >= l_delimiter
+ && memcmp (buf + (i - l_delimiter), _delimiter, l_delimiter) == 0)
{
- (*i)++;
- count++;
- break;
+ Block *b;
+
+ length = i - l_delimiter - start;
+
+ if (length > 0)
+ {
+ b = g_new0 (Block, 1);
+
+ b->data = g_memdup (buf + start, length);
+ b->length = length;
+
+ g_ptr_array_add (ar, b);
+
+ FILE *fout;
+ fout = fopen (g_strdup_printf("/tmp/blocco_loop_%d_%d_%d.txt", i, start, length), "wb");
+ fwrite (b->data, b->length, 1, fout);
+ fclose (fout);
+ }
+
+ start = i;
}
}
- line = (gchar *)g_memdup (buf + line_start, count);
- if (no_new_line_but_null_terminated)
+ if (i >= l_delimiter)
{
- line[count - 2] = '\0';
- }
+ Block *b;
+
+ length = i - start;
+
+ b = g_new0 (Block, 1);
+
+ b->data = g_memdup (buf + start, length);
+ b->length = length;
+
+ g_ptr_array_add (ar, b);
- *bytesread = count;
+ FILE *fout;
+ fout = fopen (g_strdup_printf("/tmp/blocco_loop_%d_%d_%d.txt", i, start, length), "wb");
+ fwrite (b->data, b->length, 1, fout);
+ fclose (fout);
+ }
- (*i)++;
+ for (i = 0; i < ar->len; i++)
+ {
+ FILE *fout;
+ Block *b;
+ b = (Block *)g_ptr_array_index(ar, i);
+ fout = fopen (g_strdup_printf("/tmp/blocco_%d.txt", i), "wb");
+ fwrite (b->data, b->length, 1, fout);
+ fclose (fout);
+ }
- return line;
+ return ar;
}
ZakCgiFile
return ht;
}
- content_type = (gchar *)g_getenv ("CONTENT_TYPE");
+ content_type = (gchar *)g_getenv ("CONTENT_TYPE");
if (content_type == NULL)
{
return ht;
}
else if (g_strcmp0 (splitted[0], "multipart/form-data") == 0)
{
+ GPtrArray *content_splitted;
+ guint j;
+ guint l_boundary;
+
if (g_strv_length (splitted) > 1
&& boundary == NULL)
{
}
g_strfreev (splitted);
+ l_boundary = strlen (_boundary);
+
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);
- if (g_strcmp0 (line, _boundary) == 0)
- {
- /* content-disposition */
- gchar **v_content;
- gchar **parts;
- guint l_v_content;
+ content_splitted = zak_cgi_main_split_content (buf, l, _boundary);
- gchar *param_name;
- gchar *param_name_file;
- gchar *param_value;
- guint file_l;
+ for (j = 0; j < content_splitted->len; j++)
+ {
+ GMemoryInputStream *mstream;
+ GDataInputStream *dataistream;
+ gsize length;
+ GError *error;
- GValue *gval;
- GValue *gval_tmp;
+ Block *b;
- ZakCgiFile *zgfile;
+ b = (Block *)g_ptr_array_index (content_splitted, j);
- GPtrArray *ar;
+ if (b->length == 0
+ || memcmp (b->data, "--", 2) == 0)
+ {
+ continue;
+ }
- content_disposition = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread);
+ /* read line */
+ mstream = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new_from_data (b->data, b->length, NULL));
+ dataistream = g_data_input_stream_new (G_INPUT_STREAM (mstream));
- v_content = g_strsplit (content_disposition, ";", -1);
- l_v_content = g_strv_length (v_content);
+ /* content-disposition */
+ gchar **v_content;
+ gchar **parts;
+ guint l_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);
+ gchar *param_name;
+ gchar *param_name_file;
+ gchar *param_value;
+ guint file_l;
- 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';
- g_strfreev (parts);
-
- /* content-type */
- content_type = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread);
- g_free (content_type);
- }
+ GValue *gval;
+ GValue *gval_tmp;
- g_strfreev (v_content);
- g_free (content_disposition);
+ ZakCgiFile *zgfile;
- /* empty */
- g_free (zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread));
+ GPtrArray *ar;
- if (l_v_content == 3)
+ error = NULL;
+ content_disposition = g_data_input_stream_read_line (dataistream, NULL, NULL, &error);
+ if (content_disposition == NULL)
+ {
+ if (error != NULL)
{
- param_value = (gchar *)g_malloc (1);
- if (g_strcmp0 (param_name_file, "") != 0)
- {
- gboolean exit;
-
- exit = FALSE;
- file_l = 0;
- do
- {
- tmp = zak_cgi_main_read_line (buf, l, &i, FALSE, &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));
-
- file_l = 3;
- param_value[0] = '\0';
- }
+ g_warning ("Error on read content disposition: %s", error->message);
}
else
{
- param_value = zak_cgi_main_read_line (buf, l, &i, TRUE, &bytesread);
+ g_warning ("No content disposition found.");
}
+ }
+
+ v_content = g_strsplit (content_disposition, ";", -1);
+ l_v_content = g_strv_length (v_content);
+
+ parts = g_strsplit_set (v_content[1], "=\"", 0);
+ param_name = g_strdup (parts[2]);
+ g_strfreev (parts);
+
+ if (l_v_content == 3)
+ {
+ parts = g_strsplit_set (v_content[2], "=\"", 0);
+ param_name_file = g_strdup (parts[2]);
+ g_strfreev (parts);
+
+ /* content-type */
+ content_type = g_data_input_stream_read_line (dataistream, &length, NULL, NULL);
+ g_free (content_type);
+ }
- gval_tmp = g_new0 (GValue, 1);
- if (l_v_content == 3)
+ g_strfreev (v_content);
+ g_free (content_disposition);
+
+ /* empty */
+ g_data_input_stream_read_line (dataistream, NULL, NULL, NULL);
+
+ if (l_v_content == 3)
+ {
+ param_value = (gchar *)g_malloc (1);
+ if (g_strcmp0 (param_name_file, "") != 0)
{
- zgfile = (ZakCgiFile *)g_new0 (ZakCgiFile, 1);
- zgfile->name = g_strdup (param_name_file);
- zgfile->content = g_memdup (param_value, file_l - 2);
- zgfile->size = file_l - 2;
+ tmp = g_data_input_stream_read_upto (dataistream, "", -1, &length, NULL, NULL);
- g_value_init (gval_tmp, ZAK_CGI_TYPE_FILE);
- g_value_take_boxed (gval_tmp, zgfile);
+ param_value = g_realloc (param_value, length);
+ memmove (param_value, tmp, length);
+
+ file_l = length;
}
else
{
- g_value_init (gval_tmp, G_TYPE_STRING);
- g_value_set_string (gval_tmp, g_strdup (param_value));
+ /* empty */
+ g_data_input_stream_read_line (dataistream, NULL, NULL, NULL);
+
+ file_l = 2;
+ param_value[0] = '\0';
}
+ }
+ else
+ {
+ param_value = g_data_input_stream_read_line (dataistream, &length, NULL, NULL);
+ param_value[length - 1] = '\0';
+ }
- gval = g_hash_table_lookup (ht, param_name);
- if (gval != NULL)
+ gval_tmp = g_new0 (GValue, 1);
+ if (l_v_content == 3)
+ {
+ zgfile = (ZakCgiFile *)g_new0 (ZakCgiFile, 1);
+ zgfile->name = g_strdup (param_name_file);
+ zgfile->content = g_memdup (param_value, file_l - 2);
+ zgfile->size = file_l - 2;
+
+ g_value_init (gval_tmp, ZAK_CGI_TYPE_FILE);
+ g_value_take_boxed (gval_tmp, zgfile);
+ }
+ else
+ {
+ g_value_init (gval_tmp, G_TYPE_STRING);
+ g_value_set_string (gval_tmp, g_strdup (param_value));
+ }
+
+ gval = g_hash_table_lookup (ht, param_name);
+ if (gval != NULL)
+ {
+ if (!G_VALUE_HOLDS (gval, G_TYPE_PTR_ARRAY))
{
- if (!G_VALUE_HOLDS (gval, G_TYPE_PTR_ARRAY))
- {
- GValue *g;
-
- g = (GValue *)g_new0 (GValue, 1);
- g_value_init (g, G_VALUE_TYPE (gval));
- g_value_copy (gval, g);
- g_value_unset (gval);
-
- /* converto to GPtrArray */
- ar = g_ptr_array_new ();
-
- g_ptr_array_add (ar, g);
-
- g_value_init (gval, G_TYPE_PTR_ARRAY);
- g_value_take_boxed (gval, ar);
- g_hash_table_replace (ht, g_strdup (param_name), gval);
- }
- else
- {
- ar = (GPtrArray *)g_value_get_boxed (gval);
- }
- g_ptr_array_add (ar, gval_tmp);
+ GValue *g;
+
+ g = (GValue *)g_new0 (GValue, 1);
+ g_value_init (g, G_VALUE_TYPE (gval));
+ g_value_copy (gval, g);
+ g_value_unset (gval);
+
+ /* converto to GPtrArray */
+ ar = g_ptr_array_new ();
+
+ g_ptr_array_add (ar, g);
+
+ g_value_init (gval, G_TYPE_PTR_ARRAY);
+ g_value_take_boxed (gval, ar);
+ g_hash_table_replace (ht, g_strdup (param_name), gval);
}
else
{
- g_hash_table_replace (ht, g_strdup (param_name), gval_tmp);
- }
-
- g_free (param_name);
- g_free (param_value);
- if (l_v_content == 3)
- {
- g_free (param_name_file);
+ ar = (GPtrArray *)g_value_get_boxed (gval);
}
+ g_ptr_array_add (ar, gval_tmp);
}
else
{
- tmp = g_strdup_printf ("%s--", _boundary);
- if (g_strcmp0 (line, tmp) == 0)
- {
- g_free (tmp);
- break;
- }
- g_free (tmp);
+ g_hash_table_replace (ht, g_strdup (param_name), gval_tmp);
}
- g_free (line);
- } while (i < l);
+ g_free (param_name);
+ g_free (param_value);
+ if (l_v_content == 3)
+ {
+ g_free (param_name_file);
+ }
+ }
g_free (_boundary);
}
/*
- * Copyright (C) 2015-2016 Andrea Zagli <azagli@libero.it>
+ * Copyright (C) 2015-2017 Andrea Zagli <azagli@libero.it>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
iostream = NULL;
gfile = g_file_new_tmp (g_strdup_printf ("cgi-XXXXXX-%s", zgfile->name),
- &iostream,
- NULL);
+ &iostream,
+ NULL);
ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
g_output_stream_write (ostream,
- zgfile->content,
- zgfile->size,
- NULL,
- NULL);
+ zgfile->content,
+ zgfile->size,
+ NULL,
+ NULL);
g_output_stream_close (ostream, NULL, NULL);
g_object_unref (ostream);
void
ht_foreach (gpointer key,
- gpointer value,
- gpointer user_data)
+ gpointer value,
+ gpointer user_data)
{
GString *str = (GString *)user_data;
g_string_append_printf (str, "<tr><td>%s</td><td>%s</td></tr>\n",
- (gchar *)key, g_value_get_string ((GValue *)value));
+ (gchar *)key, g_value_get_string ((GValue *)value));
}
void
ht_foreach_stdin (gpointer key,
- gpointer value,
- gpointer user_data)
+ gpointer value,
+ gpointer user_data)
{
gchar *ret;
{
ret = get_value (g_ptr_array_index (ar, i));
g_string_append_printf (str,
- "<tr><td>%s[%d]</td><td>%s</td></tr>\n",
- (gchar *)key, i, ret);
+ "<tr><td>%s[%d]</td><td>%s</td></tr>\n",
+ (gchar *)key, i, ret);
g_free (ret);
}
}
{
ret = get_value ((GValue *)value);
g_string_append_printf (str,
- "<tr><td>%s</td><td>%s</td></tr>\n",
- (gchar *)key, ret);
+ "<tr><td>%s</td><td>%s</td></tr>\n",
+ (gchar *)key, ret);
g_free (ret);
}
}
GHashTable *ht;
gchar *env;
gchar *ret;
-
+ sleep(10);
zakcgimain = zak_cgi_main_new ();
str = g_string_new ("<html>\n"
- "<head><title>Environment variables</title></head>\n"
- "<body>\n");
+ "<head><title>Environment variables</title></head>\n"
+ "<body>\n");
g_string_append_printf (str, "<table>\n");
zak_cgi_main_env_foreach (zakcgimain, ht_foreach, str);
if (env != NULL)
{
g_string_append_printf (str,
- "<br/><hr/>\n"
- "%s",
- env);
+ "<br/><hr/>\n"
+ "%s",
+ env);
g_string_append_printf (str, "<br/><hr/>\n<table>\n");
g_string_append_printf (str,
- "<tr><td>IS GET?</td><td>%s</td></tr>\n",
- zak_cgi_main_is_get (zakcgimain) ? "TRUE" : "FALSE");
+ "<tr><td>IS GET?</td><td>%s</td></tr>\n",
+ zak_cgi_main_is_get (zakcgimain) ? "TRUE" : "FALSE");
g_string_append_printf (str,
- "<tr><td>IS POST?</td><td>%s</td></tr>\n",
- zak_cgi_main_is_post (zakcgimain) ? "TRUE" : "FALSE");
+ "<tr><td>IS POST?</td><td>%s</td></tr>\n",
+ zak_cgi_main_is_post (zakcgimain) ? "TRUE" : "FALSE");
zak_cgi_main_stdin_foreach (zakcgimain, ht_foreach_stdin, str);