📄 request.h
字号:
AUTH_STATE m_AuthState; // state info for NTLM process, needs to be saved across requests
DWORD m_dwAuthFlags;
BOOL m_fDisabledNagle;
// Used for sensitive strings that should be zeroed out, in particular password info.
void ZeroAndFree(PSTR &pszData) {
if (pszData) {
DWORD dw = strlen(pszData);
memset(pszData,0,dw);
}
MyFree(pszData);
}
void ZeroAndFree(WCHAR *&wszData) {
if (wszData) {
DWORD dw = wcslen(wszData)*sizeof(WCHAR);
memset(wszData,0,dw);
}
MyFree(wszData);
}
// Authentication functions
void FreeAuth(void) {
MyFree(m_pszSecurityOutBuf);
ZeroAndFree(m_pszPassword);
ZeroAndFree(m_pszRawRemoteUser);
// Don't free NTLM structs or user name info, they're possibly persisted across multiple requests.
}
// User name info is persisted across the session.
void FreePersistedAuthInfo(void) {
ZeroAndFree(m_pszRemoteUser);
ZeroAndFree(m_wszRemoteUser);
ZeroAndFree(m_wszMemberOf);
m_AuthLevelGranted = AUTH_PUBLIC;
}
BOOL CheckAuth();
// Basic AUTH
BOOL HandleBasicAuth(PSTR pszData);
BOOL BasicToNTLM(WCHAR * wszPassword);
// SSL
BOOL m_fHandleSSL;
SSL_INFO m_SSLInfo;
BOOL m_fIsSecurePort;
BOOL m_fPerformedSSLRenegotiateRequest;
BOOL m_fPerformedClientInitiatedRenegotiate;
BOOL HandleSSLHandShake(BOOL fRenegotiate=FALSE, BYTE *pInitialData=NULL, DWORD cbInitialData=NULL);
BOOL SSLRenegotiateRequest(void);
BOOL CheckClientCert(void);
// File GET/HEAD handling functions
BOOL IsNotModified(HANDLE hFile, DWORD dwLength);
void CloseSSLSession();
// Directory: Default page & browsing functions
BOOL MapDirToDefaultPage(void);
BOOL EmitDirListing(void);
// if it doesn't end in '/' send a redirect
// returns TRUE if a redirect was sent
BOOL SendRedirectIfNeeded(void);
// For simple GET and HEAD we allow direct dir browsing. Otherwise if a dir is
// requested on another verb then we let the DAV extensions do the work on it.
BOOL VerbSupportsDirBrowsing(void) {
return (m_idMethod == VERB_GET || m_idMethod == VERB_HEAD);
}
void Init(SOCKET sock, BOOL fSecure);
BOOL ReadPostData(DWORD dwMaxSizeToRead, BOOL fInitialPostRead, BOOL fSSLRenegotiate);
// ISAPI extension handling functions
BOOL HandleScript();
BOOL SetPathTranslated();
BOOL ExecuteISAPI(WCHAR *wszExecutePath);
void FillECB(LPEXTENSION_CONTROL_BLOCK pECB);
BOOL GetServerVariable(PSTR pszVar, PVOID pvOutBuf, PDWORD pdwOutSize, BOOL fFromFilter);
BOOL WriteClient(PVOID pvBuf, PDWORD pdwSize, BOOL fFromFilter);
BOOL ServerSupportFunction(DWORD dwReq, PVOID pvBuf, PDWORD pdwSize, PDWORD pdwType);
BOOL ReadClient(PVOID pv, PDWORD pdw);
BOOL IsScript(BOOL fCheckAccess);
// Filter Specific
BOOL IsCurrentFilterCalled(DWORD dwNotificationType, int iCurrentFilter);
BOOL FillFC(PHTTP_FILTER_CONTEXT pfc, DWORD dwNotifyType,
LPVOID *ppStFilter, LPVOID *ppStFilterOrg,
PSTR *ppvBuf1, int *pcbBuf, PSTR *ppvBuf2, int *pcbBuf2);
BOOL CleanupFC(DWORD dwNotifyType, LPVOID* pFilterStruct, LPVOID *pFilterStructOrg,
PSTR *ppvBuf1, int *pcbBuf, PSTR *ppvBuf2);
BOOL AuthenticateFilter();
BOOL CallAuthFilterIfNeeded(void);
BOOL FilterMapURL(PSTR pvBuf, WCHAR *wszPath, DWORD *pdwSize, DWORD dwBufNeeded, PSTR pszURLEx=NULL);
BOOL MapURLToPath(PSTR pszBuffer, PDWORD pdwSize, LPHSE_URL_MAPEX_INFO pUrlMapEx=NULL);
BOOL HandleAuthentication(void);
// Filter Callbacks
BOOL ServerSupportFunction(enum SF_REQ_TYPE sfReq,PVOID pData,DWORD ul1, DWORD ul2);
BOOL GetHeader(LPSTR lpszName, LPVOID lpvBuffer, LPDWORD lpdwSize);
BOOL SetHeader(LPSTR lpszName, LPSTR lpszValue);
BOOL AddResponseHeaders(LPSTR lpszHeaders,DWORD dwReserved);
// WebDav
BOOL HandleWebDav(void);
friend class CWebDav;
friend class CWebDavFileLockManager;
BOOL m_fOptionsAsterisk; // Is this an 'OPTIONS *' request we need special handeling for.
// ASP Setup Fcns
BOOL ExecuteASP();
void FillACB(void *p, HINSTANCE hInst);
BOOL ReceiveCompleteRequest(PASP_CONTROL_BLOCK pcb);
public:
CHttpRequest(SOCKET sock, BOOL fSecure) {
Init(sock,fSecure);
}
~CHttpRequest();
BOOL ReInit();
BOOL IsSecure(void) { return m_fHandleSSL; }
void GetUserAndGroupInfo(PAUTH_STATE pAuth);
AUTHLEVEL DeterminePermissionGranted(const WCHAR *wszUserList, AUTHLEVEL authDefault);
// VRoot Accessors
DWORD GetPerms(void) { return m_pVRoot ? m_pVRoot->dwPermissions : 0; }
AUTHLEVEL GetAuthReq(void) { return m_pVRoot ? m_pVRoot->AuthLevel : AUTH_PUBLIC; }
SCRIPT_TYPE GetScriptType(void) { return m_pVRoot ? m_pVRoot->ScriptType : SCRIPT_TYPE_NONE; }
BOOL AllowBasic(void) { return m_pVRoot ? m_pVRoot->fBasic : 0; }
BOOL AllowNTLM(void) { return m_pVRoot ? m_pVRoot->fNTLM : 0; }
BOOL AllowNegotiate(void) { return m_pVRoot ? m_pVRoot->fNegotiate : 0; }
BOOL AllowDirBrowse(void) { return m_pVRoot ? m_pVRoot->fDirBrowse : 0; }
WCHAR * GetUserList(void) { return m_pVRoot ? m_pVRoot->wszUserList : 0; }
BOOL URLHasTrailingSlash(int iURLLen=-1) {
return URLHasTrailingSlashA(m_pszURL,iURLLen);
}
void HandleRequest();
friend DWORD WINAPI HttpConnectionThread(LPVOID lpv);
friend void CloseAllConnections(void);
void RemoveFromList();
void GenerateLog(PSTR szBuffer, PDWORD pdwToWrite);
DWORD GetLogBufferSize();
BOOL SendData(PSTR pszBuf, DWORD dwLen, BOOL fCopyBuffer=FALSE);
BOOL SendEncryptedData(PSTR pszBuf, DWORD dwLen, BOOL fCopyBuffer);
// ISAPI Extension / ASP Specific
friend BOOL WINAPI GetServerVariable(HCONN hConn, PSTR psz, PVOID pv, PDWORD pdw);
friend BOOL WINAPI ReadClient(HCONN hConn, PVOID pv, PDWORD pdw);
friend BOOL WINAPI WriteClient(HCONN hConn, PVOID pv, PDWORD pdw, DWORD dw);
friend BOOL WINAPI ServerSupportFunction(HCONN hConn, DWORD dwReq, PVOID pvBuf, PDWORD pdwSize, PDWORD pdwType);
// ASP Specific
friend BOOL WINAPI Flush(HCONN hConn);
friend BOOL WINAPI Clear(HCONN hConn);
friend BOOL WINAPI SetBuffer(HCONN hConn, BOOL fBuffer);
friend BOOL WINAPI AddHeader (HCONN hConn, LPSTR lpszName, LPSTR lpszValue);
friend BOOL WINAPI ReceiveCompleteRequest(struct _ASP_CONTROL_BLOCK *pcb);
// SSL Specific
SECURITY_STATUS SSLDecrypt(PSTR pszBuf, DWORD dwLen, DWORD *pdwBytesDecrypted, DWORD *pdwOffset, DWORD *pdwExtraRequired, DWORD *pdwIgnore, BOOL *pfCompletedRenegotiate);
BOOL HandleSSLClientCertCheck(void);
// Filter Specific
BOOL CallFilter(DWORD dwNotifyType, PSTR *ppvBuf1 = NULL,int *pcbBuf = NULL,
PSTR *ppvBuf2 = NULL, int *pcbBuf2 = NULL);
BOOL FilterNoResponse(void);
// Filters Friends (exposed to Filter dll)
friend BOOL WINAPI GetServerVariable(PHTTP_FILTER_CONTEXT pfc, PSTR psz, PVOID pv, PDWORD pdw);
friend BOOL WINAPI AddResponseHeaders(PHTTP_FILTER_CONTEXT pfc,LPSTR lpszHeaders,DWORD dwReserved);
friend VOID* WINAPI AllocMem(PHTTP_FILTER_CONTEXT pfc, DWORD cbSize, DWORD dwReserved);
friend BOOL WINAPI WriteClient(PHTTP_FILTER_CONTEXT pfc, PVOID pv, PDWORD pdw, DWORD dwFlags);
friend BOOL WINAPI ServerSupportFunction(PHTTP_FILTER_CONTEXT pfc,enum SF_REQ_TYPE sfReq,
PVOID pData, DWORD ul1, DWORD ul2);
friend BOOL WINAPI SetHeader(PHTTP_FILTER_CONTEXT pfc, LPSTR lpszName, LPSTR lpszValue);
friend BOOL WINAPI GetHeader(PHTTP_FILTER_CONTEXT pfc, LPSTR lpszName, LPVOID lpvBuffer, LPDWORD lpdwSize);
};
void SendFile(SOCKET sock, HANDLE hFile, CHttpRequest *pRequest);
// Response object. This object doesn't own any of the handles or pointers
// it uses so it doesnt free anything. The caller is responsible in all cases
// for keeping the handles & memory alive while this object is extant & freeing
// them as approp at a later time
class CHttpResponse {
CONNHEADER m_connhdr;
PCSTR m_pszType;
DWORD m_dwLength;
PCSTR m_pszRedirect;
PCSTR m_pszExtraHeaders;
PCSTR m_pszBody;
HANDLE m_hFile;
char m_szMime[MAXMIME];
CHttpRequest *m_pRequest; // calling request class, for callbacks
private:
void SetTypeFromExtW(PCWSTR wszExt) {
DEBUGCHK(!m_pszType);
if (wszExt) {
m_pRequest->GetContentTypeOfRequestURI(m_szMime,sizeof(m_szMime),wszExt);
m_pszType = m_szMime;
}
else
m_pszType = cszOctetStream;
}
public:
CHttpResponse(CHttpRequest *pRequest, RESPONSESTATUS status=STATUS_OK, CONNHEADER connhdr=CONN_UNKNOWN) {
ZEROMEM(this);
m_connhdr = (connhdr!=CONN_UNKNOWN) ? connhdr : pRequest->GetConnHeader();
m_pRequest = pRequest;
m_pRequest->m_rs = status;
}
// for generated bodies (dir listings, redirects etc) & default bodies
void SetBody(PCSTR pszBody, PCSTR pszType) {
DEBUGCHK(!m_hFile && !m_pszBody && !m_pszType && !m_dwLength);
m_pszType = pszType;
m_dwLength = strlen(pszBody);
m_pszBody = pszBody;
}
// for error reponses (NOTE: some have no body, and hence psztatusBdy will be NULL in the table)
void SetDefaultBody() {
if(rgStatus[m_pRequest->m_rs].pszStatusBody)
SetBody(rgStatus[m_pRequest->m_rs].pszStatusBody, cszTextHtml);
}
// for real files
void SetBody(HANDLE hFile, PCWSTR wszExt=NULL, DWORD dwLen=0) {
DEBUGCHK(!m_hFile && !m_pszBody && !m_pszType && !m_dwLength);
m_hFile = hFile;
SetTypeFromExtW(wszExt);
if (dwLen)
m_dwLength = dwLen;
else {
m_dwLength = GetFileSize(m_hFile, 0);
if (m_dwLength == 0)
m_dwLength = -1; // Use this to signify empty file, needed for keep-alives
}
}
// Setup "Content-Length: 0" to make keep-alives happy.
void SetZeroLenBody(void) {
m_dwLength = -1;
}
void SetLength(DWORD dw) {
m_dwLength = dw;
}
void UnSetMimeType(void) {
m_pszType = 0;
}
public:
void SendHeadersAndDefaultBodyIfAvailable(PCSTR pszExtraHeaders, PCSTR pszNewRespStatus);
void SendRedirect(PCSTR pszRedirect, BOOL fFromFilter=FALSE);
void SendResponse(PCSTR pszExtraHeaders=NULL, PCSTR pszNewRespStatus=NULL, BOOL fFromFilter=FALSE) {
// see FilterNoResponse for comments on this
if (!fFromFilter && m_pRequest->FilterNoResponse())
return;
SendHeadersAndDefaultBodyIfAvailable(pszExtraHeaders,pszNewRespStatus);
if (VERB_HEAD == m_pRequest->m_idMethod)
return;
if(m_hFile)
SendFile(m_pRequest->m_socket, m_hFile, m_pRequest);
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -