From nobody@FreeBSD.org  Wed Aug 15 03:07:01 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 9B7EA37B409
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 15 Aug 2001 03:07:00 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.4/8.11.4) id f7FA70076311;
	Wed, 15 Aug 2001 03:07:00 -0700 (PDT)
	(envelope-from nobody)
Message-Id: <200108151007.f7FA70076311@freefall.freebsd.org>
Date: Wed, 15 Aug 2001 03:07:00 -0700 (PDT)
From: Eugene Grosbein <eugen@svzserv.kemerovo.su>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH] Fixed segmentation fault in simple_httpd and some other bugfixes
X-Send-Pr-Version: www-1.0

>Number:         29725
>Category:       bin
>Synopsis:       [picobsd] [patch] fixed segmentation fault in simple_httpd and some other bugfixes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    dwmalone
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 15 03:10:17 PDT 2001
>Closed-Date:    Sat Aug 16 15:00:25 UTC 2008
>Last-Modified:  Sat Aug 16 15:00:25 UTC 2008
>Originator:     Eugene Grosbein
>Release:        FreeBSD 3.5-STABLE (the same applies to FreeBSD 4.3-STABLE and 5.0-CURRENT)
>Organization:
Svyaz-Service JSC
>Environment:
FreeBSD www.svzserv.kemerovo.su 3.5-STABLE FreeBSD 3.5-STABLE #0: Tue Aug  7 09:59:15 KRAST
2001     eu@www.svzserv.kemerovo.su:/home3/src/sys/compile/WWW  i386

>Description:
This PR fixes some bugs in /usr/src/release/picobsd/simple_httpd
and tries to clean up code.

* Fixed segmentation fault when serving request of 
  file without '.' in the name. Added file mime_t.h introducing 
  array mime_type[][] for mapping of file extentions to mime types 
  and string default_mime_type for unknown/missing extentions.
* The 'Content-length' header prepared but not sent - fixed.
* Fixed format string in init_servconnection() - missing "%d" added.
* Fixed format string for value of type off_t in http_request() -
  "%d" replaced with "%lld"
* Commented out unused variables ld, http1, msg in http_request()
* Commented out unused variables bflad, fd, lg in main()

>How-To-Repeat:
Build, configure and run simple_httpd.
Connect to it using telnet and try to 'GET' a file with an extention -
you will get no 'Content-length' header in the reply.
Try to 'GET' a file with no extention - you will get no file
and coredump of simple_httpd.


>Fix:
There are a patch for simple_httpd.c and new file mime_t.h for
including into tree. Feel free editing there but please commit fixes
for bugs.

/* start of mime_t.h */
#ifndef _MIME_T
#define _MIME_T

const char* default_mime_type = "application/octet-stream";

const char* mime_type[][2] = {
  { "txt",      "text/plain"            },
  { "htm",      "text/html"             },
  { "html",     "text/html"             },
  { "gif",      "image/gif"             },
  { "jpg",      "image/jpeg"            },
  { "mp3",      "audio/mpeg"            }
};

const int mime_type_max = sizeof(mime_type) / sizeof(mime_type[0]) - 1;

#endif
/* end of mime_t.h */

Here is a patch for simple_httpd.c from my local repository:

diff -u -r1.1.1.1 -r1.9
--- simple_httpd.c      2001/08/15 04:09:38     1.1.1.1
+++ simple_httpd.c      2001/08/15 09:32:34     1.9
@@ -47,6 +47,8 @@
 #include <time.h>
 #include <unistd.h>
 
+#include "mime_t.h"
+
 int             http_port = 80;
 int             daemonize = 1;
 int             verbose = 0;
@@ -99,7 +101,7 @@
                perror("bind socket");
                exit(1);
        }
-        if (verbose) printf("simple_httpd\n",http_port);
+        if (verbose) printf("simple_httpd:%d\n",http_port);
 }
 
 /*
@@ -191,14 +193,15 @@
  */
 http_request()
 {
-       int             fd, lg, ld, i; 
+       int             fd, lg, /*ld,*/ i; 
        int             cmd = 0;
-       int             http1 = 0;
+/*     int             http1 = 0; */
        char           *p, *par;
        char           *filename, *c;
+       size_t          fname_len;
        struct stat     file_status;
        char            req[1024];
-        char            msg[1024];
+/*      char            msg[1024]; */
        char            buff[8192];
 
        lg = read(con_sock, req, 1024);
@@ -231,10 +234,13 @@
 
        c = strtok(NULL, " ");
        if (fetch_mode[0] != NULL) strcpy(filename,fetch_mode); 
-       if (filename == NULL || 
-            strlen(filename)==1) filename="/index.html"; 
+       fname_len=strlen(filename);
+       if (filename == NULL || fname_len == 1) {
+         filename="/index.html";
+         fname_len=11;
+       }
 
-       while (filename[0]== '/') filename++;        
+       while (filename[0]== '/') { filename++; fname_len--; }
        
         /* CGI handling.  Untested */
         if (!strncmp(filename,"cgi-bin/",8))           
@@ -243,6 +249,7 @@
            if (par=strstr(filename,"?"))                        
               {
                *par=0;            
+/*             fname_len=par-filename;  // not used but note to the future */
                 par++;      
               } 
            if (access(filename,X_OK)) goto conti;
@@ -309,23 +316,22 @@
        http_output(httpd_server_ident);
        http_date();
 
-       sprintf(buff, "Content-length: %d\r\n", file_status.st_size);
-
-       if (strstr(filename,".txt")) {
-         strcpy(buff,"Content-type: text/plain\r\n");
-       } else if (strstr(filename,".html") || strstr(filename,".htm")) {
-           strcpy(buff,"Content-type: text/html\r\n");
-       } else if (strstr(filename,".gif")) {
-         strcpy(buff,"Content-type: image/gif\r\n");
-       } else if (strstr(filename,".jpg")) {
-         strcpy(buff,"Content-type: image/jpeg\r\n");
-       } else {
-         /* Take a guess at content if we don't have something already */
-         strcpy(buff,"Content-type: ");
-         strcat(buff,strstr(filename,".")+1);
-         strcat(buff,"\r\n");
-       }
+       sprintf(buff, "Content-length: %lld\r\n", file_status.st_size);
        write(con_sock, buff, strlen(buff));
+
+       strcpy(buff,"Content-type: ");
+       i=-1;
+        if (strchr(filename,'.'))      
+         for (i=mime_type_max; i>=0; i--)      /* file has an extention */
+           if ((c=strstr(filename,mime_type[i][0])))
+             if (filename+fname_len==c+strlen(mime_type[i][0])) {
+               strcat(buff,mime_type[i][1]);
+               break;
+             }
+             
+       if (i<0)                                /* extention is unknown */
+         strcat(buff,default_mime_type);       /* or file has no extention */
+       http_output(buff);
        
        strftime(buff, 50, "Last-Modified: %a, %d %h %Y %H:%M:%S %Z\r\n\r\n",
gmtime(&file_status.st_mtime));
        write(con_sock, buff, strlen(buff));
@@ -351,8 +357,8 @@
 {
         extern char *optarg;
         extern int optind;
-        int bflag, ch, fd, ld;
-        int             lg;
+        int /*bflag,*/ ch, /*fd,*/ ld;
+/*      int             lg; */
        int             httpd_group = 65534;
         pid_t server_pid;



>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: asmodai 
State-Changed-When: Sun Apr 7 13:06:23 PDT 2002 
State-Changed-Why:  
I am already working on this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=29725 
Responsible-Changed-From-To: freebsd-bugs->asmodai 
Responsible-Changed-By: johan 
Responsible-Changed-When: Tue Apr 23 17:58:03 PDT 2002 
Responsible-Changed-Why:  
Can you close this when you are done with  
the changes to simple_httpd, please. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=29725 
Responsible-Changed-From-To: asmodai->freebsd-bugs 
Responsible-Changed-By: blackend 
Responsible-Changed-When: Mon Aug 5 11:23:20 PDT 2002 
Responsible-Changed-Why:  
asmodai requested it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=29725 

From: Eugene Grosbein <eugen@kuzbass.ru>
To: bug-followup@freebsd.org
Cc:  
Subject: bin/29725
Date: Wed, 01 Jan 2003 13:56:12 +0700

 Here is an updated version of simple_httpd and ChangeLog therein:
 ftp://www.kuzbass.ru/pub/freebsd/simple_httpd.tar.bz2
 
 All found bugs are fixed, added a couple of features, still tiny size
 of source and compiled code, performance improved.

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: bin/29725
Date: Sat, 1 Mar 2003 23:44:21 +0700

 Hi!
 
 asmodai resigned longh time ago, so this PR is not analyzed really.
 Please change its state back to `open', I hope somebody will take it then.
 
 Eugene Grosbein
State-Changed-From-To: analyzed->open 
State-Changed-By: keramida 
State-Changed-When: Tue Mar 4 17:14:30 PST 2003 
State-Changed-Why:  
Reopen this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=29725 
Responsible-Changed-From-To: freebsd-bugs->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Thu Mar 13 13:58:22 PST 2003 
Responsible-Changed-Why:  
I'll have a look at this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=29725 

From: Eugene Grosbein <eugen@kuzbass.ru>
To: dwmalone@freebsd.org
Cc: bug-followup@freebsd.org
Subject: Re: bin/29725: [PATCH] Fixed segmentation fault in simple_httpd and some 
 other bugfixes
Date: Tue, 13 May 2003 12:15:01 +0800

 Hi!
 
 Do you plan to deal with this PR?
 
 Eugene Grosbein

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc: dwmalone@freebsd.org
Subject: Re: bin/29725: [PATCH] Fixed segmentation fault in simple_httpd and some other bugfixes
Date: Sun, 8 Aug 2004 22:51:57 +0800

 Hi!
 
 It seems that dwmalone@freebsd.org does not have time to deal with this PR -
 a year is gone since he touched it. Please change responsibility
 back to freebsd-bugs, I hope somebody else will take it.
 
 Eugene Grosbein

From: David Malone <dwmalone@maths.tcd.ie>
To: Eugene Grosbein <eugen@grosbein.pp.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/29725: [PATCH] Fixed segmentation fault in simple_httpd and some other bugfixes 
Date: Sun, 08 Aug 2004 17:50:22 +0100

 > It seems that dwmalone@freebsd.org does not have time to deal with this PR -
 > a year is gone since he touched it. Please change responsibility
 > back to freebsd-bugs, I hope somebody else will take it.
 
 Doh! Sorry - I've finished cleaning up the patch and I've included
 the mime type bits of the patch are below. If you think it looks
 OK, I'll commit it this evening. The changes from your original
 patch are:
 
 1) Don't make a mime_types.h 'cos we should avoid creating variables
    in header files (declaring them is OK, but we were defining them).
 2) Use strrchr to find the extension, rather than strchr.
 3) Slightly simplify the mime-type matching loop.
 
 I think I had committed the other bits of the patch already?
 
 	David.
 
 
 Index: Makefile
 ===================================================================
 RCS file: /cvs/FreeBSD-CVS/src/release/picobsd/tinyware/simple_httpd/Makefile,v
 retrieving revision 1.6
 diff -u -r1.6 Makefile
 --- Makefile	28 Aug 1999 01:33:59 -0000	1.6
 +++ Makefile	8 Aug 2004 16:02:49 -0000
 @@ -3,5 +3,7 @@
  PROG=simple_httpd
  SRCS= 	simple_httpd.c
  NOMAN=yes
 +WARNS?=6
 +CFLAGS+=-g -O2
  
  .include <bsd.prog.mk>
 Index: simple_httpd.c
 ===================================================================
 RCS file: /cvs/FreeBSD-CVS/src/release/picobsd/tinyware/simple_httpd/simple_httpd.c,v
 retrieving revision 1.15
 diff -u -r1.15 simple_httpd.c
 --- simple_httpd.c	5 Apr 2003 17:15:38 -0000	1.15
 +++ simple_httpd.c	8 Aug 2004 16:38:43 -0000
 @@ -71,6 +71,19 @@
  
  static char http_200[] = "HTTP/1.0 200 OK\r";
  
 +const char *default_mime_type = "application/octet-stream";
 +
 +const char *mime_type[][2] = {
 +    { "txt",      "text/plain"            },
 +    { "htm",      "text/html"             },
 +    { "html",     "text/html"             },
 +    { "gif",      "image/gif"             },
 +    { "jpg",      "image/jpeg"            },
 +    { "mp3",      "audio/mpeg"            }
 +};
 +
 +const int mime_type_max = sizeof(mime_type) / sizeof(mime_type[0]) - 1;
 +
  /* Two parts, HTTP Header and then HTML */
  static const char *http_404[2] = 
      {"HTTP/1.0 404 Not found\r\n", 
 @@ -205,7 +218,7 @@
  	int             fd, lg, i; 
  	int             cmd = 0;
  	char           *p, *par;
 -	const char     *filename, *c;
 +	const char     *filename, *c, *ext, *type;
  	struct stat     file_status;
  	char            req[1024];
  	char            buff[8192];
 @@ -321,21 +334,17 @@
  	sprintf(buff, "Content-length: %lld\r\n", file_status.st_size);
  	write(con_sock, buff, strlen(buff));
  
 -	if (strstr(filename,".txt")) {
 -	  strcpy(buff,"Content-type: text/plain\r\n");
 -	} else if (strstr(filename,".html") || strstr(filename,".htm")) {
 -	    strcpy(buff,"Content-type: text/html\r\n");
 -	} else if (strstr(filename,".gif")) {
 -	  strcpy(buff,"Content-type: image/gif\r\n");
 -	} else if (strstr(filename,".jpg")) {
 -	  strcpy(buff,"Content-type: image/jpeg\r\n");
 -	} else {
 -	  /* Take a guess at content if we don't have something already */
 -	  strcpy(buff,"Content-type: ");
 -	  strcat(buff,strstr(filename,".")+1);
 -	  strcat(buff,"\r\n");
 +	strcpy(buff, "Content-type: ");
 +	type = default_mime_type;
 +	if ((ext = strrchr(filename, '.')) != NULL) {
 +	  for (i = mime_type_max; i >= 0; i--)
 +	    if (strcmp(ext + 1, mime_type[i][0]) == 0) {
 +	      type = mime_type[i][1];
 +	      break;
 +	    }
  	}
 -	write(con_sock, buff, strlen(buff));
 +	strcat(buff, type);
 +	http_output(buff);
  	
  	strftime(buff, 50, "Last-Modified: %a, %d %h %Y %H:%M:%S %Z\r\n\r\n", gmtime(&file_status.st_mtime));
  	write(con_sock, buff, strlen(buff));
State-Changed-From-To: open->closed 
State-Changed-By: dwmalone 
State-Changed-When: Sat Aug 16 15:00:00 UTC 2008 
State-Changed-Why:  
Seems that I committed this ages ago. 

David. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=29725 
>Unformatted:
