diff -burNp dillo-2.0/dpi/file.c dillo-2.0-dud/dpi/file.c --- dillo-2.0/dpi/file.c 2008-09-30 17:43:43.000000000 +0200 +++ dillo-2.0-dud/dpi/file.c 2009-03-24 10:39:52.201842188 +0100 @@ -15,6 +15,7 @@ * With new HTML layout. */ +#define _GNU_SOURCE #include #include /* for tolower */ @@ -36,6 +37,7 @@ #include "../dpip/dpip.h" #include "dpiutil.h" #include "d_size.h" +#include /* * Debugging macros @@ -77,7 +79,7 @@ typedef struct { /* * Forward references */ -static const char *File_content_type(const char *filename); +static const char *File_content_type(const char *filename, int *gzipped); static int File_get_file(ClientInfo *Client, const char *filename, struct stat *sb, @@ -344,6 +346,7 @@ static void File_info2html(ClientInfo *C filecont = "Executable"; } else { filecont = File_content_type(finfo->full_path); + filecont = File_content_type(finfo->full_path, NULL); if (!filecont || !strcmp(filecont, "application/octet-stream")) filecont = "unknown"; } @@ -467,13 +470,21 @@ static void File_transfer_dir(ClientInfo /* * Return a content type based on the extension of the filename. */ -static const char *File_ext(const char *filename) +static const char *File_ext(const char *filename, int *gzipped) { char *e; + char *e, *e2; if (!(e = strrchr(filename, '.'))) return NULL; + if ((e > filename) && !strcasecmp(e+1, "gz") && ((e2 = memrchr(filename, '.', e-filename)) != NULL)) { + e2++; + if (!strncasecmp(e2, "html.", 5) || !strncasecmp(e2, "htm.", 4) || !strncasecmp(e2, "shtml.", 6)) { + if(gzipped != NULL) *gzipped = 1; + return "text/html"; + } + } e++; if (!dStrcasecmp(e, "gif")) { @@ -496,7 +507,7 @@ static const char *File_ext(const char * * Based on the extension, return the content_type for the file. * (if there's no extension, analyze the data and try to figure it out) */ -static const char *File_content_type(const char *filename) +static const char *File_content_type(const char *filename, int *gzipped) { int fd; struct stat sb; @@ -504,7 +515,7 @@ static const char *File_content_type(con char buf[256]; ssize_t buf_size; - if (!(ct = File_ext(filename))) { + if (!(ct = File_ext(filename, gzipped))) { /* everything failed, let's analyze the data... */ if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) != -1) { if ((buf_size = read(fd, buf, 256)) == 256 ) { @@ -530,28 +541,40 @@ static void File_get(ClientInfo *Client, int res; struct stat sb; char *d_cmd; + char *tmp_filename = (char*)filename, *p; Dstr *ds = NULL; if (stat(filename, &sb) != 0) { + char *e = strrchr(filename, '.'); + if ((e == NULL) || strcasecmp(e + 1, "gz")) { + if ((p = malloc(strlen(filename) + 4)) != NULL) { + tmp_filename = p; + strcpy(tmp_filename, filename); + strcat(tmp_filename, ".gz"); + filename = tmp_filename; + } + } + } + if (stat(tmp_filename, &sb) != 0) { /* stat failed, prepare a file-not-found error. */ res = FILE_NOT_FOUND; } else if (S_ISDIR(sb.st_mode)) { /* set up for reading directory */ - res = File_get_dir(Client, filename, orig_url); + res = File_get_dir(Client, tmp_filename, orig_url); } else { /* set up for reading a file */ - res = File_get_file(Client, filename, &sb, orig_url); + res = File_get_file(Client, tmp_filename, &sb, orig_url); } if (res == FILE_NOT_FOUND) { ds = dStr_sized_new(128); - dStr_sprintf(ds, "%s Not Found: %s", - S_ISDIR(sb.st_mode) ? "Directory" : "File", filename); + dStr_sprintf(ds, "%s Not Found: %s", S_ISDIR(sb.st_mode) ? "Directory" : "File", tmp_filename); } else if (res == FILE_NO_ACCESS) { ds = dStr_sized_new(128); - dStr_sprintf(ds, "Access denied to %s: %s", - S_ISDIR(sb.st_mode) ? "Directory" : "File", filename); + dStr_sprintf(ds, "Access denied to %s: %s", S_ISDIR(sb.st_mode) ? "Directory" : "File", tmp_filename); } + if(tmp_filename != filename) + free(tmp_filename); if (ds) { d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s","send_status_message",ds->str); sock_handler_write_str(Client->sh, 1, d_cmd); @@ -599,7 +622,8 @@ static int File_get_file(ClientInfo *Cli const char *unknown_type = "application/octet-stream"; char buf[LBUF], *d_cmd, *name; int fd, st, namelen; - bool_t gzipped = FALSE; + int gzipped = 0; + gzFile gzdata; if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) < 0) return FILE_NO_ACCESS; @@ -628,6 +652,18 @@ static int File_get_file(ClientInfo *Cli /* Send HTTP headers */ if (gzipped) { sock_handler_write_str(Client->sh, 0, "Content-Encoding: gzip\n"); + gzdata = gzdopen(fd, "r"); + do { + if ((st = gzread(gzdata, buf, LBUF)) > 0) { + if (sock_handler_write(Client->sh, buf, st, 0) != 0) + break; + } else if (st < 0) { + perror("[read]"); + if (errno == EINTR || errno == EAGAIN) + continue; + } + } while (st > 0); + gzclose(gzdata); } if (!gzipped || strcmp(ct, unknown_type)) { sock_handler_printf(Client->sh, 0, "Content-Type: %s\n", ct); diff -burNp dillo-2.0/dpi/Makefile.am dillo-2.0-dud/dpi/Makefile.am --- dillo-2.0/dpi/Makefile.am 2008-04-26 23:29:10.000000000 +0200 +++ dillo-2.0-dud/dpi/Makefile.am 2009-03-24 10:40:40.881837317 +0100 @@ -20,7 +20,7 @@ downloads_dpi_LDADD = @LIBFLTK_LIBS@ ../ ftp_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a https_filter_dpi_LDADD = @LIBSSL_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a hello_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a -file_dpi_LDADD = @LIBPTHREAD_LIBS@ ../dpip/libDpip.a ../dlib/libDlib.a +file_dpi_LDADD = @GLIB_LIBS@ @LIBPTHREAD_LIBS@ ../dpip/libDpip.a -lz cookies_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a datauri_filter_dpi_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a