List Archive

Thread

Thread Index

Message

From: Lisa Matias <lisa.matias%gmail.com@localhost>
To: Thomas Klausner <tk%giga.or.at@localhost>
Subject: Re: ZIP_CREATE flag for zip_fdopen issues
Date: Thu, 5 Jan 2017 06:37:42 -0800

Hi Thomas:

The RAM disk option is not possible since for security, the CGI web application runs in chroot() set to an isolated directory with no other access to the web server file-system, so it cannot access /tmp.  Furthermore, I do not have root/administer access on the web server this will be deployed on to set up any other RAM disks.

The example/in-memory.c is different than my intended usage, so I am still unclear on how to do this properly.

Please consider this simple code example...

// #########################################
static char file1 [] = "This is the contents of the first file!";
static char file2 [] = "This is the contents of the second file!";
static char file3 [] = "This is the contents of the third file!";

static unsigned char zipBuffer [65536];  // 64kB buffer for ZIP which is more than large enough
zip_source_t *zipSource, *zipFile;
zip_error_t zipError;
zip_t *zip;

memset (zipBuffer, 0, sizeof (zipBuffer));
zip_error_init (&zipError);
if (!(zipSource = zip_source_buffer_create (zipBuffer, sizeof (zipBuf), 0, &zipError)))
    printf ("zip_source_buffer_create() error\n");
else if (!(zip = zip_open_from_source (zipSource, ZIP_TRUNCATE | ZIP_CREATE, &zipError)))
    printf ("zip_open_from_source() error\n");
else if (!(zipFile = zip_source_buffer (zip, file1, sizeof (file1) - 1, 0)))
    printf ("zip_source_buffer() error\n");
else if (0 != zip_file_add (zip, "first.txt", zipFile, ZIP_FL_ENC_UTF_8))
    printf ("zip_file_add() error\n");
else if (!(zipFile = zip_source_buffer (zip, file2, sizeof (file2) - 1, 0)))
    printf ("zip_source_buffer() error!\n");
else if (1 != zip_file_add (zip, "second.txt", zipFile, ZIP_FL_ENC_UTF_8))
    printf ("zip_file_add() error\n");
else if (!(zipFile = zip_source_buffer (zip, file3, sizeof (file3) - 1, 0)))
    printf ("zip_source_buffer() error\n");
else if (2 != zip_file_add (zip, "third.txt", zipFile, ZIP_FL_ENC_UTF_8))
    printf ("zip_file_add() error!\n");
else {
    zip_close (zip);
    printf ("zip created in memory\n");
    // Note that zipBuffer is empty!
}
zip_error_fini (&zipError);
// #########################################

I am able to compile this without warnings (with gcc and "-Wall" option), and when I run this I get the output "zip created in memory", which would indicate that the ZIP file should have been created in the zipBuffer in memory.

But when I do a HEX dump of all 64kB of zipBuffer, every byte is set to zero, so it remains empty.

Could you or anyone else please advice on how to properly create a new ZIP archive in memory with the 3 trivial files I specified?

Thanks.

Lisa.


On 3 January 2017 at 08:38, Thomas Klausner <tk%giga.or.at@localhost> wrote:
On Tue, Jan 03, 2017 at 08:35:50AM -0800, Lisa Matias wrote:
> I have a web server CGI application which needs to dynamically create a
> unique ZIP archive which is sent via the web socket (file descriptor) to
> the user's browser for download.
>
> Since the web server is running on Debian Linux, the goal is to avoid
> having to create and use temporary files, especially since the ZIP archive
> will only contain 3 dynamic files that are specified in 3 unsigned
> character (UINT8_T) buffers.  Creating unnecessary temporary files will
> only result in causing significant flash aging on the web server's SSD.
>
> However, there seems to be issues with using the ZIP_CREATE flag for
> zip_fdopen().
>
> Looking at the man page: https://nih.at/libzip/zip_fdopen.html
>
> The ZIP_CREATE is not even specified as flag for "zip_fdopen()" as it is
> for "zip_open()".

zip_fdopen is not for writing. The man page you point to mentions that:

"In contrast to zip_open(3), using zip_fdopen the archive can only be
opened in read-only mode."

> Any advice on how to do this properly with libzip?

Perhaps you want to create the zip file in memory instead?

See examples/in-memory.c for how to do that.

(Having /tmp on a memory file system would be another workaround.)

Cheers,
 Thomas

Made by MHonArc.