📄 parser.cpp
字号:
//
// 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: PARSER.CPP
Abstract: HTTP request parser
--*/
#include "httpd.h"
// Methods
// NOTE: This follows same order as "enum VERB" list in request.h.
const char *rg_cszMethods[] = {
"GET",
"HEAD",
"POST",
"OPTIONS",
"PUT",
"MOVE",
"COPY",
"DELETE",
"MKCOL",
"PROPFIND",
"PROPPATCH",
// "SEARCH",
"LOCK",
"UNLOCK",
#if 0 // unsupported DAV vebs
"SUBSCRIBE",
"UNSUBSCRIBE",
"POLL",
"BDELETE",
"BCOPY",
"BMOVE",
"BPROPPATCH",
"BPROPFIND",
"X-MS-ENUMATTS",
#endif
};
const int cKnownMethods = ARRAYSIZEOF(rg_cszMethods);
// other Header tokens
const char cszHTTPVER[] = "HTTP/%d.%d";
// String constants
// const CHAR cszAccept_CHAR set[] = "Accept-CHAR set:";
// const CHAR cszAccept_Encoding[] = "Accept-Encoding:";
// const CHAR cszAccept_Language[] = "Accept-Language:";
const CHAR cszAccept_Ranges[] = "Accept-Ranges:";
const DWORD ccAccept_Ranges = SVSUTIL_CONSTSTRLEN(cszAccept_Ranges);
const CHAR cszAccept[] = "Accept:";
const DWORD ccAccept = SVSUTIL_CONSTSTRLEN(cszAccept);
// const CHAR cszAge[] = "Age:";
const CHAR cszAllow[] = "Allow:";
const DWORD ccAllow = SVSUTIL_CONSTSTRLEN(cszAllow);
// const CHAR cszAtomic[] = "Atomic:";
const CHAR cszAuthorization[] = "Authorization:";
const DWORD ccAuthorization = SVSUTIL_CONSTSTRLEN(cszAuthorization);
// const CHAR cszCollection_Member[] = "Collection-Member:";
// const CHAR cszCompatibility[] = "Compatibility:";
const CHAR cszConnection[] = "Connection:";
const DWORD ccConnection = SVSUTIL_CONSTSTRLEN(cszConnection);
// const CHAR cszContent_Base[] = "Content-Base:";
// const CHAR cszContent_Encoding[] = "Content-Encoding:";
// const CHAR cszContent_Language[] = "Content-Language:";
const CHAR cszContent_Length[] = "Content-Length:";
const DWORD ccContent_Length = SVSUTIL_CONSTSTRLEN(cszContent_Length);
const CHAR cszContent_Location[] = "Content-Location:";
const DWORD ccContent_Location = SVSUTIL_CONSTSTRLEN(cszContent_Location);
// const CHAR cszContent_MD5[] = "Content-MD5:";
const CHAR cszContent_Range[] = "Content-Range:";
const DWORD ccContent_Range = SVSUTIL_CONSTSTRLEN(cszContent_Range);
const CHAR cszContent_Type[] = "Content-Type:";
const DWORD ccContent_Type = SVSUTIL_CONSTSTRLEN(cszContent_Type);
// const CHAR cszContent_Disposition[] = "Content-Disposition:";
const CHAR cszCookie[] = "Cookie:";
const DWORD ccCookie = SVSUTIL_CONSTSTRLEN(cszCookie);
const CHAR cszDate[] = "Date:";
const DWORD ccDate = SVSUTIL_CONSTSTRLEN(cszDate);
const CHAR cszDepth[] = "Depth:";
const DWORD ccDepth = SVSUTIL_CONSTSTRLEN(cszDepth);
const CHAR cszDestination[] = "Destination:";
const DWORD ccDestination = SVSUTIL_CONSTSTRLEN(cszDestination);
// const CHAR cszDestroy[] = "Destroy:";
// const CHAR cszExpires[] = "Expires:";
const CHAR cszETag[] = "ETag:";
const DWORD ccETag = SVSUTIL_CONSTSTRLEN(cszETag);
// const CHAR cszFrom[] = "From:";
const CHAR cszHost[] = "Host:";
const DWORD ccHost = SVSUTIL_CONSTSTRLEN(cszHost);
const CHAR cszIfToken[] = "If:";
const DWORD ccIfToken = SVSUTIL_CONSTSTRLEN(cszIfToken);
const CHAR cszIf_Match[] = "If-Match:";
const DWORD ccIf_Match = SVSUTIL_CONSTSTRLEN(cszIf_Match);
const CHAR cszIf_Modified_Since[] = "If-Modified-Since:";
const DWORD ccIf_Modified_Since = SVSUTIL_CONSTSTRLEN(cszIf_Modified_Since);
const CHAR cszIf_None_Match[] = "If-None-Match:";
const DWORD ccIf_None_Match = SVSUTIL_CONSTSTRLEN(cszIf_None_Match);
const CHAR cszIf_None_State_Match[] = "If-None-State-Match:";
const DWORD ccIf_None_State_Match = SVSUTIL_CONSTSTRLEN(cszIf_None_State_Match);
const CHAR cszIf_Range[] = "If-Range:";
const DWORD ccIf_Range = SVSUTIL_CONSTSTRLEN(cszIf_Range);
const CHAR cszIf_State_Match[] = "If-State-Match:";
const DWORD ccIf_State_Match = SVSUTIL_CONSTSTRLEN(cszIf_State_Match);
const CHAR cszIf_Unmodified_Since[] = "If-Unmodified-Since:";
const DWORD ccIf_Unmodified_Since = SVSUTIL_CONSTSTRLEN(cszIf_Unmodified_Since);
// const CHAR cszLast_Modified[] = "Last-Modified:";
const CHAR cszLocation[] = "Location:";
const DWORD ccLocation = SVSUTIL_CONSTSTRLEN(cszLocation);
const CHAR cszLockInfo[] = "Lock-Info:";
const DWORD ccLockInfo = SVSUTIL_CONSTSTRLEN(cszLockInfo);
const CHAR cszLockToken[] = "Lock-Token:";
const DWORD ccLockToken = SVSUTIL_CONSTSTRLEN(cszLockToken);
// const CHAR cszMS_Author_Via[] = "MS-Author-Via:";
// const CHAR cszMS_Exchange_FlatURL[] = "MS-Exchange-Permanent-URL:";
const CHAR cszOverwrite[] = "Overwrite:";
const DWORD ccOverwrite = SVSUTIL_CONSTSTRLEN(cszOverwrite);
const CHAR cszAllowRename[] = "Allow-Rename:";
const DWORD ccAllowRename = SVSUTIL_CONSTSTRLEN(cszAllowRename);
const CHAR cszPublic[] = "Public:";
const DWORD ccPublic = SVSUTIL_CONSTSTRLEN(cszPublic);
const CHAR cszRange[] = "Range:";
const DWORD ccRange = SVSUTIL_CONSTSTRLEN(cszRange);
const CHAR cszReferer[] = "Referer:";
const DWORD ccReferer = SVSUTIL_CONSTSTRLEN(cszReferer);
// const CHAR cszRetry_After[] = "Retry-After:";
const CHAR cszServer[] = "Server:";
const DWORD ccServer = SVSUTIL_CONSTSTRLEN(cszServer);
// const CHAR cszSet_Cookie[] = "Set-Cookie:";
const CHAR cszTimeOut[] = "Timeout:";
const DWORD ccTimeOut = SVSUTIL_CONSTSTRLEN(cszTimeOut);
const CHAR cszTransfer_Encoding[] = "Transfer-Encoding:";
const DWORD ccTransfer_Encoding = SVSUTIL_CONSTSTRLEN(cszTransfer_Encoding);
const CHAR cszTranslate[] = "Translate:";
const DWORD ccTranslate = SVSUTIL_CONSTSTRLEN(cszTranslate);
// const CHAR cszUpdate[] = "Update:";
// const CHAR cszUser_Agent[] = "User-Agent:";
// const CHAR cszVary[] = "Vary:";
// const CHAR cszWarning[] = "Warning:";
const CHAR cszWWW_Authenticate[] = "WWW-Authenticate:";
const DWORD ccWWW_Authenticate = SVSUTIL_CONSTSTRLEN(cszWWW_Authenticate);
// const CHAR cszVersioning_Support[] = "Versioning-Support:";
// const CHAR cszBrief[] = "Brief:";
//
// Common header values
//
const CHAR cszDateFmtGMT[] = "%3s, %02d %3s %04d %02d:%02d:%02d GMT";
const CHAR* rgWkday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 0 };
const CHAR* rgMonth[] = { "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0 };
const CHAR cszNone[] = "none";
const DWORD ccNone = SVSUTIL_CONSTSTRLEN(cszNone);
const CHAR cszChunked[] = "chunked";
const DWORD ccChunked = SVSUTIL_CONSTSTRLEN(cszChunked);
const CHAR cszBasic[] = "Basic";
const DWORD ccBasic = SVSUTIL_CONSTSTRLEN(cszBasic);
const CHAR cszNTLM[] = "NTLM";
const DWORD ccNTLM = SVSUTIL_CONSTSTRLEN(cszNTLM);
const CHAR cszNegotiate[] = "Negotiate";
const DWORD ccNegotiate = SVSUTIL_CONSTSTRLEN(cszNegotiate);
const CHAR cszBytes[] = "bytes";
const DWORD ccBytes = SVSUTIL_CONSTSTRLEN(cszBytes);
const CHAR cszAnd[] = "and";
const DWORD ccAnd = SVSUTIL_CONSTSTRLEN(cszAnd);
const CHAR cszOr[] = "or";
const DWORD ccOr = SVSUTIL_CONSTSTRLEN(cszOr);
const CHAR cszMS_Author_Via_Dav[] = "DAV";
const DWORD ccMS_Author_Via_Dav = SVSUTIL_CONSTSTRLEN(cszMS_Author_Via_Dav);
const CHAR cszHttpPrefix[] = "http://";
const DWORD ccHttpPrefix = SVSUTIL_CONSTSTRLEN(cszHttpPrefix);
const CHAR cszHttpsPrefix[] = "https://";
const DWORD ccHttpsPrefix = SVSUTIL_CONSTSTRLEN(cszHttpsPrefix);
const CHAR cszRespStatus[] = "HTTP/1.%d %d %s\r\n";
const DWORD ccRespStatus = SVSUTIL_CONSTSTRLEN(cszRespStatus);
const CHAR cszRespServer[] = "Server: %s\r\n";
const DWORD ccRespServer = SVSUTIL_CONSTSTRLEN(cszRespServer);
const CHAR cszRespType[] = "Content-Type: %s\r\n";
const DWORD ccRespType = SVSUTIL_CONSTSTRLEN(cszRespType);
const CHAR cszRespLength[] = "Content-Length: %d\r\n";
const DWORD ccRespLength = SVSUTIL_CONSTSTRLEN(cszRespLength);
const CHAR cszRespDate[] = "Date: ";
const DWORD ccRespDate = SVSUTIL_CONSTSTRLEN(cszRespDate);
const CHAR cszRespLocation[] = "Location: ";
const DWORD ccRespLocation = SVSUTIL_CONSTSTRLEN(cszRespLocation);
const CHAR cszConnectionResp[] = "Connection: %s\r\n";
const DWORD ccConnectionResp = SVSUTIL_CONSTSTRLEN(cszConnectionResp);
const CHAR cszKeepAlive[] = "keep-alive";
const DWORD ccKeepAlive = SVSUTIL_CONSTSTRLEN(cszKeepAlive);
const CHAR cszCRLF[] = "\r\n";
const DWORD ccCRLF = SVSUTIL_CONSTSTRLEN(cszCRLF);
const CHAR cszRespLastMod[] = "Last-Modified:";
const DWORD ccRespLastMod = SVSUTIL_CONSTSTRLEN(cszRespLastMod);
const CHAR cszOpaquelocktokenPrefix[] = "opaquelocktoken:";
const DWORD ccOpaquelocktokenPrefix = SVSUTIL_CONSTSTRLEN(cszOpaquelocktokenPrefix);
#define PFNPARSE(x) &(CHttpRequest::Parse##x)
#define TABLEENTRY(csz, id, pfn) { csz, sizeof(csz)-1, id, PFNPARSE(pfn) }
typedef (CHttpRequest::*PFNPARSEPROC)(PCSTR pszTok, TOKEN idHeader);
typedef struct tagHeaderDesc {
const char* sz;
int iLen;
TOKEN id;
PFNPARSEPROC pfn;
} HEADERDESC;
const HEADERDESC rgHeaders[] =
{
// General headers
TABLEENTRY(cszConnection, TOK_CONNECTION, Connection),
//TABLEENTRY(cszDate, TOK_DATE, Date),
//TABLEENTRY(cszPragma, TOK_PRAGMA, Pragma),
// Request headers
TABLEENTRY(cszCookie, TOK_COOKIE, Cookie),
TABLEENTRY(cszAccept, TOK_ACCEPT, Accept),
//TABLEENTRY(cszReferer, TOK_REFERER Referer),
//TABLEENTRY(cszUserAgent,TOK_UAGENT, UserAgent),
TABLEENTRY(cszAuthorization, TOK_AUTH, Authorization),
TABLEENTRY(cszIf_Modified_Since, TOK_IFMOD, IfModifiedSince),
// Entity Headers
//TABLEENTRY(cszContentEncoding, TOK_ENCODING Encoding),
TABLEENTRY(cszContent_Type, TOK_TYPE, ContentType),
TABLEENTRY(cszContent_Length, TOK_LENGTH, ContentLength),
TABLEENTRY(cszHost, TOK_HOST, Host),
{ 0, 0, (TOKEN)0, 0}
};
// Parse all the headers, line by line
BOOL CHttpRequest::ParseHeaders() {
DEBUG_CODE_INIT;
PSTR pszTok;
PWSTR pwszTemp;
PSTR pszPathInfo = NULL;
int i, iLen;
BOOL ret = FALSE;
if (!m_bufRequest.NextTokenWS(&pszTok, &iLen)) {
m_rs = STATUS_BADREQ;
myleave(287);
}
if (! ParseMethod(pszTok,iLen)) {
m_rs = STATUS_BADREQ;
myleave(288);
}
if (!m_bufRequest.NextLine()) {
m_rs = STATUS_BADREQ;
myleave(290);
}
// outer-loop. one header per iteration
while (m_bufRequest.NextTokenHeaderName(&pszTok, &iLen)) {
// compare token with tokens in table
for (i=0; rgHeaders[i].sz; i++) {
//DEBUGMSG(ZONE_PARSER, (L"HTTPD: Comparing %a %d %d\r\n", rgHeaders[i].sz, rgHeaders[i].iLen, rgHeaders[i].pfn));
if ( ((int)rgHeaders[i].iLen == iLen) &&
0==_memicmp(rgHeaders[i].sz, pszTok, iLen) )
break;
}
if (rgHeaders[i].pfn) {
DEBUGMSG(ZONE_PARSER, (L"HTTPD: Parsing %a\r\n", rgHeaders[i].sz));
// call the specific function to parse this header.
if (! ((this->*(rgHeaders[i].pfn))(pszTok, rgHeaders[i].id)) ) {
DEBUGMSG(ZONE_PARSER, (L"HTTPD: Parser: failed to parse %a\r\n", rgHeaders[i].sz));
// If none of the Parse functions set last error, set to bad req
if (m_rs == STATUS_OK)
m_rs = STATUS_BADREQ;
myleave(296);
}
}
else {
DEBUGMSG(ZONE_PARSER, (L"HTTPD: Ignoring header %a\r\n", pszTok));
}
if (!m_bufRequest.NextLine()) {
m_rs = STATUS_BADREQ;
myleave(290);
}
}
if (!m_bufRequest.NextLine()) { // eat the blank line
m_rs = STATUS_BADREQ;
myleave(295);
}
DEBUGMSG(ZONE_PARSER, (L"HTTPD: Parser: DONE\r\n"));
// check what we got
if (!m_pszMethod) {
DEBUGMSG(ZONE_PARSER, (L"HTTPD: Parser: missing URL or method, illformatted Request-line\r\n"));
m_rs = STATUS_BADREQ;
myleave(291);
}
// Once we've read the request line, give filter shot at modifying the
// remaining headers.
if (g_pVars->m_fFilters &&
! CallFilter(SF_NOTIFY_PREPROC_HEADERS))
myleave(292);
if (!m_fResolvedHostWebSite) {
// Now that we have Host: (if we'll get it) map website on first request.
m_pWebsite = MapWebsite(m_socket,m_pszHost);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -