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

📄 request.h

📁 Windows CE 6.0 Server 源码
💻 H
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*--
Module Name: REQUEST.H
Abstract: HTTP request class
--*/


// Scalar types used by CHTTPRequest
typedef enum {
	TOK_DATE,
	TOK_PRAGMA,
	TOK_COOKIE,
	TOK_ACCEPT,
	TOK_REFERER,
	TOK_UAGENT,
	TOK_AUTH,
	TOK_IFMOD,
	TOK_TYPE,
	TOK_LENGTH,
	TOK_ENCODING,
	TOK_CONNECTION,
	TOK_HOST,
}
TOKEN;

// NOTE: This follows same order as "const char *rg_cszMethods" list in parser.cpp
//       and also davTable in webdav.cpp
typedef enum {
	VERB_UNKNOWN,
	VERB_GET,
	VERB_HEAD,
	VERB_POST,
	VERB_OPTIONS,
	VERB_PUT,
	VERB_MOVE,
	VERB_COPY,
	VERB_DELETE,
	VERB_MKCOL,
	VERB_PROPFIND,
	VERB_PROPPATCH,
//	VERB_SEARCH,
	VERB_LOCK,
	VERB_UNLOCK,
#if 1 
	VERB_LAST_VALID = VERB_UNLOCK,
#else // unsupported DAV vebs
	VERB_SUBSCRIBE,
	VERB_UNSUBSCRIBE,
	VERB_POLL,
	VERB_BDELETE,
	VERB_BCOPY,
	VERB_BMOVE,
	VERB_BPROPPATCH,
	VERB_BPROPFIND,
	VERB_X_MS_ENUMATTS,
	VERB_LAST_VALID = VERB_X_MS_ENUMATTS,
#endif
}
VERB;

inline BOOL IsBasic(AUTHTYPE a)          { return (a == AUTHTYPE_BASIC); }
inline BOOL IsNTLM(AUTHTYPE a)           { return (a == AUTHTYPE_NTLM); }
inline BOOL IsNegotiate(AUTHTYPE a)      { return (a == AUTHTYPE_NEGOTIATE); }
inline BOOL IsSupportedAuth(AUTHTYPE a)  { return (IsNTLM(a) || IsBasic(a) || IsNegotiate(a)); }

typedef enum {
	CONN_NONE    = 0,
	CONN_CLOSE   = 1,
	CONN_KEEP    = 2,
	CONN_UNKNOWN = 3
}
CONNHEADER;

#define CHTTPREQUEST_SIG 0xAB0D

// If strlen(url) is already known, don't recalc it but pass it in.  If unknown set = -1.
inline BOOL URLHasTrailingSlashA(PCSTR pszURL, int iURLLen=-1) {
	if (iURLLen == -1)
		iURLLen = strlen(pszURL);

	DEBUGCHK((iURLLen == (int)strlen(pszURL)) && (iURLLen>=1));
	return (pszURL[iURLLen-1]=='/' || pszURL[iURLLen-1]=='\\');
}

inline BOOL URLHasTrailingSlashW(WCHAR *wszURL, int iURLLen=-1) {
	if (iURLLen == -1)
		iURLLen = wcslen(wszURL);

	DEBUGCHK((iURLLen == (int)wcslen(wszURL)) && (iURLLen>=1));
	return (wszURL[iURLLen-1]=='/' || wszURL[iURLLen-1]=='\\');
}

inline void RemoveTrailingSlashIfNeededA(PSTR pszURL, int iURLLen=-1) {
	if (iURLLen == -1)
		iURLLen = strlen(pszURL);

	if (URLHasTrailingSlashA(pszURL,iURLLen))
		pszURL[iURLLen-1] = 0;
}

RESPONSESTATUS GLEtoStatus(int iGLE);


// This object is the top-level object for an incoming HTTP request. One such object
// is created per request & a thread is created to handle it.

class CFilterInfo;
class CWebDav;
class CHttpResponse;

class CHttpRequest {
	// socket
	DWORD   m_dwSig;
	SOCKET	m_socket;
	CHttpRequest *m_pNext;
	
	// buffers
	CBuffer m_bufRequest;
	CBuffer m_bufRespBody;
	
	// method, version, URL etc. Direct results of parse
	PSTR	m_pszMethod;
	PSTR	m_pszURL;
	PSTR	m_pszContentType;
	DWORD	m_dwContentLength;
	PSTR	m_pszAccept;
	FILETIME m_ftIfModifiedSince;
	DWORD	m_dwIfModifiedLength;
	PSTR 	m_pszCookie;
	PSTR    m_pszHost;

	// Decoded URL (indirect results of parse)
	PSTR	m_pszQueryString;
	PWSTR	m_wszPath;
	PWSTR	m_wszExt;
	PSTR    m_pszPathInfo;
	PSTR	m_pszPathTranslated;
	DWORD   m_dwFileAttributes;  // results of GetFileAttributes(m_wszPath) call.

	DWORD   m_dwInitialPostRead;  // how much we read off wire before calling ISAPI extension
	DWORD   m_ccWPath; // # of wide chars of m_wszPath.

	PVROOTINFO m_pVRoot; // do NOT free, points to global data that is alloced/freed on server init/deinit.

	// Logging members
	PSTR	m_pszLogParam;
	RESPONSESTATUS m_rs;

	BOOL m_fBufferedResponse;	// Are we using m_bufResponse or sending straight to client?
	HRINPUT m_hrPreviousReadClient;    // Should next call to ReadClient() timeout?

	// Parsing functions
	void FreeHeaders(void) {
		MyFree(m_pszMethod);
		MyFree(m_pszURL);
		MyFree(m_pszContentType);
		MyFree(m_pszAccept);
		MyFree(m_pszQueryString);
		MyFree(m_wszPath);
		MyFree(m_wszExt);
		MyFree(m_pszCookie);
		MyFree(m_pszHost);
		MyFree(m_pszLogParam);	
		MyFree(m_pszPathInfo);
		MyFree(m_pszPathTranslated);
		MyFree(m_pszAuthType);
	}
	BOOL ParseHeaders();
	BOOL MyCrackURL(PSTR pszRawURL, int iLen);

	BOOL CheckAuth(AUTHLEVEL auth) {
		return (m_AuthLevelGranted >= auth) ? TRUE : FALSE;
	}

public:
	BOOL ParseMethod(PCSTR pszMethod, int cbMethod);
	BOOL ParseContentLength(PCSTR pszMethod, TOKEN id);
	BOOL ParseContentType(PCSTR pszMethod, TOKEN id);
	BOOL ParseIfModifiedSince(PCSTR pszMethod, TOKEN id);
	BOOL ParseAuthorization(PCSTR pszMethod, TOKEN id);
	BOOL ParseAccept(PCSTR pszMethod, TOKEN id);
	BOOL ParseConnection(PCSTR pszMethod, TOKEN id);
	BOOL ParseCookie(PCSTR pszMethod, TOKEN id);
	BOOL ParseHost(PCSTR pszMethod, TOKEN id);
	BOOL HandleNTLMNegotiateAuth(PSTR pszSecurityToken, BOOL fUseNTLM);
	PSTR    m_pszSecurityOutBuf;		// buffer to send client on NTLM/negotiate response, Base64 encoded
	DWORD   m_dwVersion;	// LOWORD=minor, HIWORD=major.  
	VERB	m_idMethod;
	CBuffer m_bufRespHeaders;
	CFilterInfo *m_pFInfo;		// Filter state information
	BOOL    m_fKeepAlive;
	BOOL    m_fResponseHTTP11;  // put "HTTP/1.1" in response headers?  Currently only WebDAV will spit out HTTP 1.1 headers, so an HTTP/1.1 request to non WebDAV resource still returns 1.0.

	DWORD   MinorHTTPStatus(void) { return m_fResponseHTTP11 ? 1 : 0; }
	RESPONSESTATUS GetStatus(void) { return m_rs; }

#if defined (DEBUG)
	// When HTTP header buf has a \0 temporarily put into it to create a string, no further 
	// calls to FindHttpHeader can be made, as header we're looking for maybe after '\0'.
	BOOL             m_fHeadersInvalid;     
	void             DebugSetHeadersInvalid(BOOL f) { m_fHeadersInvalid = f; }
#else
	void             DebugSetHeadersInvalid(BOOL f) { ; }
#endif

	PSTR FindHttpHeader(PCSTR szHeaderName, DWORD ccHeaderName);
	BOOL TranslateRequestToScript(void);

	// which set of config variables (vroots, auth, etc...) to use, depending on website request services.
	// Note that certain functionality (the thread pool, ISAPI extension dll cache, 
	// parts of auth like function table interfaces into security DLLs, and ISAPI filters)
	// are handled globally and will access g_pVars (default website) directly.
	CGlobalVariables *m_pWebsite;
	BOOL m_fResolvedHostWebSite;

	//  When using SSL client certificates, we don't use standard BASIC/NTLM/... 
	//  authentication at the same time.
	BOOL SendAuthenticate(void)  { return !(m_SSLInfo.m_pClientCertContext); }

	void CloseSocket(void) {
		if (m_socket) {
			// In certain scenarios, HTTPD may not be reading the last 2 bytes of content.
			// Read them now if they are available so we do not send a TCP reset to the client.
			// For certain TCP stacks, receiving this reset will cause it to kill the client
			// connection even though HTTPD has sent back all the required bytes and closed the connection.
			BYTE recvBuf[4]; // Recv up to 4 bytes just in case
			RecvToBuf(m_socket,recvBuf,sizeof(recvBuf),0);

			// Now perform socket shutdown.
			shutdown(m_socket, 1);
			closesocket(m_socket);
			m_socket = 0;
		}
	}

	// In some scenarios it's easier to manipulate m_wszPath if it can 
	// be assumed there's a '\' as trailing character.
	void AddTrailingSlashToPhysicalPath(void) {
		if ((m_ccWPath > 1) && (! URLHasTrailingSlashW(m_wszPath,m_ccWPath))) {
			m_wszPath[m_ccWPath++]  = '\\';
			m_wszPath[m_ccWPath]    = 0;
		}
		DEBUGCHK(m_ccWPath == wcslen(m_wszPath));
	}

	void RemoveTrailingSlashToPhysicalPath(void) {
		if ((m_ccWPath > 1) && URLHasTrailingSlashW(m_wszPath,m_ccWPath)) {
			m_wszPath[--m_ccWPath]  = 0;
		}
		DEBUGCHK((m_wszPath==NULL) || m_ccWPath == wcslen(m_wszPath));
	}

	BOOL IsRootPath(void) {
		return ((m_wszPath[0] == '\\' || m_wszPath[0] == '/') && m_wszPath[1] == 0);
	}

	BOOL IsRootVDir(void) {
		return (IsSlash(m_pszURL[0]) && m_pszURL[1] == 0);
	}

	// Only case we'd be inactive is during shutdown.
	BOOL IsActive(void)  { return (m_socket != 0); }
	CONNHEADER GetConnHeader()   { return m_fKeepAlive ? CONN_KEEP : CONN_CLOSE; }

	void GetContentTypeOfRequestURI(PSTR szContentType, DWORD ccContentType, const WCHAR *wszExt=NULL);
	
private:
	friend class CHttpResponse;

	// Authentication data members
	AUTHLEVEL m_AuthLevelGranted;
	PSTR	m_pszAuthType;
	PSTR	m_pszRawRemoteUser;		// Holds base64 encoded data, before auth decodes it
	PSTR	m_pszRemoteUser;
	WCHAR*  m_wszRemoteUser;
	WCHAR*  m_wszMemberOf;
	PSTR	m_pszPassword;

⌨️ 快捷键说明

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