From 6ae861c7c1de9cf5534b959aa5a8f938d4f34771 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Fri, 2 Jun 2023 18:49:35 +0200 Subject: [PATCH] manage content-encoding --- file.c | 48 ++++++++++++++++++++++++++++++------- file.h | 4 +++- http.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++---- webserver.c | 2 +- 4 files changed, 107 insertions(+), 15 deletions(-) diff --git a/file.c b/file.c index 472ab42..fdcd1ee 100644 --- a/file.c +++ b/file.c @@ -16,10 +16,10 @@ int readfile (char **buffer, char *filename) /* open file */ - VERBOSE (DEBUG, PRINT ("Opening file %s\n", filename)); + VERBOSE (DEBUG, PRINT ("Opening file %s for reading\n", filename)); FILE *fd = fopen (filename, "rb"); if (fd == NULL) { - VERBOSE (WARNING, PRINT ("Can't open file (%s)\n", filename)); + VERBOSE (WARNING, PRINT ("Can't open file (%s) for reading\n", filename)); return -1; } @@ -32,28 +32,60 @@ int readfile (char **buffer, char *filename) VERBOSE (DEBUG, PRINT ("Reading %d bytes\n", size)); *buffer = calloc (size + 1, 1); - fread (*buffer, size, 1, fd); + int len = fread (*buffer, size, 1, fd); + if (len != size) { + VERBOSE (WARNING, PRINT ("Can't read full file (%s)\n", filename)); + } fclose (fd); - (*buffer)[size] = 0; - return size; + (*buffer)[len] = 0; + return len; } /* temp name */ -char *tempname (char *tempdir) +char *tempname (char *tempdir, char *ext) { char table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; - unsigned int len = strlen (tempdir) + 1 + 4 + TLEN + 1; + unsigned int len = strlen (tempdir) + 1 + 4 + TLEN + ((ext) ? strlen (ext) : 0) + 1; char *name = (char *) calloc (len, 1); sprintf (name, "%s/tmp-", tempdir); - while (strlen (name) + 1 < len) { + while (strlen (name) + 1 < len - ((ext) ? strlen (ext) : 0)) { name[strlen (name)] = table[rand () % 64]; } + if (ext) { + strcat (name, ext); + } return name; } +/* write full file */ + +int writefile (char *filename, char *buffer, int size) +{ + + /* open file */ + + VERBOSE (DEBUG, PRINT ("Opening file %s for writing\n", filename)); + FILE *fd = fopen (filename, "wb"); + if (fd == NULL) { + VERBOSE (WARNING, PRINT ("Can't open file (%s) for writing\n", filename)); + return -1; + } + + /* write full file */ + + VERBOSE (DEBUG, PRINT ("Writing %d bytes\n", size)); + int len = fwrite (buffer, size, 1, fd); + if (len != size) { + VERBOSE (WARNING, PRINT ("Can't write full file (%s)\n", filename)); + } + fclose (fd); + + return len; +} + /* vim: set ts=4 sw=4 et: */ diff --git a/file.h b/file.h index 106f881..86fdb4f 100644 --- a/file.h +++ b/file.h @@ -3,7 +3,9 @@ int readfile (char **buffer, char *filename); -char *tempname (char *tempdir); +char *tempname (char *tempdir, char *ext); + +int writefile (char *filename, char *buffer, int size); #endif /* __FILE_H__ */ diff --git a/http.c b/http.c index 044ab36..2f37611 100644 --- a/http.c +++ b/http.c @@ -310,6 +310,15 @@ char *trim (char *str) return str; } +/* creqte command */ + +char *createcommand (char *format, char *name) +{ + char *command = (char *) calloc (strlen (format) + strlen (name) + 1, 1); + sprintf (command, format, name); + return command; +} + /* main HTTP processing */ int processing (char *data, int len, conf_t *conf, char **pdata) @@ -362,7 +371,7 @@ int processing (char *data, int len, conf_t *conf, char **pdata) if (*line == 0) { break; } - + VERBOSE (DEBUG, PRINT ("Analyse field\n")); if (strcmp (field, "Allow") == 0) { header.allow = value; } else if (strcmp (field, "Authorization") == 0) { header.authorization = value; } @@ -393,15 +402,62 @@ int processing (char *data, int len, conf_t *conf, char **pdata) /* body */ char *body = data; + char *newbody = NULL; len -= saved_data - data; if (len != (header.content_length ? atoi (header.content_length) : 0)) { VERBOSE (WARNING, PRINT ("Incoherent size (%d <> %s)\n", len, header.content_length)); } if (len > 0) { + int i; + char *fcomp= NULL; + char *fdecomp = NULL; + char *command = NULL; + switch (header.content_encoding) { - case encoding_plain_e: break; - case encoding_gzip_e: VERBOSE (WARNING, PRINT ("Gzip encoding not supported yet\n")); break; - case encoding_compress_e: VERBOSE (WARNING, PRINT ("Compress encoding not supported yet\n")); break; + case encoding_plain_e: + break; + + case encoding_gzip_e: + fcomp = tempname (conf->temp, ".gz"); + writefile (fcomp, body, len); + command = createcommand ("gunzip %s", fcomp); + system (command); + fdecomp = strdup (fcomp); + for (i = strlen (fdecomp) - 1; i > 0; i--) { + if (fdecomp[i] == '.') { + fdecomp[i] = 0; + break; + } + } + len = readfile (&newbody, fdecomp); + break; + + case encoding_compress_e: + fcomp = tempname (conf->temp, ".Z"); + writefile (fcomp, body, len); + command = createcommand ("compress %s", fcomp); + system (command); + fdecomp = strdup (fcomp); + for (i = strlen (fdecomp) - 1; i > 0; i--) { + if (fdecomp[i] == '.') { + fdecomp[i] = 0; + break; + } + } + len = readfile (&newbody, fdecomp); + break; + } + + if (fcomp) { + unlink (fcomp); + free (fcomp); + } + if (fdecomp) { + unlink (fdecomp); + free (fdecomp); + } + if (command) { + free (command); } } @@ -441,9 +497,11 @@ int processing (char *data, int len, conf_t *conf, char **pdata) /* cleaning */ VERBOSE (DEBUG, PRINT ("Cleaning\n")); if (path) { - VERBOSE (DEBUG, PRINT ("Cleaning path\n")); free (path); } + if (newbody) { + free (newbody); + } return len; } diff --git a/webserver.c b/webserver.c index bca0262..555afbf 100644 --- a/webserver.c +++ b/webserver.c @@ -157,7 +157,7 @@ int main (int argc, char *argv[]) VERBOSE (ERROR, PERROR ("Can't read directory (%s)\n", temp)); return 1; } - char *ntemp = tempname (temp); + char *ntemp = tempname (temp, NULL); FILE *ftemp = fopen (ntemp, "w"); if (ftemp == NULL) { VERBOSE (ERROR, PERROR ("Can't write temporary file (%s)\n", ntemp)); -- 2.30.2