⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libhttpd.c.bak

📁 修改后的thttp
💻 BAK
📖 第 1 页 / 共 5 页
字号:
	return -1;	}    realloc_str( &hc->expnfilename, &hc->maxexpnfilename, strlen( cp ) );    (void) strcpy( hc->expnfilename, cp );    realloc_str( &hc->pathinfo, &hc->maxpathinfo, strlen( pi ) );    (void) strcpy( hc->pathinfo, pi );    /* Remove pathinfo stuff from the original filename too. */    if ( hc->pathinfo[0] != '\0' )	{	int i;	i = strlen( hc->origfilename ) - strlen( hc->pathinfo );	if ( i > 0 && strcmp( &hc->origfilename[i], hc->pathinfo ) == 0 )	    hc->origfilename[i - 1] = '\0';	}    /* If the expanded filename is an absolute path, check that it's still    ** within the current directory or the alternate directory.    */    if ( hc->expnfilename[0] == '/' )	{	if ( strncmp(		 hc->expnfilename, hc->hs->cwd, strlen( hc->hs->cwd ) ) == 0 )	    /* Elide the current directory. */	    (void) strcpy(		hc->expnfilename, &hc->expnfilename[strlen( hc->hs->cwd )] );	else if ( hc->altdir[0] != '\0' &&		  ( strncmp(		       hc->expnfilename, hc->altdir,		       strlen( hc->altdir ) ) != 0 ||		    ( hc->expnfilename[strlen( hc->altdir )] != '\0' &&		      hc->expnfilename[strlen( hc->altdir )] != '/' ) ) )	    {	    httpd_send_err( hc, 403, err403title, err403form, hc->encodedurl );	    return -1;	    }	}    hc->accept[0] = '\0';    hc->accepte[0] = '\0';    hc->remoteuser[0] = '\0';    hc->response[0] = '\0';    hc->responselen = 0;    hc->referer = "";    hc->useragent = "";    hc->cookie = "";    hc->contenttype = "";    hc->hdrhost = "";    hc->authorization = "";    hc->if_modified_since = (time_t) -1;    hc->range_if = (time_t) -1;    hc->contentlength = -1;    hc->got_range = 0;    hc->init_byte_loc = 0;    hc->end_byte_loc = -1;    hc->keep_alive = 0;    if ( hc->mime_flag )	{	/* Read the MIME headers. */	while ( ( buf = bufgets( hc ) ) != (char*) 0 )	    {	    if ( buf[0] == '\0' )		break;	    if ( strncasecmp( buf, "Referer:", 8 ) == 0 )		{		cp = &buf[8];		cp += strspn( cp, " \t" );		hc->referer = cp;		}	    else if ( strncasecmp( buf, "User-Agent:", 11 ) == 0 )		{		cp = &buf[11];		cp += strspn( cp, " \t" );		hc->useragent = cp;		}	    else if ( strncasecmp( buf, "Host:", 5 ) == 0 )		{		cp = &buf[5];		cp += strspn( cp, " \t" );		hc->hdrhost = cp;		}	    else if ( strncasecmp( buf, "Accept:", 7 ) == 0 )		{		cp = &buf[7];		cp += strspn( cp, " \t" );		if ( hc->accept[0] != '\0' )		    {		    if ( strlen( hc->accept ) > 5000 )			{			syslog(			    LOG_ERR, "%.80s way too much Accept: data",			    inet_ntoa( hc->client_addr ) );			continue;			}		    realloc_str(			&hc->accept, &hc->maxaccept,			strlen( hc->accept ) + 2 + strlen( cp ) );		    (void) strcat( hc->accept, ", " );		    }		else		    realloc_str( &hc->accept, &hc->maxaccept, strlen( cp ) );		(void) strcat( hc->accept, cp );		}	    else if ( strncasecmp( buf, "Accept-Encoding:", 16 ) == 0 )		{		cp = &buf[16];		cp += strspn( cp, " \t" );		if ( hc->accepte[0] != '\0' )		    {		    if ( strlen( hc->accepte ) > 5000 )			{			syslog(			    LOG_ERR, "%.80s way too much Accept-Encoding: data",			    inet_ntoa( hc->client_addr ) );			continue;			}		    realloc_str(			&hc->accepte, &hc->maxaccepte,			strlen( hc->accepte ) + 2 + strlen( cp ) );		    (void) strcat( hc->accepte, ", " );		    }		else		    realloc_str( &hc->accepte, &hc->maxaccepte, strlen( cp ) );		(void) strcpy( hc->accepte, cp );		}	    else if ( strncasecmp( buf, "If-Modified-Since:", 18 ) == 0 )		{		cp = &buf[18];		hc->if_modified_since = tdate_parse( cp );		if ( hc->if_modified_since == (time_t) -1 )		    syslog( LOG_DEBUG, "unparsable time: %.80s", cp );		}	    else if ( strncasecmp( buf, "Cookie:", 7 ) == 0 )		{		cp = &buf[7];		cp += strspn( cp, " \t" );		hc->cookie = cp;		}	    else if ( strncasecmp( buf, "Range:", 6 ) == 0 )		{		/* Only support %d- and %d-%d, not %d-%d,%d-%d or -%d. */		if ( strchr( buf, ',' ) == (char*) 0 )		    {		    char* cp_dash;		    cp = strpbrk( buf, "=" );		    if ( cp != (char*) 0 )			{			cp_dash = strchr( cp + 1, '-' );			if ( cp_dash != (char*) 0 && cp_dash != cp + 1 )			    {			    *cp_dash = '\0';			    hc->got_range = 1;			    hc->init_byte_loc = atol( cp + 1 );			    if ( isdigit( (int) cp_dash[1] ) )				hc->end_byte_loc = atol( cp_dash + 1 );			    }			}		    }		}	    else if ( strncasecmp( buf, "Range-If:", 9 ) == 0 ||	              strncasecmp( buf, "If-Range:", 9 ) == 0 )		{		cp = &buf[9];		hc->range_if = tdate_parse( cp );		if ( hc->range_if == (time_t) -1 )		    syslog( LOG_DEBUG, "unparsable time: %.80s", cp );		}	    else if ( strncasecmp( buf, "Content-Type:", 13 ) == 0 )		{		cp = &buf[13];		cp += strspn( cp, " \t" );		hc->contenttype = cp;		}	    else if ( strncasecmp( buf, "Content-Length:", 15 ) == 0 )		{		cp = &buf[15];		hc->contentlength = atol( cp );		}	    else if ( strncasecmp( buf, "Authorization:", 14 ) == 0 )		{		cp = &buf[14];		cp += strspn( cp, " \t" );		hc->authorization = cp;		}	    else if ( strncasecmp( buf, "Connection:", 11 ) == 0 )		{		cp = &buf[11];		cp += strspn( cp, " \t" );		if ( strcasecmp( cp, "keep-alive" ) == 0 )		    hc->keep_alive = 1;		}#ifdef LOG_UNKNOWN_HEADERS	    else if ( strncasecmp( buf, "Accept-Charset:", 15 ) == 0 ||	              strncasecmp( buf, "Accept-Language:", 16 ) == 0 ||	              strncasecmp( buf, "Agent:", 6 ) == 0 ||	              strncasecmp( buf, "Cache-Control:", 14 ) == 0 ||	              strncasecmp( buf, "Cache-Info:", 11 ) == 0 ||	              strncasecmp( buf, "Charge-To:", 10 ) == 0 ||	              strncasecmp( buf, "Client-ip:", 10 ) == 0 ||	              strncasecmp( buf, "Date:", 5 ) == 0 ||	              strncasecmp( buf, "Extension:", 10 ) == 0 ||	              strncasecmp( buf, "Forwarded:", 10 ) == 0 ||	              strncasecmp( buf, "From:", 5 ) == 0 ||	              strncasecmp( buf, "HTTP-Version:", 13 ) == 0 ||	              strncasecmp( buf, "Message-ID:", 11 ) == 0 ||	              strncasecmp( buf, "MIME-Version:", 13 ) == 0 ||	              strncasecmp( buf, "Negotiate:", 10 ) == 0 ||	              strncasecmp( buf, "Pragma:", 7 ) == 0 ||	              strncasecmp( buf, "Proxy-agent:", 12 ) == 0 ||	              strncasecmp( buf, "Proxy-Connection:", 17 ) == 0 ||	              strncasecmp( buf, "Security-Scheme:", 16 ) == 0 ||	              strncasecmp( buf, "Session-ID:", 11 ) == 0 ||	              strncasecmp( buf, "UA-color:", 9 ) == 0 ||	              strncasecmp( buf, "UA-CPU:", 7 ) == 0 ||	              strncasecmp( buf, "UA-Disp:", 8 ) == 0 ||	              strncasecmp( buf, "UA-OS:", 6 ) == 0 ||	              strncasecmp( buf, "UA-pixels:", 10 ) == 0 ||	              strncasecmp( buf, "User:", 5 ) == 0 ||	              strncasecmp( buf, "Via:", 4 ) == 0 ||	              strncasecmp( buf, "X-", 2 ) == 0 )		; /* ignore */	    else		syslog( LOG_DEBUG, "unknown request header: %.80s", buf );#endif /* LOG_UNKNOWN_HEADERS */	    }	}        if ( hc->one_one )	{	/* Check that HTTP/1.1 requests specify a host, as required. */	if ( hc->reqhost[0] == '\0' && hc->hdrhost[0] == '\0' )	    {	    httpd_send_err( hc, 400, httpd_err400title, httpd_err400form, "" );	    return -1;	    }	/* This is where we would check that the host specified is the	** host we're serving.  However, since we still only support one	** virtual host per thttpd process, it's not currently possible	** to use thttpd to serve the new HTTP/1.1-style CNAME-only	** virtual hosts.  Therefore, why bother checking for the correct	** host here?  It would just be something for the admin to screw	** up, with no benefit from getting it right.	*/	/* If the client wants to do keep-alives, it might also be doing	** pipelining.  There's no way for us to tell.  Since we don't	** implement keep-alives yet, if we close such a connection there	** might be unread pipelined requests waiting.  So, we have to	** do a lingering close.	*/	if ( hc->keep_alive )	    hc->should_linger = 1;	}    return 0;    }static char*bufgets( httpd_conn* hc )    {    int i;    char c;    for ( i = hc->checked_idx; hc->checked_idx < hc->read_idx; ++hc->checked_idx )	{	c = hc->read_buf[hc->checked_idx];	if ( c == '\n' || c == '\r' )	    {	    hc->read_buf[hc->checked_idx] = '\0';	    ++hc->checked_idx;	    if ( c == '\r' && hc->checked_idx < hc->read_idx &&		 hc->read_buf[hc->checked_idx] == '\n' )		{		hc->read_buf[hc->checked_idx] = '\0';		++hc->checked_idx;		}	    return &(hc->read_buf[i]);	    }	}    return (char*) 0;    }voidhttpd_close_conn( httpd_conn* hc, struct timeval* nowP )    {    if ( hc->file_address != (char*) 0 )	{	mmc_unmap( hc->file_address, nowP );	hc->file_address = (char*) 0;	}    if ( hc->conn_fd >= 0 )	{	(void) close( hc->conn_fd );	hc->conn_fd = -1;	}    }voidhttpd_destroy_conn( httpd_conn* hc )    {    if ( hc->initialized )	{	free( (void*) hc->decodedurl );	free( (void*) hc->origfilename );	free( (void*) hc->expnfilename );	free( (void*) hc->encodings );	free( (void*) hc->pathinfo );	free( (void*) hc->query );	free( (void*) hc->altdir );	free( (void*) hc->accept );	free( (void*) hc->accepte );	free( (void*) hc->reqhost );	free( (void*) hc->remoteuser );	free( (void*) hc->response );	hc->initialized = 0;	}    }/* Figures out MIME encodings and type based on the filename.  Multiple** encodings are separated by semicolons.*/static voidfigure_mime( httpd_conn* hc )    {    int i, j, k, l;    int got_enc;    struct table {	char* ext;	char* val;	};    static struct table enc_tab[] = {#include "mime_encodings.h"	};    static struct table typ_tab[] = {#include "mime_types.h"	};    /* Look at the extensions on hc->expnfilename from the back forwards. */    hc->encodings[0] = '\0';    i = strlen( hc->expnfilename );    for (;;)	{	j = i;	for (;;)	    {	    --i;	    if ( i <= 0 )		{		/* No extensions left. */		hc->type = "text/plain";		return;		}	    if ( hc->expnfilename[i] == '.' )		break;	    }	/* Found an extension. */	got_enc = 0;	for ( k = 0; k < sizeof(enc_tab)/sizeof(*enc_tab); ++k )	    {	    l = strlen( enc_tab[k].ext );	    if ( l == j - i - 1 &&		 strncasecmp( &hc->expnfilename[i+1], enc_tab[k].ext, l ) == 0 )		{		realloc_str(		    &hc->encodings, &hc->maxencodings,		    strlen( enc_tab[k].val ) + 1 );		if ( hc->encodings[0] != '\0' )		    (void) strcat( hc->encodings, ";" );		(void) strcat( hc->encodings, enc_tab[k].val );		got_enc = 1;		}	    }	if ( ! got_enc )	    {	    /* No encoding extension found - time to try type extensions. */	    for ( k = 0; k < sizeof(typ_tab)/sizeof(*typ_tab); ++k )		{		l = strlen( typ_tab[k].ext );		if ( l == j - i - 1 &&		     strncasecmp(			 &hc->expnfilename[i+1], typ_tab[k].ext, l ) == 0 )		    {		    hc->type = typ_tab[k].val;		    return;		    }		}	    /* No recognized type extension found - return default. */	    hc->type = "text/plain";	    return;	    }	}    }#ifdef CGI_TIMELIMITstatic voidcgi_kill2( ClientData client_data, struct timeval* nowP )    {    pid_t pid;    printf("CGI kill2\n");        pid = (pid_t) client_data.i;    if ( kill( pid, SIGKILL ) == 0 )	syslog( LOG_ERR, "hard-killed CGI process %d", pid );    }static voidcgi_kill( ClientData client_data, struct timeval* nowP )    {    pid_t pid;    /* Before trying to kill the CGI process, reap any zombie processes.    ** That may get rid of the CGI process.    */  printf("CGI kill\n");      (void) do_reap();    pid = (pid_t) client_data.i;    if ( kill( pid, SIGINT ) == 0 )	{	syslog( LOG_ERR, "killed CGI process %d", pid );	/* In case this isn't enough, schedule an uncatchable kill. */	(void) tmr_create( nowP, cgi_kill2, client_data, 5 * 1000L, 0 );	}    }#endif /* CGI_TIMELIMIT */#ifdef GENERATE_INDEXES/* qsort comparison routine - declared old-style on purpose, for portability. */static intname_compare( a, b )    char** a;    char** b;    {    return strcmp( *a, *b );    }static off_tls( httpd_conn* hc )    {    DIR* dirp;    struct dirent* de;    int namlen;    static int maxnames = 0;    int nnames;    static char* names;    static char** nameptrs;    static char* name;    static int maxname = 0;    static char* rname;    static int maxrname = 0;    FILE* fp;    int i, r;    struct stat sb;    struct stat lsb;    char modestr[20];    char* linkprefix;    char link[MAXPATHLEN];    int linklen;    char* fileclass;    time_t now;    char* timestr;    ClientData client_data;    dirp = opendir( hc->expnfilename );    if ( dirp == (DIR*) 0 )	{	syslog( LOG_ERR, "opendir %.80s - %m", hc->expnfilename );	httpd_send_err( hc, 404, err404title, err404form, hc->encodedurl );	return -1;	}    send_mime(	hc, 200, ok200title, "", "", "text/html", -1, hc->sb.st_mtime );    hc->bytes = 0;    if ( hc->method == METHOD_HEAD )	closedir( dirp );    else if ( hc->method == METHOD_GET )	{	httpd_write_response( hc );#ifdef EMBED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -