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

📄 webs.c

📁 一个典型的用于嵌入式Linux环境的Webserver
💻 C
📖 第 1 页 / 共 5 页
字号:
{	a_assert(websValid(wp));	a_assert(bytes >= 0);	wp->numbytes = bytes;}/******************************************************************************//* *	Set the flags for this request */void websSetRequestFlags(webs_t wp, int flags){	a_assert(websValid(wp));	wp->flags = flags;}/******************************************************************************//* *	Set the local path for the request */void websSetRequestLpath(webs_t wp, char_t *lpath){	a_assert(websValid(wp));	a_assert(lpath && *lpath);	if (wp->lpath) {		bfree(B_L, wp->lpath);	}	wp->lpath = bstrdup(B_L, lpath);	websSetVar(wp, T("PATH_TRANSLATED"), wp->lpath);}/******************************************************************************//* *	Update the URL path and the directory containing the web page */void websSetRequestPath(webs_t wp, char_t *dir, char_t *path){	char_t	*tmp;	a_assert(websValid(wp));	if (dir) { 		tmp = wp->dir;		wp->dir = bstrdup(B_L, dir);		if (tmp) {			bfree(B_L, tmp);		}	}	if (path) {		tmp = wp->path;		wp->path = bstrdup(B_L, path);		websSetVar(wp, T("PATH_INFO"), wp->path);		if (tmp) {			bfree(B_L, tmp);		}	}}/******************************************************************************//* *	Set the Write handler for this socket */void websSetRequestSocketHandler(webs_t wp, int mask, void (*fn)(webs_t wp)){	a_assert(websValid(wp));	wp->writeSocket = fn;	socketCreateHandler(wp->sid, SOCKET_WRITABLE, websSocketEvent, (int) wp);}/******************************************************************************//* *	Set the number of bytes written */void websSetRequestWritten(webs_t wp, int written){	a_assert(websValid(wp));	wp->written = written;}/******************************************************************************//* *	Reurn true if the webs handle is valid */int websValid(webs_t wp){	int		wid;	for (wid = 0; wid < websMax; wid++) {		if (wp == webs[wid]) {			return 1;		}	}	return 0;}/******************************************************************************//* *	Build an ASCII time string.  If sbuf is NULL we use the current time, *	else we use the last modified time of sbuf; */char_t *websGetDateString(websStatType *sbuf){	char_t*	cp, *r;	time_t	now;	if (sbuf == NULL) {		time(&now);	} else {		now = sbuf->mtime;	}	if ((cp = gctime(&now)) != NULL) {		cp[gstrlen(cp) - 1] = '\0';		r = bstrdup(B_L, cp);		return r;	}	return NULL;}/******************************************************************************//* *	Mark time. Set a timestamp so that, later, we can return the number of *	seconds since we made the mark. Note that the mark my not be a *	"real" time, but rather a relative marker. */void websSetTimeMark(webs_t wp){	wp->timestamp = time(0);}/******************************************************************************//* *	Get the number of seconds since the last mark. */static int websGetTimeSinceMark(webs_t wp){	return time(0) - wp->timestamp;}/******************************************************************************//* *	Store the new realm name */void websSetRealm(char_t *realmName){	a_assert(realmName);	gstrncpy(websRealm, realmName, TSZ(websRealm));}/******************************************************************************//* *	Return the realm name (used for authorization) */char_t *websGetRealm(){	return websRealm;}#ifdef WEBS_IF_MODIFIED_SUPPORT/******************************************************************************//*	 *	These functions are intended to closely mirror the syntax for HTTP-date  *	from RFC 2616 (HTTP/1.1 spec).  This code was submitted by Pete Bergstrom. *//*	 *	RFC1123Date	= wkday "," SP date1 SP time SP "GMT" *	RFC850Date	= weekday "," SP date2 SP time SP "GMT" *	ASCTimeDate	= wkday SP date3 SP time SP 4DIGIT * *	Each of these functions tries to parse the value and update the index to  *	the point it leaves off parsing. */typedef enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } MonthEnumeration;typedef enum { SUN, MON, TUE, WED, THU, FRI, SAT } WeekdayEnumeration;/******************************************************************************//*	 *	Parse an N-digit value */static int parseNDIGIT(char_t *buf, int digits, int *index) {	int tmpIndex, returnValue;	returnValue = 0;	for (tmpIndex = *index; tmpIndex < *index+digits; tmpIndex++) {		if (gisdigit(buf[tmpIndex])) {			returnValue = returnValue * 10 + (buf[tmpIndex] - T('0'));		}	}	*index = tmpIndex;		return returnValue;}/******************************************************************************//* *	Return an index into the month array */static int parseMonth(char_t *buf, int *index) {/*	 *	"Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" |  *	"Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec" */	int tmpIndex, returnValue;	returnValue = -1;	tmpIndex = *index;	switch (buf[tmpIndex]) {		case 'A':			switch (buf[tmpIndex+1]) {				case 'p':					returnValue = APR;					break;				case 'u':					returnValue = AUG;					break;			}			break;		case 'D':			returnValue = DEC;			break;		case 'F':			returnValue = FEB;			break;		case 'J':			switch (buf[tmpIndex+1]) {				case 'a':					returnValue = JAN;					break;				case 'u':					switch (buf[tmpIndex+2]) {						case 'l':							returnValue = JUL;							break;						case 'n':							returnValue = JUN;							break;					}					break;			}			break;		case 'M':			switch (buf[tmpIndex+1]) {				case 'a':					switch (buf[tmpIndex+2]) {						case 'r':							returnValue = MAR;							break;						case 'y':							returnValue = MAY;							break;					}					break;			}			break;		case 'N':			returnValue = NOV;			break;		case 'O':			returnValue = OCT;			break;		case 'S':			returnValue = SEP;			break;	}	if (returnValue >= 0) {		*index += 3;	}	return returnValue;}/******************************************************************************//*  *	Parse a year value (either 2 or 4 digits) */static int parseYear(char_t *buf, int *index) {	int tmpIndex, returnValue;	tmpIndex = *index;	returnValue = parseNDIGIT(buf, 4, &tmpIndex);	if (returnValue >= 0) {		*index = tmpIndex;	} else {		returnValue = parseNDIGIT(buf, 2, &tmpIndex);		if (returnValue >= 0) {/* *			Assume that any year earlier than the start of the  *			epoch for time_t (1970) specifies 20xx */			if (returnValue < 70) {				returnValue += 2000;			} else {				returnValue += 1900;			}			*index = tmpIndex;		}	}	return returnValue;}/******************************************************************************//*  *	The formulas used to build these functions are from "Calendrical Calculations",  *	by Nachum Dershowitz, Edward M. Reingold, Cambridge University Press, 1997. */#include <math.h>const int GregorianEpoch = 1;/******************************************************************************//* *  Determine if year is a leap year */int GregorianLeapYearP(long year) {	int		result;	long	tmp;		tmp = year % 400;	if ((year % 4 == 0) &&		(tmp != 100) &&		(tmp != 200) &&		(tmp != 300)) {		result = TRUE;	} else {		result = FALSE;	}	return result;}/******************************************************************************//* *  Return the fixed date from the gregorian date */long FixedFromGregorian(long month, long day, long year) {	long fixedDate;	fixedDate = (long)(GregorianEpoch - 1 + 365 * (year - 1) + 		floor((year - 1) / 4.0) -		floor((double)(year - 1) / 100.0) + 		floor((double)(year - 1) / 400.0) + 		floor((367.0 * ((double)month) - 362.0) / 12.0));	if (month <= 2) {		fixedDate += 0;	} else if (TRUE == GregorianLeapYearP(year)) {		fixedDate += -1;	} else {		fixedDate += -2;	}	fixedDate += day;	return fixedDate;}/******************************************************************************//* *  Return the gregorian year from a fixed date */long GregorianYearFromFixed(long fixedDate) {	long result, d0, n400, d1, n100, d2, n4, d3, n1, d4, year;	d0 =	fixedDate - GregorianEpoch;	n400 =	(long)(floor((double)d0 / (double)146097));	d1 =	d0 % 146097;	n100 =	(long)(floor((double)d1 / (double)36524));	d2 =	d1 % 36524;	n4 =	(long)(floor((double)d2 / (double)1461));	d3 =	d2 % 1461;	n1 =	(long)(floor((double)d3 / (double)365));	d4 =	(d3 % 365) + 1;	year =	400 * n400 + 100 * n100 + 4 * n4 + n1;	if ((n100 == 4) || (n1 == 4)) {		result = year;	} else {		result = year + 1;	}	return result;}/******************************************************************************//*  *	Returns the Gregorian date from a fixed date *	(not needed for this use, but included for completeness */#if 0GregorianFromFixed(long fixedDate, long *month, long *day, long *year) {	long priorDays, correction;	*year =			GregorianYearFromFixed(fixedDate);	priorDays =		fixedDate - FixedFromGregorian(1, 1, *year);	if (fixedDate < FixedFromGregorian(3,1,*year)) {		correction = 0;	} else if (true == GregorianLeapYearP(*year)) {		correction = 1;	} else {		correction = 2;	}	*month = (long)(floor((12.0 * (double)(priorDays + correction) + 373.0) / 367.0));	*day = fixedDate - FixedFromGregorian(*month, 1, *year);}#endif/******************************************************************************//*  *	Returns the difference between two Gregorian dates */long GregorianDateDifference(	long month1, long day1, long year1,								long month2, long day2, long year2) {	return FixedFromGregorian(month2, day2, year2) - 		FixedFromGregorian(month1, day1, year1);}/******************************************************************************//* *	Return the number of seconds into the current day */#define SECONDS_PER_DAY 24*60*60static int parseTime(char_t *buf, int *index) {/*	 *	Format of buf is - 2DIGIT ":" 2DIGIT ":" 2DIGIT */	int returnValue, tmpIndex, hourValue, minuteValue, secondValue;	hourValue = minuteValue = secondValue = -1;	returnValue = -1;	tmpIndex = *index;	hourValue = parseNDIGIT(buf, 2, &tmpIndex);	if (hourValue >= 0) {		tmpIndex++;		minuteValue = parseNDIGIT(buf, 2, &tmpIndex);		if (minuteValue >= 0) {			tmpIndex++;			secondValue = parseNDIGIT(buf, 2, &tmpIndex);		}	}	if ((hourValue >= 0) &&		(minuteValue >= 0) &&		(secondValue >= 0)) {		returnValue = (((hourValue * 60) + minuteValue) * 60) + secondValue;		*index = tmpIndex;	}	return returnValue;}/******************************************************************************//* *	Return the equivalent of time() given a gregorian date */static time_t dateToTimet(int year, int month, int day) {	long dayDifference;     /*       * Bug fix by Jeff Reeder (Jun 14, 2002): The 'month' parameter is       * numbered from  0 (Jan == 0), but FixedFromGregorian() takes       * months numbered from 1 (January == 1). We need to add 1       * to the month       */	dayDifference = FixedFromGregorian(month + 1, day, year) - 		FixedFromGregorian(1, 1, 1970);	return dayDifference * SECONDS_PER_DAY;}/******************************************************************************//* *	Return the number of seconds between Jan 1, 1970 and the parsed date *	(corresponds to documentation for time() function) */static time_t parseDate1or2(char_t *buf, int *index) {/*	 *	Format of buf is either *	2DIGIT SP month SP 4DIGIT *	or *	2DIGIT "-" month "-" 2DIGIT */	int		dayValue, monthValue, yearValue, tmpIndex;	time_t	returnValue;	returnValue = (time_t) -1;	tmpIndex = *index;	dayValue = monthValue = yearValue = -1;	if (buf[tmpIndex] == T(',')) {/*  *		Skip over the ", "  */		tmpIndex += 2; 		dayValue = parseNDIGIT(buf, 2, &tmpIndex);		if (dayValue >= 0) {/* *			Skip over the space or hyphen */			tmpIndex++; 			monthValue = parseMonth(buf, &tmpIndex);			if (monthValue >= 0) {/* *				Skip over the space or hyphen */				tmpIndex++; 				yearValue = parseYear(buf, &tmpIndex);			}		}		if ((dayValue >= 0) &&			(monthValue >= 0) &&			(yearValue >= 0)) {			if (yearValue < 1970) {/*				 *				Allow for Microsoft IE's year 1601 dates  *

⌨️ 快捷键说明

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