2022-05-23 02:35:42 +00:00
|
|
|
|
#include "HttpHead.h"
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
const unsigned int asciiTableData[256] =
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
|
|
|
|
0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004,
|
|
|
|
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
|
|
|
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
|
|
|
|
0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
|
|
|
|
|
0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
|
|
|
|
|
0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
|
|
|
|
|
0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
|
|
|
|
|
0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
|
|
|
|
|
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
|
|
|
|
|
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
|
|
|
|
|
0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
|
|
|
|
|
0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
|
|
|
|
|
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
|
|
|
|
|
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
|
|
|
|
|
0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004
|
|
|
|
|
/* the upper 128 are all zeroes */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void TrimString(std::string& str)
|
|
|
|
|
{
|
|
|
|
|
std::string str1;
|
|
|
|
|
bool add1 = false;
|
|
|
|
|
std::string::const_iterator iter1;
|
|
|
|
|
for (iter1 = str.begin(); iter1 != str.end(); ++iter1)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
int c = (HGByte)(*iter1);
|
|
|
|
|
if (!add1)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (!isspace(c))
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
|
|
|
|
str1.push_back(c);
|
2022-05-23 10:29:23 +00:00
|
|
|
|
add1 = true;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
else
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
str1.push_back(c);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (str1.empty())
|
|
|
|
|
{
|
|
|
|
|
str.clear();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::string str2;
|
|
|
|
|
bool add2 = false;
|
|
|
|
|
std::string::const_reverse_iterator iter2;
|
|
|
|
|
for (iter2 = str1.rbegin(); iter2 != str1.rend(); ++iter2)
|
|
|
|
|
{
|
|
|
|
|
int c = (HGByte)(*iter2);
|
|
|
|
|
if (!add2)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (!isspace(c))
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
|
|
|
|
str2.push_back(c);
|
2022-05-23 10:29:23 +00:00
|
|
|
|
add2 = true;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
else
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
str2.push_back(c);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (str2.empty())
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
str.clear();
|
|
|
|
|
return;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
str = std::string(str2.rbegin(), str2.rend());
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
HttpHead::HttpHead()
|
|
|
|
|
{
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
HttpHead::~HttpHead()
|
|
|
|
|
{
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
bool HttpHead::Parse(const std::string& head)
|
|
|
|
|
{
|
|
|
|
|
AnalysisHead(head, m_requestMethod, m_requestURIPath, m_requestURIQueryInfos,
|
|
|
|
|
m_requestURIFragment, m_requestHttpVersion, m_headInfos);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
void HttpHead::Clear()
|
|
|
|
|
{
|
|
|
|
|
m_requestMethod.clear();
|
|
|
|
|
m_requestURIPath.clear();
|
|
|
|
|
m_requestURIQueryInfos.clear();
|
|
|
|
|
m_requestURIFragment.clear();
|
|
|
|
|
m_requestHttpVersion.clear();
|
|
|
|
|
m_headInfos.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string HttpHead::GetRequestMethod() const
|
|
|
|
|
{
|
|
|
|
|
return m_requestMethod;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::string HttpHead::GetRequestURIPath() const
|
|
|
|
|
{
|
|
|
|
|
return m_requestURIPath;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
HttpPairs HttpHead::GetRequestURIQueryInfos() const
|
|
|
|
|
{
|
|
|
|
|
return m_requestURIQueryInfos;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::string HttpHead::GetRequestURIFragment() const
|
|
|
|
|
{
|
|
|
|
|
return m_requestURIFragment;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string HttpHead::GetRequestHttpVersion() const
|
|
|
|
|
{
|
|
|
|
|
return m_requestHttpVersion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HttpPairs HttpHead::GetHeadInfos() const
|
|
|
|
|
{
|
|
|
|
|
return m_headInfos;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
int HttpHead::GetContentLength() const
|
|
|
|
|
{
|
|
|
|
|
int len = 0;
|
|
|
|
|
for (int i = 0; i < (int)m_headInfos.size(); ++i)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
|
|
|
|
#if defined(HG_CMP_MSC)
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (0 == _stricmp("Content-Length", m_headInfos[i].first.c_str()))
|
2022-05-23 02:35:42 +00:00
|
|
|
|
#else
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (0 == strcasecmp("Content-Length", m_headInfos[i].first.c_str()))
|
2022-05-23 02:35:42 +00:00
|
|
|
|
#endif
|
2022-05-23 10:29:23 +00:00
|
|
|
|
{
|
|
|
|
|
len = atoi(m_headInfos[i].second.c_str());
|
|
|
|
|
break;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string HttpHead::GetContentType() const
|
|
|
|
|
{
|
|
|
|
|
std::string type;
|
|
|
|
|
for (int i = 0; i < (int)m_headInfos.size(); ++i)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
|
|
|
|
#if defined(HG_CMP_MSC)
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (0 == _stricmp("Content-Type", m_headInfos[i].first.c_str()))
|
2022-05-23 02:35:42 +00:00
|
|
|
|
#else
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (0 == strcasecmp("Content-Type", m_headInfos[i].first.c_str()))
|
2022-05-23 02:35:42 +00:00
|
|
|
|
#endif
|
2022-05-23 10:29:23 +00:00
|
|
|
|
{
|
|
|
|
|
type = m_headInfos[i].second.c_str();
|
|
|
|
|
break;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string HttpHead::GetValue(const HttpPairs& infos, const std::string& key)
|
|
|
|
|
{
|
|
|
|
|
std::string value;
|
|
|
|
|
for (int i = 0; i < (int)infos.size(); ++i)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (key == infos[i].first)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
value = infos[i].second;
|
|
|
|
|
break;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
void HttpHead::AnalysisURIQuery(const std::string& query, HttpPairs& queryInfos)
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> queryList;
|
|
|
|
|
|
|
|
|
|
char* p = new char[query.size() + 1];
|
|
|
|
|
strcpy(p, query.c_str());
|
|
|
|
|
char* pStr = strtok(p, "&");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
queryList.push_back(pStr);
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
pStr = strtok(NULL, "&");
|
|
|
|
|
if (NULL == pStr)
|
|
|
|
|
break;
|
|
|
|
|
queryList.push_back(pStr);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
delete[] p;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
queryInfos.clear();
|
|
|
|
|
for (int i = 0; i < (int)queryList.size(); ++i)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
p = new char[queryList[i].size() + 1];
|
|
|
|
|
strcpy(p, queryList[i].c_str());
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::pair <std::string, std::string> pr;
|
|
|
|
|
pStr = strtok(p, "=");
|
2022-05-23 02:35:42 +00:00
|
|
|
|
if (NULL != pStr)
|
2022-05-23 10:29:23 +00:00
|
|
|
|
pr.first = AnalyURIString(pStr);
|
|
|
|
|
pStr = strtok(NULL, "=");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
pr.second = AnalyURIString(pStr);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
queryInfos.push_back(pr);
|
|
|
|
|
delete[] p;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
void HttpHead::AnalysisURI(const std::string& uri, std::string& path, HttpPairs& queryInfos, std::string& fragment)
|
|
|
|
|
{
|
|
|
|
|
size_t pathPos = uri.find('/');
|
|
|
|
|
size_t queryPos = uri.find('?');
|
|
|
|
|
size_t fragmentPos = uri.find('#');
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
path.clear();
|
|
|
|
|
if (std::string::npos != pathPos)
|
|
|
|
|
{
|
|
|
|
|
size_t count = std::string::npos;
|
|
|
|
|
if (queryPos != std::string::npos)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
assert(queryPos > pathPos);
|
|
|
|
|
count = queryPos - pathPos;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
else if (fragmentPos != std::string::npos)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
assert(fragmentPos > pathPos);
|
|
|
|
|
count = fragmentPos - pathPos;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
path = AnalyURIString(uri.substr(pathPos, count));
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
queryInfos.clear();
|
|
|
|
|
if (std::string::npos != queryPos)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
size_t count = std::string::npos;
|
|
|
|
|
if (fragmentPos != std::string::npos)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
assert(fragmentPos > queryPos);
|
|
|
|
|
count = fragmentPos - queryPos;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::string query = uri.substr(queryPos + 1, count - 1);
|
|
|
|
|
AnalysisURIQuery(query, queryInfos);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
fragment.clear();
|
|
|
|
|
if (std::string::npos != fragmentPos)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
fragment = AnalyURIString(uri.substr(fragmentPos + 1));
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
void HttpHead::AnalysisHead(const std::string& head, std::string& requestMethod, std::string& requestURIPath,
|
|
|
|
|
HttpPairs& requestURIQueryInfos, std::string& requestURIFragment, std::string& httpVersion, HttpPairs& headInfos)
|
|
|
|
|
{
|
|
|
|
|
requestMethod.clear();
|
|
|
|
|
requestURIPath.clear();
|
|
|
|
|
requestURIQueryInfos.clear();
|
|
|
|
|
requestURIFragment.clear();
|
|
|
|
|
httpVersion.clear();
|
|
|
|
|
headInfos.clear();
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> headList;
|
|
|
|
|
|
|
|
|
|
char* p = new char[head.size() + 1];
|
|
|
|
|
strcpy(p, head.c_str());
|
|
|
|
|
char* pStr = strtok(p, "\r\n");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
headList.push_back(pStr);
|
|
|
|
|
while (1)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
pStr = strtok(NULL, "\r\n");
|
|
|
|
|
if (NULL == pStr)
|
|
|
|
|
break;
|
|
|
|
|
headList.push_back(pStr);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
delete[] p;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (headList.size() < 1)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
return;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::string requestURI;
|
|
|
|
|
|
|
|
|
|
// 解析请求行
|
|
|
|
|
p = new char[headList[0].size() + 1];
|
|
|
|
|
strcpy(p, headList[0].c_str());
|
|
|
|
|
pStr = strtok(p, " ");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
requestMethod = pStr;
|
|
|
|
|
pStr = strtok(NULL, " ");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
requestURI = pStr;
|
|
|
|
|
pStr = strtok(NULL, " ");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
httpVersion = pStr;
|
|
|
|
|
delete[] p;
|
|
|
|
|
|
|
|
|
|
// 解析URI
|
|
|
|
|
AnalysisURI(requestURI, requestURIPath, requestURIQueryInfos, requestURIFragment);
|
|
|
|
|
|
|
|
|
|
// 解析请求头
|
|
|
|
|
for (int i = 1; i < (int)headList.size(); ++i)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
p = new char[headList[i].size() + 1];
|
|
|
|
|
strcpy(p, headList[i].c_str());
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
std::pair <std::string, std::string> pr;
|
|
|
|
|
pStr = strtok(p, ":");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
pr.first = pStr;
|
|
|
|
|
pStr = strtok(NULL, ":");
|
|
|
|
|
if (NULL != pStr)
|
|
|
|
|
pr.second = pStr;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
TrimString(pr.first);
|
|
|
|
|
TrimString(pr.second);
|
|
|
|
|
headInfos.push_back(pr);
|
|
|
|
|
|
|
|
|
|
delete[] p;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
/*判断ascii码是否是数字0-9*/
|
|
|
|
|
static bool asciiIsDigit(char c)
|
|
|
|
|
{
|
|
|
|
|
/*字符的ascii码&8 结果为0-127,则是数字*/
|
|
|
|
|
return asciiTableData[(unsigned char)c & (1 << 3)];
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
static int asciiDigitValue(char c)
|
|
|
|
|
{
|
|
|
|
|
if (asciiIsDigit(c))
|
|
|
|
|
return c - '0';
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
static int asciiXdigitValue(char c)
|
|
|
|
|
{
|
|
|
|
|
//printf("-->%c\n",c);
|
|
|
|
|
if (c >= 'A' && c <= 'F')
|
|
|
|
|
return c - 'A' + 10;//(A B C D E F)->(10 11 12 13 14 15)
|
|
|
|
|
if (c >= 'a' && c <= 'f')
|
|
|
|
|
return c - 'a' + 10;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
return asciiDigitValue(c);//('0'...'9')->(0...9)
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
static int unescapeCharacter(const char* scanner)
|
|
|
|
|
{
|
|
|
|
|
int first = asciiXdigitValue(scanner[0]);
|
|
|
|
|
if (first < 0)
|
|
|
|
|
return -1;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
int second = asciiXdigitValue(scanner[1]);
|
|
|
|
|
if (second < 0)
|
|
|
|
|
return -1;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
return (first << 4) | second; //== (first*16 | second) == (first*16 + second)
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
static char* unescapeUriString(const char* uriString, bool asciiEscape)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == uriString)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
int strLen = (int)strlen(uriString);
|
|
|
|
|
char* result = (char*)malloc(strLen + 1);//可推测解码后的长度<=原长度
|
|
|
|
|
char* out = result;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
const char* in, * end;
|
|
|
|
|
for (in = uriString, end = in + strLen; in < end; ++in)
|
|
|
|
|
{
|
|
|
|
|
int c = *in;
|
|
|
|
|
|
|
|
|
|
//遇到了'%'才去解析
|
|
|
|
|
if ('%' == c)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
if (in + 3 > end)
|
|
|
|
|
break;
|
|
|
|
|
//获取%后2个字符的解码值
|
|
|
|
|
c = unescapeCharacter(in + 1);
|
|
|
|
|
if (c <= 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (asciiEscape && c <= 0x7F)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
in += 2;//一般的格式为%后加两个ascii码字符
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
*out++ = c;//存储转义结果
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
*out = '\0';
|
|
|
|
|
|
|
|
|
|
if (in != end)
|
2022-05-23 02:35:42 +00:00
|
|
|
|
{
|
2022-05-23 10:29:23 +00:00
|
|
|
|
free(result);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2022-05-23 02:35:42 +00:00
|
|
|
|
|
2022-05-23 10:29:23 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string HttpHead::AnalyURIString(const std::string& str)
|
|
|
|
|
{
|
|
|
|
|
std::string ret;
|
|
|
|
|
char* decodeStr = unescapeUriString(str.c_str(), false);
|
|
|
|
|
if (NULL != decodeStr)
|
|
|
|
|
{
|
|
|
|
|
ret = decodeStr;
|
|
|
|
|
free(decodeStr);
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|
2022-05-23 10:29:23 +00:00
|
|
|
|
|
|
|
|
|
return ret;
|
2022-05-23 02:35:42 +00:00
|
|
|
|
}
|