windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/w3/server/mimemap.cxx
2020-09-26 16:20:57 +08:00

273 lines
7.2 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1994 **/
/**********************************************************************/
/*
mimemap.cxx
This module contains the code for MIME to file type mappings
The mime mappings are used for selecting the correct type based on file
extensions and for indicating what types the server accepts.
FILE HISTORY:
Johnl 23-Aug-1994 Created
*/
#include "w3p.hxx"
//
// Private constants.
//
//
// Private globals.
//
//
// Private prototypes.
//
BOOL
SelectCustomMimeMapping(
IN const CHAR *pszPath,
IN STR *pstrContentType,
IN CHAR *pszMimeMapping
)
/*++
Routine Description
Called when we have a configured metadata mime mapping on a directory,
and want to look it up.
Arguments
pszPath - Path including extension to be looked up.
pstrContentType - Where to return the content type.
pszMimeMapping - Pointer to mime mapping string.
Returns
TRUE if operation successful.
--*/
{
CHAR *pszCurrentMimeType;
CHAR *pszExt;
DWORD dwExtLength;
BOOL bCheckingDefault;
CHAR *pszLastSlash;
if (pszPath == NULL)
{
pszExt = "*";
dwExtLength = sizeof("*") - 1;
bCheckingDefault = TRUE;
}
else
{
// Need to find the extension. The extension is whatever follows the
// dot after the last slash in the path.
// Find the last slash. If there isn't one, use the start of the path.
pszLastSlash = strrchr((CHAR *)pszPath, '\\');
if (pszLastSlash == NULL)
{
pszLastSlash = (CHAR *)pszPath;
}
pszExt = strrchr(pszLastSlash, '.');
if (pszExt == NULL || *(pszExt+1) == '\0')
{
// Didn't find one, so look for the default mapping.
pszExt = "*";
dwExtLength = sizeof("*") - 1;
bCheckingDefault = TRUE;
}
else
{
dwExtLength = strlen(pszExt);
bCheckingDefault = FALSE;
}
}
// Look at the mime type mapping string and see if we have a match. The
// string was preformatted when we read the metadata, and is stored as
// a set of multi-sz mime-type, .ext strings. If we're not looking for the
// default, and we don't find one on the first pass, we'll try to find the
// default mapping.
for (;;)
{
pszCurrentMimeType = pszMimeMapping;
do {
CHAR *pszCurrentSeparator;
DWORD dwCurrentExtLength;
CHAR *pszCurrentMimeString;
DWORD dwCurrentMimeStringLength;
// First, isolate the mime type from the extension.
pszCurrentSeparator = strchr(pszCurrentMimeType, ',');
// Compute the length of the extension
dwCurrentExtLength = DIFF(pszCurrentSeparator - pszCurrentMimeType);
// Find the mime map string, and it's length
pszCurrentMimeString = pszCurrentSeparator + 1;
dwCurrentMimeStringLength = strlen(pszCurrentMimeString);
// We have the extension and the length, compare against the
// input extension.
if (dwExtLength == dwCurrentExtLength &&
!_strnicmp(pszExt, pszCurrentMimeType, dwExtLength))
{
// Allright, we have a winner.
return pstrContentType->Copy(pszCurrentMimeString,
dwCurrentMimeStringLength);
}
// Otherwise, look at the next one.
pszCurrentMimeType = pszCurrentMimeString + dwCurrentMimeStringLength + 1;
} while ( *pszCurrentMimeType != '\0' );
if (!bCheckingDefault)
{
// Look backwards for another '.' so we can support extensions
// like ".xyz.xyz" or ".a.b.c".
if ( pszExt > pszLastSlash )
{
pszExt--;
while ( ( pszExt > pszLastSlash ) && ( *pszExt != '.' ) )
{
pszExt--;
}
if ( *pszExt == '.' )
{
dwExtLength = strlen( pszExt );
continue;
}
}
// Didn't find one, so look for the default mapping.
pszExt = "*";
dwExtLength = sizeof("*") - 1;
bCheckingDefault = TRUE;
}
else
{
break;
}
}
return FALSE;
}
/*******************************************************************
NAME: SelectMimeMapping
SYNOPSIS: Given a file name, this routine finds the appropriate
MIME type for the name
ENTRY: pstrContentType - Receives MIME type or icon file to use
pszPath - Path of file being requested (extension
is used for the mime mapping). Should be
fully qualified and canonicalized. If NULL, then the
default mapping is used
mmtype - Type of data to retrieve. Can retrieve either
the mime type associated with the file extension or
the icon associated with the extension
RETURNS: TRUE on success, FALSE on error (call GetLastError)
HISTORY:
Johnl 04-Sep-1994 Created
********************************************************************/
BOOL SelectMimeMapping( STR * pstrContentType,
const CHAR * pszPath,
PW3_METADATA pMetaData,
enum MIMEMAP_TYPE mmtype )
{
BOOL fRet = TRUE;
CHAR *pszMimeMap;
switch ( mmtype )
{
case MIMEMAP_MIME_TYPE:
pszMimeMap = (CHAR *)pMetaData->QueryMimeMap()->QueryPtr();
if (*pszMimeMap != '\0')
{
fRet = SelectCustomMimeMapping( pszPath,
pstrContentType,
pszMimeMap );
if ( fRet )
{
break;
}
}
fRet = SelectMimeMappingForFileExt( g_pInetSvc,
pszPath,
pstrContentType );
break;
case MIMEMAP_MIME_ICON:
fRet = SelectMimeMappingForFileExt( g_pInetSvc,
pszPath,
NULL,
pstrContentType );
break;
default:
DBG_ASSERT( FALSE );
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
IF_DEBUG( PARSING )
{
if ( mmtype == MIMEMAP_MIME_TYPE )
DBGPRINTF((DBG_CONTEXT,
"[SelectMimeMapping] Returning %s for extension %s\n",
pstrContentType->QueryStr(),
pszPath ? pszPath : TEXT("*") ));
}
return fRet;
}
//
// Private functions.
//