Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

412 lines
12 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
compression.h
Abstract:
Do Http compression
Author:
Anil Ruia (AnilR) 10-Apr-2000
--*/
#ifndef _COMPRESSION_H_
#define _COMPRESSION_H_
#define COMPRESSION_MIN_IO_BUFFER_SIZE 256
#define COMPRESSION_MAX_IO_BUFFER_SIZE 100000
#define COMPRESSION_MIN_COMP_BUFFER_SIZE 1024
#define COMPRESSION_MAX_COMP_BUFFER_SIZE 100000
#define COMPRESSION_MAX_QUEUE_LENGTH 10000
#define COMPRESSION_MIN_FILES_DELETED_PER_DISK_FREE 1
#define COMPRESSION_MAX_FILES_DELETED_PER_DISK_FREE 1024
#define COMPRESSION_MAX_COMPRESSION_LEVEL 10
#define COMPRESSION_DEFAULT_DISK_SPACE_USAGE 100000000
#define COMPRESSION_DEFAULT_BUFFER_SIZE 8192
#define COMPRESSION_DEFAULT_QUEUE_LENGTH 1000
#define COMPRESSION_DEFAULT_FILES_DELETED_PER_DISK_FREE 256
#define COMPRESSION_DEFAULT_FILE_SIZE_FOR_COMPRESSION 1
enum COMP_INIT_STATUS
{
COMP_INIT_NONE,
COMP_INIT_SCHEMES,
COMP_INIT_DIRLOCK,
COMP_INIT_CONTEXT,
COMP_INIT_DONE
};
class COMPRESSION_SCHEME
{
public:
COMPRESSION_SCHEME()
: m_hCompressionDll (NULL),
m_pCompressionContext (NULL),
m_dwPriority (1),
m_dwDynamicCompressionLevel (0),
m_dwOnDemandCompressionLevel (COMPRESSION_MAX_COMPRESSION_LEVEL),
m_dwCreateFlags (0),
m_fDoStaticCompression (TRUE),
m_fDoOnDemandCompression (TRUE),
m_fDoDynamicCompression (TRUE),
m_pfnInitCompression (NULL),
m_pfnDeInitCompression (NULL),
m_pfnCreateCompression (NULL),
m_pfnCompress (NULL),
m_pfnDestroyCompression (NULL),
m_pfnResetCompression (NULL)
{}
HRESULT Initialize(MB *pmb, LPWSTR schemeName);
~COMPRESSION_SCHEME()
{
if (m_pfnDestroyCompression && m_pCompressionContext)
{
m_pfnDestroyCompression(m_pCompressionContext);
m_pCompressionContext = NULL;
}
if (m_pfnDeInitCompression)
{
m_pfnDeInitCompression();
}
if (m_hCompressionDll)
{
FreeLibrary(m_hCompressionDll);
m_hCompressionDll = NULL;
}
}
STRU m_strCompressionSchemeName;
STRA m_straCompressionSchemeName;
STRU m_strFilePrefix;
MULTISZ m_mszFileExtensions;
MULTISZ m_mszScriptFileExtensions;
DWORD m_dwPriority;
HMODULE m_hCompressionDll;
PFNCODEC_INIT_COMPRESSION m_pfnInitCompression;
PFNCODEC_DEINIT_COMPRESSION m_pfnDeInitCompression;
PFNCODEC_CREATE_COMPRESSION m_pfnCreateCompression;
PFNCODEC_COMPRESS m_pfnCompress;
PFNCODEC_DESTROY_COMPRESSION m_pfnDestroyCompression;
PFNCODEC_RESET_COMPRESSION m_pfnResetCompression;
// The compression context used for static compression
PVOID m_pCompressionContext;
DWORD m_dwDynamicCompressionLevel;
DWORD m_dwOnDemandCompressionLevel;
DWORD m_dwCreateFlags;
BOOL m_fDoDynamicCompression;
BOOL m_fDoStaticCompression;
BOOL m_fDoOnDemandCompression;
};
typedef enum
{
COMPRESSION_WORK_ITEM_COMPRESS,
COMPRESSION_WORK_ITEM_DELETE,
COMPRESSION_WORK_ITEM_TERMINATE,
COMPRESSION_WORK_ITEM_INVALID
} COMPRESSION_WORK_ITEM_TYPE;
class COMPRESSION_WORK_ITEM
{
public:
COMPRESSION_WORK_ITEM()
: WorkItemType (COMPRESSION_WORK_ITEM_INVALID),
scheme (NULL),
pFileInfo (NULL)
{
InitializeListHead(&ListEntry);
}
virtual ~COMPRESSION_WORK_ITEM()
{
InitializeListHead(&ListEntry);
if (pFileInfo != NULL)
{
pFileInfo->DereferenceCacheEntry();
pFileInfo = NULL;
}
}
LIST_ENTRY ListEntry;
COMPRESSION_WORK_ITEM_TYPE WorkItemType;
COMPRESSION_SCHEME *scheme;
STRU strPhysicalPath;
W3_FILE_INFO *pFileInfo;
};
#define MAX_SERVER_SCHEMES 100
typedef enum
{
DO_STATIC_COMPRESSION,
DO_DYNAMIC_COMPRESSION
} COMPRESSION_TO_PERFORM;
#define DYNAMIC_COMPRESSION_BUFFER_SIZE 2000
typedef enum
{
IN_CHUNK_LENGTH,
IN_CHUNK_EXTENSION,
IN_CHUNK_HEADER_NEW_LINE,
AT_CHUNK_DATA_NEW_LINE,
IN_CHUNK_DATA_NEW_LINE,
IN_CHUNK_DATA
} COMPRESS_CHUNK_STATE;
class COMPRESSION_CONTEXT
{
public:
static HRESULT Initialize()
{
ALLOC_CACHE_CONFIGURATION acConfig;
acConfig.nConcurrency = 1;
acConfig.nThreshold = 100;
acConfig.cbSize = sizeof COMPRESSION_CONTEXT;
allocHandler = new ALLOC_CACHE_HANDLER("COMPRESSION_CONTEXT",
&acConfig);
if (allocHandler == NULL)
{
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
return S_OK;
}
static void Terminate()
{
if (allocHandler != NULL)
{
delete allocHandler;
}
}
void *operator new(
#if DBG
size_t size
#else
size_t
#endif
)
{
DBG_ASSERT(size == sizeof COMPRESSION_CONTEXT);
DBG_ASSERT(allocHandler != NULL);
return allocHandler->Alloc();
}
void operator delete(void *pCompressionContext)
{
DBG_ASSERT(pCompressionContext != NULL);
DBG_ASSERT(allocHandler != NULL);
DBG_REQUIRE(allocHandler->Free(pCompressionContext));
}
COMPRESSION_CONTEXT()
: m_pScheme (NULL),
m_fTransferChunkEncoded (FALSE),
m_pCompressionContext (NULL),
m_dwBytesInCurrentEncodedChunk (0),
m_encodedChunkState (IN_CHUNK_LENGTH),
m_fHeadersSent (FALSE),
m_fRequestIsHead (FALSE),
m_fOriginalBodyEmpty (TRUE)
{}
~COMPRESSION_CONTEXT()
{
if (m_pCompressionContext)
{
m_pScheme->m_pfnDestroyCompression(m_pCompressionContext);
m_pCompressionContext = NULL;
}
}
HRESULT ProcessEncodedChunkHeader();
HRESULT CalculateEncodedChunkByteCount();
VOID DeleteEncodedChunkExtension();
VOID IncrementPointerInULChunk(IN DWORD dwIncr = 1)
{
m_pbOrigData += dwIncr;
m_cbOrigData -= dwIncr;
}
COMPRESSION_SCHEME *m_pScheme;
//
// Is the original response chunk encoded?
//
BOOL m_fTransferChunkEncoded;
//
// If the original response is Chunk encoded, information about the
// current chunk in the response
//
DWORD m_dwBytesInCurrentEncodedChunk;
COMPRESS_CHUNK_STATE m_encodedChunkState;
//
// The context used by the compression routines
//
PVOID m_pCompressionContext;
//
// position in the original response
//
PBYTE m_pbOrigData;
DWORD m_cbOrigData;
static ALLOC_CACHE_HANDLER *allocHandler;
//
// Some members to keep track of HEAD request body suppression
//
BOOL m_fRequestIsHead;
BOOL m_fOriginalBodyEmpty;
//
// Has the end of response headers been seen?
//
BOOL m_fHeadersSent;
//
// A chunk's worth of data
//
BUFFER m_bufChunk;
};
class HTTP_COMPRESSION
{
public:
static HRESULT Initialize();
static VOID Terminate();
static HRESULT DoStaticFileCompression(IN W3_CONTEXT *pW3Context,
IN OUT W3_FILE_INFO **ppFileInfo,
OUT BOOL *pfDoCache);
static HRESULT OnSendResponse(
IN W3_CONTEXT *pW3Context);
static HRESULT DoDynamicCompression(
IN W3_CONTEXT *pW3Context,
IN BOOL fMoreData,
IN HTTP_FILTER_RAW_DATA * pRawData );
static BOOL QueryDoStaticCompression()
{
return sm_fDoStaticCompression;
}
static BOOL QueryDoDynamicCompression()
{
return sm_fDoDynamicCompression;
}
private:
static COMPRESSION_SCHEME *sm_pCompressionSchemes[MAX_SERVER_SCHEMES];
static DWORD sm_dwNumberOfSchemes;
static STRU *sm_pstrCompressionDirectory;
static STRA *sm_pstrCacheControlHeader;
static STRA *sm_pstrExpiresHeader;
static BOOL sm_fDoStaticCompression;
static BOOL sm_fDoDynamicCompression;
static BOOL sm_fDoOnDemandCompression;
static BOOL sm_fDoDiskSpaceLimiting;
static BOOL sm_fNoCompressionForHttp10;
static BOOL sm_fNoCompressionForProxies;
static BOOL sm_fNoCompressionForRange;
static BOOL sm_fSendCacheHeaders;
static DWORD sm_dwMaxDiskSpaceUsage;
static DWORD sm_dwIoBufferSize;
static DWORD sm_dwCompressionBufferSize;
static DWORD sm_dwMaxQueueLength;
static DWORD sm_dwFilesDeletedPerDiskFree;
static DWORD sm_dwMinFileSizeForCompression;
static PBYTE sm_pIoBuffer;
static PBYTE sm_pCompressionBuffer;
static CRITICAL_SECTION sm_CompressionDirectoryLock;
static DWORD sm_dwCurrentDiskSpaceUsage;
static BOOL sm_fCompressionVolumeIsFat;
static LIST_ENTRY sm_CompressionThreadWorkQueue;
static CRITICAL_SECTION sm_CompressionThreadLock;
static HANDLE sm_hThreadEvent;
static HANDLE sm_hCompressionThreadHandle;
static DWORD sm_dwCurrentQueueLength;
static COMP_INIT_STATUS sm_InitStatus;
static BOOL sm_fIsTerminating;
static HRESULT ReadMetadata(MB *pmb);
static HRESULT InitializeCompressionSchemes(MB *pmb);
static HRESULT InitializeCompressionDirectory();
static HRESULT InitializeCompressionThread();
static DWORD WINAPI CompressionThread(LPVOID);
static BOOL QueueWorkItem(
IN COMPRESSION_WORK_ITEM *WorkItem,
IN BOOL fOverrideMaxQueueLength,
IN BOOL fQueueAtHead);
static VOID FindMatchingSchemes(
IN CHAR * pszAcceptEncoding,
IN LPWSTR pszExtension,
IN COMPRESSION_TO_PERFORM performCompr,
OUT DWORD matchingSchemes[],
OUT DWORD *pdwClientCompressionCount);
static HRESULT ConvertPhysicalPathToCompressedPath(
IN COMPRESSION_SCHEME *scheme,
IN STRU *pstrPhysicalPath,
OUT STRU *pstrCompressedFileName);
static BOOL CheckForExistenceOfCompressedFile(
IN W3_FILE_INFO *pOrigFile,
IN STRU *pstrCompressedFileName,
OUT W3_FILE_INFO **ppCompFile,
IN BOOL fDeleteAllowed = TRUE);
static BOOL QueueCompressFile(
IN COMPRESSION_SCHEME *scheme,
IN W3_FILE_INFO *pFileInfo);
static VOID CompressFile(IN COMPRESSION_SCHEME *scheme,
IN W3_FILE_INFO *pFileInfo);
static VOID FreeDiskSpace();
static BOOL CompressAndWriteData(
IN COMPRESSION_SCHEME *scheme,
IN PBYTE InputBuffer,
IN DWORD BytesToCompress,
OUT PDWORD BytesWritten,
IN HANDLE hCompressedFile);
};
#endif _COMPRESSION_H_