/*-- Copyright (c) 1995-1998 Microsoft Corporation Module Name: HTTPD.H Author: Arul Menezes Abstract: Global defns for the HTTP server --*/ #ifndef _HTTPD_H_ #define _HTTPD_H_ #ifndef UNDER_CE #define SECURITY_WIN32 #endif #if DBG #define DEBUG #endif #include #include // OLD_CE_BUILD is defined when using the Windows CE Toolkit in Visual // Studio (in proj servers\vc\httpexece). We build this way when we're building for // older Windows CE devices (version 2.x). The reason we do this in the first place is // for shipping a beta version of the web server. // We won't have functions like sprintf or sscanf, so we implement our own, scaled down versions. // Also, there is no ASP support in this case. #ifdef OLD_CE_BUILD #pragma message ("Using Visual Studio Windows CE Toolkit Settings") // Write our own strrchr if we're using version 2.0 of CE, it wouldn't exist otherwise inline char *strrchr( const char *string, int c ) { PCSTR pszTrav = string; PSTR pszLast = NULL; while ( *pszTrav ) { if (*pszTrav == (CHAR) c) pszLast = (PSTR) pszTrav; pszTrav++; } return pszLast; } inline int isspace(int c) { return ( c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v'); } #else #include #endif #include #include #include #include #include #include #include #include #include #ifdef UNDER_CE #include #include #else #include #endif //------------- Arbitrary constants ----------------------- // the assumption is that this buffer size covers the vast majority of requests #define MINBUFSIZE 1024 // this the the timeout we use when waiting for the next request on a keep-alive connection #define KEEPALIVETIMEOUT 60000 // subsequent-input timeout value. shoudl only hit on malformed headers/garbled packets #define RECVTIMEOUT 30000 // maximum size of output headers #define MAXHEADERS 512 // maximum size of a mime-type #define MAXMIME 64 // maximum size username+password #define MAXUSERPASS 256 // the assumption is that this buffer size covers most dir listings #define DIRBUFSIZE 4096 // Size of response headers ("normal" headers, cookies and other extra headers are dynamic) #define HEADERBUFSIZE 4096 // Used for dynamically growing arrays #define VALUE_GROW_SIZE 5 // Size of buffer to hold all the bodies on web server errors #define BODYSTRINGSIZE 2048 #define HTTPD_DEV_PREFIX L"HTP" #define HTTPD_DEV_INDEX 0 #define HTTPD_DEV_NAME L"HTP0:" //------------- not-so-arbitrary constants ----------------------- #define IPPORT_HTTP 2869 //-------------------- Debug defines ------------------------ // Debug zones #ifdef DEBUG #define ZONE_ERROR DEBUGZONE(0) #define ZONE_INIT DEBUGZONE(1) #define ZONE_LISTEN DEBUGZONE(2) #define ZONE_SOCKET DEBUGZONE(3) #define ZONE_REQUEST DEBUGZONE(4) #define ZONE_RESPONSE DEBUGZONE(5) #define ZONE_ISAPI DEBUGZONE(6) #define ZONE_VROOTS DEBUGZONE(7) #define ZONE_ASP DEBUGZONE(8) #define ZONE_DEVICE DEBUGZONE(9) #define ZONE_MEM DEBUGZONE(13) #define ZONE_PARSER DEBUGZONE(14) #define ZONE_TOKEN DEBUGZONE(15) #endif #define NTLM_PACKAGE_NAME TEXT("NTLM") // We need CE_STRING because GetProcAddress takes a LPCSTR as arg on NT, but UNICODE is defined // so the TEXT macro would return a UNICODE string #ifdef UNDER_CE #define NTLM_DLL_NAME TEXT("secur32.dll") #define CE_STRING(x) TEXT(x) #define SECURITY_ENTRYPOINT_CE SECURITY_ENTRYPOINT #else #define NTLM_DLL_NAME TEXT("security.dll") #define CE_STRING(x) (LPCSTR) (x) #define SECURITY_ENTRYPOINT_CE SECURITY_ENTRYPOINT_ANSIA #endif #define ASP_DLL_NAME TEXT("asp.dll") ///////////////////////////////////////////////////////////////////////////// // Misc string handling helpers ///////////////////////////////////////////////////////////////////////////// PSTR MySzDupA(PCSTR pszIn, int iLen=0); PWSTR MySzDupW(PCWSTR wszIn, int iLen=0); PWSTR MySzDupAtoW(PCSTR pszIn, int iInLen=-1); PSTR MySzDupWtoA(PCWSTR wszIn, int iInLen=-1); BOOL MyStrCatA(PSTR *ppszDest, PSTR pszSource, PSTR pszDivider=NULL); // Misc HTTP helper macros #define CHECKHCONN(h) if(!h || ((CHttpRequest*)h)->m_dwSig != CHTTPREQUEST_SIG) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } #define CHECKPFC(h) if (!h || ((CHttpRequest*)h->ServerContext)->m_dwSig != CHTTPREQUEST_SIG) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } #define CHECKPTR(p) if (!p) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } #define CHECKPTRS2(p1, p2) if(!p1 || !p2) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } #define CHECKPTRS3(p1, p2, p3) if(!p1 || !p2 || !p3) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } #define CHECKFILTER(pfc) { if (! ((CHttpRequest*)pfc->ServerContext)->m_pFInfo->m_fFAccept) \ { SetLastError(ERROR_OPERATION_ABORTED); return FALSE; } } #define SkipWWhiteSpace(lpsz) while ( (lpsz)[0] != L'\0' && iswspace((lpsz)[0])) ++(lpsz) //------------- Scalar Data typedefs ----------------------- // HTTP status codes typedef enum { STATUS_OK = 0, STATUS_MOVED, STATUS_NOTMODIFIED, STATUS_BADREQ, STATUS_UNAUTHORIZED, STATUS_FORBIDDEN, STATUS_NOTFOUND, STATUS_INTERNALERR, STATUS_NOTIMPLEM, STATUS_NOTSUPP, STATUS_MAX, } RESPONSESTATUS; // Data used for response static data typedef struct { DWORD dwStatusNumber; PCSTR pszStatusText; PCSTR pszStatusBody; } STATUSINFO; //------------- Const data prototypes ----------------------- extern STATUSINFO rgStatus[STATUS_MAX]; extern const char cszTextHtml[]; extern const char cszEmpty[]; extern const char cszServerID[]; extern const char cszProductID[]; extern const char* rgMonth[]; extern const char cszKeepAlive[]; extern const char cszHTTPVER[]; extern const char cszDateParseFmt[]; extern const char cszDateOutputFmt[]; extern const char* rgWkday[]; extern const char* rgMonth[]; extern const char cszCRLF[]; extern const char cszBasic[]; extern BOOL g_fFromExe; // Did the executable start us? //----------------------- Class defns ----------------------- #include #include #include #include #include #include #include #include #include //-------------------- All global data is accessed through Global Class ---------- class CGlobalVariables { public: SOCKET m_sockListen; DWORD m_dwListenPort; // port we're listening on (can be modified in registry. default=80) CVRoots* m_pVroots; // ptr to VRoot structure, containing or URL-->Paths mappings BOOL m_fBasicAuth; // are we allowing Basic auth (from registry) BOOL m_fNTLMAuth; // are we allowing NTLM auth (from registry) BOOL m_fFilters; // Is ISAPI filter component included? BOOL m_fExtensions; // Is ISAPI extension component included? BOOL m_fASP; // Is ASP component included? BOOL m_fDirBrowse; // are we allowing directory browsing (from registry) PWSTR m_wszDefaultPages; // are we allowing directory browsing (from registry) BOOL m_fAcceptConnections; // are we accepting new threads? LONG m_nConnections; // # of connections (threads) we're handling LONG m_nMaxConnections; // Maximum # of connections we support concurrently CLog* m_pLog; // Logging structure DWORD m_dwPostReadSize; // Size of chunks of data to recv() in POST request. PSTR m_pszServerID; // Server ID CISAPICache *m_pISAPICache; // Used to cache ISAPI extension and ASP dlls DWORD m_dwCacheSleep; // How often (in millesecs) do we PWSTR m_wszAdminUsers; // List of users who have administrative privelages PWSTR m_wszAdminGroups; // List of groups who have administrative privelages PSTR m_pszStatusBodyBuf; // Holds the strings of http bodies loaded from rc file SVSThreadPool *m_pThreadPool; // All httpd threads other than HttpConnectionThread use this LONG m_fISAPICacheRunning; // Is ISAPI cache cleanup thread running? // ASP Specific SCRIPT_LANG m_ASPScriptLang; // Registry set default scripting language LCID m_ASPlcid; // Registry set default LCID UINT m_lASPCodePage; // Registry set default Code Page // Authentication Specific HINSTANCE m_hNTLMLib; // Global NTLM library handle DWORD m_cbNTLMMax; // max ntlm allowable data size PSecurityFunctionTable m_pNTLMFuncs; // fcn table for NTLM requests HANDLE m_hEventSelect; HANDLE m_hEventShutdown; CGlobalVariables(); ~CGlobalVariables(); }; extern CGlobalVariables *g_pVars; extern HINSTANCE g_hInst; extern HANDLE g_hListenThread; extern BOOL g_fRegistered; extern LONG g_fState; //------------- Function prototypes ------------------------- DWORD WINAPI HttpConnectionThread(LPVOID lpv); DWORD WINAPI HandleAccept(LPVOID lpv); extern "C" int HttpInitialize(TCHAR *szRegPath); void GetRemoteAddress(SOCKET sock, PSTR pszBuf); void GetLocalAddress(SOCKET sock, PSTR pszBuf); DWORD WINAPI RemoveUnusedISAPIs(LPVOID lpv); BOOL SetHTTPVersion(PSTR pszVersion, DWORD *pdwVersion); void WriteHTTPVersion(PSTR pszVersion, DWORD dwVersion); char *strcpyEx(char *szDest, const char *szSrc); BOOL SetHTTPDate(PSTR pszDate, PSTR pszMonth, SYSTEMTIME *pst,PDWORD pdwModifiedLength); PSTR WriteHTTPDate(PSTR pszDateBuf, SYSTEMTIME *pst, BOOL fAddGMT); void InitializeResponseCodes(PSTR pszStatusBodyBuf); BOOL Base64Encode( BYTE * bufin, // in DWORD nbytes, // in char * pbuffEncoded); // out BOOL Base64Decode( char * bufcoded, // in char * pbuffdecoded, // out DWORD * pcbDecoded); // in out #endif //_HTTPD_H_