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

📄 default.c

📁 一个典型的用于嵌入式Linux环境的Webserver
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * default.c -- Default URL handler. Includes support for ASP. * * Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved. * * See the file "license.txt" for usage and redistribution license requirements * * $Id: default.c,v 1.9 2003/04/11 18:10:28 bporter Exp $ *//******************************** Description *********************************//* *	This module provides default URL handling and Active Server Page support. * *	In many cases we don't check the return code of calls to websWrite as *	it is easier, smaller and non-fatal to continue even when the requesting *	browser has gone away. *//********************************* Includes ***********************************/#include	"wsIntrn.h"/*********************************** Locals ***********************************/static char_t	*websDefaultPage;			/* Default page name */static char_t	*websDefaultDir;			/* Default Web page directory *//**************************** Forward Declarations ****************************/static void websDefaultWriteEvent(webs_t wp);/*********************************** Code *************************************//* *	Process a default URL request. This will validate the URL and handle "../" *	and will provide support for Active Server Pages. As the handler is the *	last handler to run, it always indicates that it has handled the URL  *	by returning 1.  */int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,						char_t *url, char_t *path, char_t *query){	websStatType	sbuf;	char_t			*lpath, *tmp, *date;	int				bytes, flags, nchars;	a_assert(websValid(wp));	a_assert(url && *url);	a_assert(path);	a_assert(query);/* *	Validate the URL and ensure that ".."s don't give access to unwanted files */	flags = websGetRequestFlags(wp);	if (websValidateUrl(wp, path) < 0)    {      /*        * preventing a cross-site scripting exploit -- you may restore the       * following line of code to revert to the original behavior...       */		/*websError(wp, 500, T("Invalid URL %s"), url);*/      websError(wp, 500, T("Invalid URL"));		return 1;	}	lpath = websGetRequestLpath(wp);	nchars = gstrlen(lpath) - 1;	if (lpath[nchars] == '/' || lpath[nchars] == '\\') {		lpath[nchars] = '\0';	}/* *	If the file is a directory, redirect using the nominated default page */	if (websPageIsDirectory(lpath)) {		nchars = gstrlen(path);		if (path[nchars-1] == '/' || path[nchars-1] == '\\') {			path[--nchars] = '\0';		}		nchars += gstrlen(websDefaultPage) + 2;		fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);		websRedirect(wp, tmp);		bfreeSafe(B_L, tmp);		return 1;	}/* *	Open the document. Stat for later use. */	if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY, 		0666) < 0)    {      /* 10 Dec 02 BgP -- according to        * <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>,        * the proper code to return here is NOT 400 (old code), which is used       * to indicate a malformed request. Here, the request is good, but the       * error we need to tell the client about is 404 (Not Found).       */      /*        * 17 Mar 03 BgP -- prevent a cross-site scripting exploit		websError(wp, 404, T("Cannot open URL %s"), url);       */      		websError(wp, 404, T("Cannot open URL"));		return 1;	} 	if (websPageStat(wp, lpath, path, &sbuf) < 0) {      /*       * 17 Mar 03 BgP       * prevent a cross-site scripting exploit		websError(wp, 400, T("Cannot stat page for URL %s"), url);       */		websError(wp, 400, T("Cannot stat page for URL"));		return 1;	}/* *	If the page has not been modified since the user last received it and it *	is not dynamically generated each time (ASP), then optimize request by *	sending a 304 Use local copy response */	websStats.localHits++;#ifdef WEBS_IF_MODIFIED_SUPPORT	if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {		if (sbuf.mtime <= wp->since) {			websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));/* *			by license terms the following line of code must *			not be modified. */			websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);			if (flags & WEBS_KEEP_ALIVE) {				websWrite(wp, T("Connection: keep-alive\r\n"));			}			websWrite(wp, T("\r\n"));			websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);			websDone(wp, 304);			return 1;		}	}#endif/* *	Output the normal HTTP response header */	if ((date = websGetDateString(NULL)) != NULL) {		websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);/* *		By license terms the following line of code must not be modified. */		websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);		bfree(B_L, date);	}	flags |= WEBS_HEADER_DONE;/* *	If this is an ASP request, ensure the remote browser doesn't cache it. *	Send back both HTTP/1.0 and HTTP/1.1 cache control directives */	if (flags & WEBS_ASP) {		bytes = 0;		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));	} else {		if ((date = websGetDateString(&sbuf)) != NULL) {			websWrite(wp, T("Last-modified: %s\r\n"), date);			bfree(B_L, date);		}		bytes = sbuf.size;	}	if (bytes) {		websWrite(wp, T("Content-length: %d\r\n"), bytes);		websSetRequestBytes(wp, bytes);	}	websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));	if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {		websWrite(wp, T("Connection: keep-alive\r\n"));	}	websWrite(wp, T("\r\n"));/* *	All done if the browser did a HEAD request */	if (flags & WEBS_HEAD_REQUEST) {		websDone(wp, 200);		return 1;	}/* *	Evaluate ASP requests */	if (flags & WEBS_ASP) {		if (websAspRequest(wp, lpath) < 0) {			return 1;		}		websDone(wp, 200);		return 1;	}#ifdef WEBS_SSL_SUPPORT	if (wp->flags & WEBS_SECURE) {		websDefaultWriteEvent(wp);	} else {		websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);	}#else/* *	For normal web documents, return the data via background write */	websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);#endif	return 1;}#ifdef WIN32static int badPath(char_t* path, char_t* badPath, int badLen){   int retval = 0;   int len = gstrlen(path);   int i = 0;   if (len <= badLen +1)   {      for (i = 0; i < badLen; ++i)      {         if (badPath[i] != gtolower(path[i]))         {            return 0;         }      }      /* if we get here, the first 'badLen' characters match.       * If 'path' is 1 character larger than 'badPath' and that extra        * character is NOT a letter or a number, we have a bad path.       */      retval = 1;      if (badLen + 1 == len)      {         /* e.g. path == "aux:" */         if (gisalnum(path[len-1]))         {            /* the last character is alphanumeric, so we let this path go              * through.              */            retval = 0;         }      }   }   return retval;}static int isBadWindowsPath(char_t** parts, int partCount){   /*    * If we're running on Windows 95/98/ME, malicious users can crash the     * OS by requesting an URL with any of several reserved DOS device names     * in them (AUX, NUL, etc.).    * If we're running on any of those OS versions, we scan the URL     * for paths with any of these elements before     * trying to access them. If any of the subdirectory names match one    * of our prohibited links, we declare this to be a 'bad' path, and return     * 1 to indicate this. This may be an overly heavy-handed approach, but should     * prevent the DOS attack.    * NOTE that this function is only compiled in when we are running on Win32,     * and only has an effect when we are running on Win95/98, or ME. On all other     * versions of Windows, we check the version info, and return 0 immediately.    *    * According to http://packetstormsecurity.nl/0003-exploits/SCX-SA-01.txt:    *  II.  Problem Description    *   When the Microsoft Windows operating system is parsing a path that     *   is being crafted like "c:\[device]\[device]" it will halt, and crash     *   the entire operating system.      *   Four device drivers have been found to crash the system.  The CON,    *   NUL, AUX, CLOCK$ and CONFIG$ are the two device drivers which are     *   known to crash.  Other devices as LPT[x]:, COM[x]: and PRN have not     *   been found to crash the system.      *   Making combinations as CON\NUL, NUL\CON, AUX\NUL, ... seems to     *   crash Ms Windows as well.    *   Calling a path such as "C:\CON\[filename]" won't result in a crash    *   but in an error-message.  Creating the map "CON", "CLOCK$", "AUX"    *   "NUL" or "CONFIG$" will also result in a simple error-message     *   saying: ''creating that map isn't allowed''.    *    * returns 1 if it finds a bad path element.    */   OSVERSIONINFO version;   int i;   version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);   if (GetVersionEx(&version))

⌨️ 快捷键说明

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