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

📄 dirindex.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		result -= 2;
	} else {
		// case sensitivity
		if ( bCaseSensitive ) {
			result = strcmp(HTTPCore_getMIMETypeFromExtension( PIFInfo_getExtension( arg1 )),
				HTTPCore_getMIMETypeFromExtension( PIFInfo_getExtension( arg2 )));
		} else {
			result = PIUtil_stricmp(HTTPCore_getMIMETypeFromExtension( PIFInfo_getExtension( arg1 )),
				HTTPCore_getMIMETypeFromExtension( PIFInfo_getExtension( arg2 )));
		};
		// same type ? sort by name!
		if (!result) {
			result = bCaseSensitive ?
				strcmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ))
			  : PIUtil_stricmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ));
		};
	};

	// sort order
	return bDescending ? -result : result;
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Compare two keys of type PIFInfo * by size.
\*____________________________________________________________________________*/

int cmpSize( PIFInfo *arg1, PIFInfo *arg2, PIDB *pDB, int bDescending, int bCaseSensitive ) {
	
	// assume directories has 0 bytes (smaller than files)
	// directories are always top level
	int result = cmpDirs( arg1, arg2 );
	if ( result ) {
		result -= 2;
	} else {
		// no case sensitivity
		result = PIFInfo_getSize(arg1) - PIFInfo_getSize(arg2);

		// same size ? sort by name!
		if (!result) {
			result = bCaseSensitive ?
				strcmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ))
			  : PIUtil_stricmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ));
		};
	}
	// sort order
	return bDescending ? -result : result;
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Compare two keys of type PIFInfo * by date.
\*____________________________________________________________________________*/

int cmpDate( PIFInfo *arg1, PIFInfo *arg2, PIDB *pDB, int bDescending, int bCaseSensitive ) {
	
	// directories are always top level
	int result = cmpDirs( arg1, arg2 );
	if ( result ) {
		result -= 2;
	} else {
		// no case sensitivity
		result = PIFInfo_getLastModified(arg1) - PIFInfo_getLastModified(arg2);

		// same date ? sort by name!
		if (!result) {
			result = bCaseSensitive ?
				strcmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ))
			  : PIUtil_stricmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ));
		};
	}
	// sort order
	return bDescending ? -result : result;
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Compare two keys of type PIFInfo * by description.
\*____________________________________________________________________________*/

int cmpDesc( PIFInfo *arg1, PIFInfo *arg2, PIDB *pDB, int bDescending, int bCaseSensitive) {
	
	// directories are always top level
	int result = cmpDirs( arg1, arg2 );
	if ( result ) {
		result -= 2;
	} else {
		// load default description (Mime-Type) for 1st argument
		const char *pVal1 = PIFInfo_isDirectory( arg1 ) ? TYPE_MAGIC_DIRECTORY
			: HTTPCore_getMIMETypeFromExtension( PIFInfo_getExtension( arg1 ));

		// load default description (Mime-Type) for 2nd argument
		const char *pVal2 = PIFInfo_isDirectory( arg2 ) ? TYPE_MAGIC_DIRECTORY
			: HTTPCore_getMIMETypeFromExtension( PIFInfo_getExtension( arg2 ));

		if ( pDB ) {
			// load 1st description from Map-DB
			DescriptionMap *pDesc1 = (DescriptionMap *)PIDB_lookup(
				pDB, PIDBTYPE_OPAQUE, PIFInfo_getName( arg1 ), 0 );
			if ( pDesc1 ) pVal1 = pDesc1->sDescription;

			// load 2nd description from Map-DB
			DescriptionMap *pDesc2 = (DescriptionMap *)PIDB_lookup(
				pDB, PIDBTYPE_OPAQUE, PIFInfo_getName( arg2 ), 0 );
			if ( pDesc2 ) pVal2 = pDesc2->sDescription;
		};
		// description can contain (invisibly) leading HTML-tags, skip them
		if (strchr(pVal1, '<')==pVal1) { pVal1 = strchr(pVal1, '>'); pVal1++; }
		if (strchr(pVal2, '<')==pVal2) { pVal2 = strchr(pVal2, '>'); pVal2++; }
		// case sensitivity
		result = bCaseSensitive ? strcmp( pVal1, pVal2 ) : PIUtil_stricmp( pVal1, pVal2 );

		// same description ? sort by name!
		if (!result) {
			result = bCaseSensitive ?
				strcmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ))
			  : PIUtil_stricmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ));
		};
	}
	// sort order
	return bDescending ? -result : result;
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Quick sort of an array of PIFInfo pointers, by given column no.
	Optional descending, case sensitive sort flags.
\*____________________________________________________________________________*/

void qSort(PIFInfo *A[], int Min, int Max, PIDB *pDB, int iSortByColumn, int bDescending, int bCaseSensitive) {
	if ( iSortByColumn == SORT_NONE) { return; };
	int Lo = Min;
	int Hi = Max;
	PIFInfo *T;
	PIFInfo *Mid = A[(Lo + Hi) / 2];
    do {
		switch ( iSortByColumn )
		{
			case SORT_TYPE:
				while ( cmpType( A[Lo], Mid, pDB, bDescending, bCaseSensitive) < 0 && A[Lo++] != Mid);
				while ( cmpType( A[Hi], Mid, pDB, bDescending, bCaseSensitive) > 0 && A[Hi--] != Mid);
				break;
			case SORT_NAME:
				while ( cmpName( A[Lo], Mid, pDB, bDescending, bCaseSensitive) < 0 && A[Lo++] != Mid);
				while ( cmpName( A[Hi], Mid, pDB, bDescending, bCaseSensitive) > 0 && A[Hi--] != Mid);
				break;
			case SORT_SIZE:
				while ( cmpSize( A[Lo], Mid, pDB, bDescending, bCaseSensitive) < 0 && A[Lo++] != Mid);
				while ( cmpSize( A[Hi], Mid, pDB, bDescending, bCaseSensitive) > 0 && A[Hi--] != Mid);
				break;
			case SORT_DATE:
				while ( cmpDate( A[Lo], Mid, pDB, bDescending, bCaseSensitive) < 0 && A[Lo++] != Mid);
				while ( cmpDate( A[Hi], Mid, pDB, bDescending, bCaseSensitive) > 0 && A[Hi--] != Mid);
				break;
			case SORT_DESC:
				while ( cmpDesc( A[Lo], Mid, pDB, bDescending, bCaseSensitive) < 0 && A[Lo++] != Mid);
				while ( cmpDesc( A[Hi], Mid, pDB, bDescending, bCaseSensitive) > 0 && A[Hi--] != Mid);
				break;
			default: break;
		};

		if ( Lo <= Hi ) {
	        T = A[Lo];
		    A[Lo] = A[Hi];
			A[Hi] = T;
			Lo++;
			Hi--;
		};
	} while ( Lo <= Hi );
	if ( Hi > Min ) { qSort( A, Min, Hi, pDB, iSortByColumn, bDescending, bCaseSensitive ); };
	if ( Lo < Max ) { qSort( A, Lo, Max, pDB, iSortByColumn, bDescending, bCaseSensitive ); };
};

/* ---
end of change
--- */

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Directory index handler
\*____________________________________________________________________________*/
class DirectoryIndex : public HandlerBaseHTTP
{
private:
	/* --- forbid copy constructor --- */
	DirectoryIndex( const DirectoryIndex &t )
	: HandlerBaseHTTP( t )
		{ assert( 0 ); };

	/* ---
	Configuration data
	--- */
	Pi3Expression *pHeaderPattern;	/* pattern for top */
	Pi3Expression *pListTopPattern;	/* pattern sent before index */
	Pi3Expression *pFilePattern;	/* pattern for file */
	Pi3Expression *pListBottomPattern;/* pattern sent after index */
	Pi3Expression *pFooterPattern;	/* pattern for footer */
	PIString sHeaderFile;			/* file to be sent as header */
	PIString sFooterFile;			/* file to be sent as footer */
	PIString sLastModifiedFormat;	/* last modified format */
	PIString sNewPattern;			/* pattern to tag new files */
	DblList lInclude;				/* patterns to include */
	DblList lExclude;				/* patterns to exclude */
	DblList lMIMEIcons;				/* mappings of MIME types to images */
	DblList lSwapFileNames;			/* files to swap */
	DblList lHTTPEquivalents;		/* response headers to send */
	PIString sDescriptionFile;		/* description file */
	int iOptions;					/* options/flags */
	time_t tNewTreshold;			/* threshold time for new files */

	/* ---
	FastKeys
	--- */
	const char *pFKContentType;			/* RFC822: Content-Type */
	const char *pFKURI;					/* RFC822: URI from request header */
	const char *pFKPath;				/* STRING: Translated path */

	PIString sListTop;
	int bSortDescending;
	int iSortByColumn;
	/* ---
	end of change
	--- */
	
protected:
	/*___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ *

				Load an expression or condition

	 *___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ */
	int LoadExpression( const char *pName, Pi3Expression **ppExpression,
		FnPi3Write *pFunctions, const char *pValue, PIOStrStream &os )	
		{
		assert( ppExpression );
		Pi3Expression *pExpression = *ppExpression;
		if ( pExpression )
			{
			os << "'" << pName << "' may only be specified once." << ends;
			CONFIG_ERR( Object(), os.str() );
			return 0;
			};
		Pi3String *pError = Pi3String_new( 0 );
		pExpression = Pi3Expression_new( pValue, pFunctions, pError );
		if ( !pExpression )
			{
			os << "Error parsing expression: " <<
				Pi3String_getPtr( pError ) << ends;
			CONFIG_ERR( Object(), os.str() );
			Pi3String_delete( pError );
			return 0;
			};
		Pi3String_delete( pError );
		*ppExpression = pExpression;
		return 1;
		};

	/*___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ *

		Configure handler object based on parameters

	 *___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ */
	int Parameter( const char *pVariable, const char *pValue,
		const char *pWhere )
		{
		assert( pVariable && pValue );
		PIOStrStream os;
		os << pWhere << "DirectoryIndex: ";
		if ( !PIUtil_stricmp( KEY_CONF_HEADERFILE, pVariable ) )
			{
			sHeaderFile = pValue;
			}
		else if ( !PIUtil_stricmp( KEY_CONF_FOOTERFILE, pVariable ) )
			{
			sFooterFile = pValue;
			}
		else if ( !PIUtil_stricmp( KEY_CONF_LASTMODIFIEDFORMAT, pVariable ) )
			{
			iOptions |= FLG_MODDATE;
			sLastModifiedFormat = pValue;
			}
		else if ( !PIUtil_stricmp( KEY_CONF_HEADERPATTERN, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_HEADERPATTERN, &pHeaderPattern,
				aFunctions, pValue, os ) )
				{ return 0; };
			}
		else if ( !PIUtil_stricmp( KEY_CONF_LISTTOP, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_LISTTOP, &pListTopPattern,
				aFunctions, pValue, os ) )
				{ return 0;	};
			sListTop = pValue;
			}
		else if ( !PIUtil_stricmp( KEY_CONF_FILEPATTERN, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_FILEPATTERN, &pFilePattern,
				aFunctions, pValue, os ) )
				{ return 0; };
			}
		else if ( !PIUtil_stricmp( KEY_CONF_FOOTERPATTERN, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_FOOTERPATTERN, &pFooterPattern,
				aFunctions, pValue, os ) )
				{ return 0; };
			}
		else if ( !PIUtil_stricmp( KEY_CONF_LISTBOTTOM, pVariable ) )
			{
			if ( !LoadExpression( KEY_CONF_LISTBOTTOM, &pListBottomPattern,
				aFunctions, pValue, os ) )
				{ return 0; };
			}
		else if ( !PIUtil_stricmp( KEY_CONF_OPTIONS, pVariable ) )
			{
			/* ---
			Split the options up by the bar ('|') character and then
			strip trailing and leading whitespace from option before
			attempting to match it.
			--- */
			StringTokenizer tTokens( pValue, "|" );
			for(int i=0; i<tTokens.NumTokens(); i++)
				{
				const char *pToken = tTokens.GetToken( i );

				/* --- skip leading whitespace --- */
				for( ; *pToken && (isspace(*pToken)); pToken++ );

				/* ---
				include only to first whitespace trailing whitespace
				--- */
				int j=0;
				for( ; pToken[j] && !(isspace(pToken[j])); j++ );
				/* ---
				j now contains the length of the first word in pToken
				--- */

				/* ---
				cycle through the list of available flags
				comparing them with this one
				--- */
				int i=0;
				for( ; aFlagMap[i].pName; i++ )
					{
					if ( !PIUtil_strncmpi( aFlagMap[i].pName, pToken, j ) )
						{ break; };
					};
				if ( !aFlagMap[i].pName )
					{
					/* --- flag not found --- */
					PIString sTmp( pToken, j );
					os << "Unknown option flag '" << sTmp << "'." << ends;
					CONFIG_ERR( Object(), os.str() );
					return 0;
					};
				iOptions |= aFlagMap[i].iFlag;
				};	/* --- loop over tokens seperated by '|' --- */
			}
		else if ( !PIUtil_stricmp( KEY_CONF_INCLUDE, pVariable ) )
			{
			lInclude.Append( (DblList::type) PI_NEW( PIString( pValue ) ) );
			}
		else if ( !PIUtil_stricmp( KEY_CONF_EXCLUDE, pVariable ) )
			{
			lExclude.Append( (DblList::type) PI_NEW( PIString( pValue ) ) );
			}
		else if ( !PIUtil_stricmp( KEY_CONF_SWAPFILENAME, pVariable ) )
			{
			int i;
			for( i=0; pValue[i] && !(isspace(pValue[i])); i++);
			PIString sOld( pValue, i );
			pValue = &( pValue[i] );
			for( ; *pValue && (isspace(*pValue)); pValue++ );
			lSwapFileNames.Append( (DblList::type)
				PI_NEW( SwapFileName( sOld, pValue ) ) );
			}
		else if ( !PIUtil_stricmp( KEY_CONF_DESCRIPTIONFILE, pVariable ) )
			{
			sDescriptionFile = pValue;
			}
		else if ( !PIUtil_stricmp( KEY_CONF_MIMEICON, pVariable ) )
			{
			StringTokenizer tTokens( pValue, " ", 0 );
			if ( tTokens.NumTokens()!=2 )
				{	
				os << "Syntax error in definiton of 'MIMEIcon', line is '" <<
					pValue << "'" << ends;
				CONFIG_ERR( Object(), os.str() );
				return 0;
				};
			lMIMEIcons.Append( (DblList::type) PI_NEW(
				MIMEIcon( tTokens.GetToken(0), tTokens.GetToken(1) ) ) );
			}
        else if ( !PIUtil_stricmp( KEY_CONF_HTTPEQUIV, pVariable ) )
            {
            RFC822Header *pHeader = PI_NEW( RFC822Header( pValue ) );
            if ( !pHeader || !pHeader->IsOK() )
                {
                os << "Bad HTTPEquiv expression, '" << pValue << "'" << ends;
                CONFIG_ERR( Object(), os.str() );
                PI_DELETE( pHeader );
                return 0;
                }
            else
                {
                lHTTPEquivalents.Append( (DblList::type)pHeader );
                };
            }
		else if ( !PIUtil_stricmp( KEY_CONF_NEWPATTERN, pVariable ) )
			{
			sNewPattern = pValue;
			}
		else if ( !PIUtil_stricmp( KEY_CONF_NEWTHRESHOLD, pVariable ) )
			{
			tNewTreshold = 86400 * atoi(pValue);
			}
		else
			{
			os << "Unknown directive '" << pVariable <<
				"'" << ends;
			CONFIG_ERR( Object(), os.str() );
			return 0;
			};

		return 1;
		};

public:
	/*___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ *
		
				Object lifetime stuff

	 *___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ */
	DirectoryIndex( PIObject *pTheObject, int iArgc, const char *ppArgv[] )
	:
		HandlerBaseHTTP( pTheObject ),
		pHeaderPattern( 0 ),
		pListTopPattern( 0 ),
		pFilePattern( 0 ),
		pListBottomPattern( 0 ),
		pFooterPattern( 0 ),
		iOptions( FLG_NONE ),

⌨️ 快捷键说明

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