diff -urN dillo-0.8.6.orig/dpi/file.c dillo-0.8.6/dpi/file.c --- dillo-0.8.6.orig/dpi/file.c 2006-04-11 19:50:23.000000000 +0200 +++ dillo-0.8.6/dpi/file.c 2006-08-20 20:27:22.392356500 +0200 @@ -15,6 +15,7 @@ * With new HTML layout. */ +#define _GNU_SOURCE #include #include /* for tolower */ @@ -33,6 +34,7 @@ #include #include #include +#include #include "../dpip/dpip.h" #include "dpiutil.h" @@ -73,7 +75,7 @@ /* * Forward references */ -static const char *File_content_type(const char *filename); +static const char *File_content_type(const char *filename, int *gzipped); static gint File_get_file(ClientInfo *Client, const gchar *filename, struct stat *sb, @@ -343,7 +345,7 @@ } else if (finfo->mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { 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"; } @@ -468,13 +470,24 @@ /* * 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 (!strcasecmp(e, "gif")) { @@ -497,7 +510,7 @@ * 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) { gint fd; struct stat sb; @@ -505,7 +518,7 @@ gchar 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 ) { @@ -531,25 +544,39 @@ int res; struct stat sb; char *msg = NULL, *d_cmd; + char *tmp_filename = (char*)filename, *p; 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) { msg = g_strdup_printf("%s Not Found: %s", - S_ISDIR(sb.st_mode) ? "Directory" : "File", filename); + S_ISDIR(sb.st_mode) ? "Directory" : "File", tmp_filename); } else if (res == FILE_NO_ACCESS) { msg = g_strdup_printf("Access denied to %s: %s", - S_ISDIR(sb.st_mode) ? "Directory" : "File", filename); + S_ISDIR(sb.st_mode) ? "Directory" : "File", tmp_filename); } + if(tmp_filename != filename) + free(tmp_filename); if (msg) { d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_status_message", msg); sock_handler_write_str(Client->sh, d_cmd, 1); @@ -596,6 +623,8 @@ const gchar *ct; char buf[LBUF], *d_cmd; gint fd, st; + int gzipped = 0; + gzFile gzdata; if ( (fd = open(filename, O_RDONLY | O_NONBLOCK)) < 0) return FILE_NO_ACCESS; @@ -604,7 +633,7 @@ * known extension, then we do data sniffing. If this doesn't lead * to a conclusion, "application/octet-stream" is sent. */ - if (!(ct = File_content_type(filename))) + ct = File_content_type(filename, &gzipped); ct = "application/octet-stream"; /* Send DPI command */ @@ -612,6 +641,24 @@ sock_handler_write_str(Client->sh, d_cmd, 1); g_free(d_cmd); + if (gzipped) { + /* Send HTTP stream */ + sock_handler_printf(Client->sh, 0, + "Content-Type: %s\n\n", ct); + + 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); + } else { /* Send HTTP stream */ sock_handler_printf(Client->sh, 0, "Content-Type: %s\n" @@ -629,6 +676,7 @@ continue; } } while (st > 0); + } /* todo: It may be better to send an error report to dillo instead of * calling abort from g_error() */ diff -urN dillo-0.8.6.orig/dpi/Makefile.am dillo-0.8.6/dpi/Makefile.am --- dillo-0.8.6.orig/dpi/Makefile.am 2006-01-03 21:16:10.000000000 +0100 +++ dillo-0.8.6/dpi/Makefile.am 2006-08-20 20:10:16.412236750 +0200 @@ -27,7 +27,7 @@ ftp_filter_dpi_LDADD = @GLIB_LIBS@ ../dpip/libDpip.a https_filter_dpi_LDADD = @GLIB_LIBS@ @LIBSSL_LIBS@ ../dpip/libDpip.a hello_filter_dpi_LDADD = @GLIB_LIBS@ ../dpip/libDpip.a -file_dpi_LDADD = @GLIB_LIBS@ @LIBPTHREAD_LIBS@ ../dpip/libDpip.a +file_dpi_LDADD = @GLIB_LIBS@ @LIBPTHREAD_LIBS@ ../dpip/libDpip.a -lz cookies_dpi_LDADD = @GLIB_LIBS@ ../dpip/libDpip.a datauri_filter_dpi_LDADD = @GLIB_LIBS@ ../dpip/libDpip.a