Files
smartservice_native/hdssd/huslib/NetUtil.cpp
T
2026-05-20 03:08:08 +09:00

593 lines
12 KiB
C++

#include "stringex.h"
#include "Defines.h"
#include "Common.h"
#include "Object.h"
#include "String.h"
#include "DataStruct.h"
#include "NetUtil.h"
#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
static struct {
const char * pszSecondLevelDomain;
int nBaseDot;
} SecondLevelDomain[] = {
{ ".com.br", 2 },
{ ".com.cn", 2 },
{ ".com.hk", 2 },
{ ".com.pl", 2 },
{ ".co.kr", 2 },
{ ".go.kr", 2 },
{ ".ac.kr", 2 },
{ ".ac.uk", 2 },
{ ".or.kr", 2 },
{ ".re.kr", 2 },
{ ".co.uk", 2 },
{ ".ac.at", 2 },
{ ".ac.id", 2 },
{ ".ac.jp", 2 },
{ ".ac.rs", 2 },
{ ".co.jp", 2 },
{ ".go.jp", 2 },
{ ".or.jp", 2 },
{ ".ed.gov", 2 },
{ ".gov.pl", 2 },
{ ".gc.ca", 2 },
{ ".edu.au", 2 },
{ ".edu.tw", 2 },
{ ".gov.tr", 2 },
{ ".gov.uk", 2 },
{ ".org.au", 2 },
{ ".org.in", 2 },
{ ".gda.pl", 2 },
{ ".org.au", 2 },
{ ".org.uk", 2 },
{ ".org.br", 2 },
{ ".org.tw", 2 },
{ ".com.sg", 2 },
{ ".edu.pl", 2 }
};
#define ARRAYCOUNT(array) ((unsigned)(sizeof(array)/sizeof(array[0])))
bool IsIpString(const char * psz)
{
int nCount = 0;
char * pOne = (char *)psz;
while (*pOne)
{
if (*pOne == '.')
nCount++;
else if (*pOne < 48 || *pOne > 57)
return false;
pOne++;
}
if (nCount != 3)
return false;
return true;
}
void ConvertHexStrIP(char * pszDst, unsigned long nS_Addr)
{
if (pszDst == NULL)
return;
#if 0
_snprintf(pszDst, 9, "%X", nS_Addr);
#else
// 4bit number to hex character
#define NUMTOHEXC(N) (((N) < 10) ? ((N) + '0') : ((N) - 10 + 'A'))
unsigned long nNum = nS_Addr;
int nFigure;
for(nFigure = 0; nNum != 0; nFigure++)
nNum = nNum >> 4;
for (int i = 0; i < nFigure; i++)
pszDst[i] = (char)NUMTOHEXC((nS_Addr >> ((nFigure - (i + 1)) * 4)) & 0xF);
pszDst[nFigure] = '\0';
#endif
}
void RestoreDotIP(char * pszDst, const char * pszSrc)
{
if (pszDst == NULL || pszSrc == NULL) return;
struct in_addr sin_addr;
sin_addr.s_addr = strtoul(pszSrc, NULL, 16);
//strcpy(pszDst, inet_ntoa(sin_addr));
strncpy(pszDst, inet_ntoa(sin_addr), 16);
}
bool IsInsideIp(const char * pszIpRange, const char * pszIp)
{
const char * pTild;
const char * pLastDot;
if ((pTild = strchr(pszIpRange, '~')))
{
if ((pLastDot = strrchr(pszIpRange, '.')) && pLastDot + 1 < pTild)
{
size_t nFrontSize = (size_t)(pLastDot - pszIpRange);
if (strncmp(pszIpRange, pszIp, nFrontSize) == 0)
{
char szStartRange[128], szEndRange[128];
StrNCpy(szStartRange, pLastDot + 1, pTild - pLastDot - 1);
strcpy(szEndRange, pTild + 1);
int nDotCount = 0;
const char * pOne = pszIpRange;
while (*pOne)
{
if (*pOne == '.')
nDotCount++;
pOne++;
}
pOne = pszIp;
while (*pOne)
{
if (*pOne == '.')
{
if (--nDotCount <= 0)
{
pOne++;
break;
}
}
pOne++;
}
int nCompare;
if ((pLastDot = strchr(pOne, '.')))
{
char szCompare[128];
StrNCpy(szCompare, pOne, pLastDot - pOne);
nCompare = atoi(szCompare);
}
else
{
nCompare = atoi(pOne);
}
if (nCompare >= atoi(szStartRange) && nCompare <= atoi(szEndRange))
return true;
}
}
}
return false;
}
bool IsDomainName(const char * pszName)
{
if (IsIpString(pszName) == true)
return false;
//if (IsFileLinkString(pszName))
// return false;
int nDotCount = 0;
char * pOne = (char *)pszName;
while (*pOne)
{
if (*pOne == '.')
nDotCount++;
pOne++;
}
if (nDotCount == 1)
return true;
int nBaseDot = 0;
for (unsigned i = 0; i < ARRAYCOUNT(SecondLevelDomain); i++)
{
if (strstr(pszName, SecondLevelDomain[i].pszSecondLevelDomain) != NULL)
{
nBaseDot = SecondLevelDomain[i].nBaseDot;
break;
}
}
if (nDotCount == nBaseDot)
return true;
return false;
}
bool IsHostName(const char * pszName)
{
const char * p = pszName;
for (; *p; p++)
{
if (!isalnum(*p) && *p != '.' && *p != '-' && *p != ':')
return false;
}
return true;
}
void ExtractDomainName(char * pszDest, const char * pszHostName)
{
if (IsIpString(pszHostName))
{
const char * pszTemp = strstr(pszHostName, ":");
if (pszTemp)
{
// ex) 192.168.0.1:8080 -> 192.168.0.1
size_t nFrontLength = pszTemp - pszHostName;
memcpy(pszDest, pszHostName, nFrontLength);
pszDest[nFrontLength] = '\0';
}
else
{
strcpy(pszDest, pszHostName); // ex) 192.168.0.1 -> 192.168.0.1
}
return;
}
int nDotCount = 0;
char * pOne = (char *)pszHostName;
while (*pOne)
{
if (*pOne == '.')
nDotCount++;
pOne++;
}
if (nDotCount <= 1)
{
strcpy(pszDest, pszHostName);
return;
}
int nBaseDot = 1;
for (unsigned i = 0; i < ARRAYCOUNT(SecondLevelDomain); i++)
{
if (strstr(pszHostName, SecondLevelDomain[i].pszSecondLevelDomain) != NULL)
{
nBaseDot = SecondLevelDomain[i].nBaseDot;
break;
}
}
pOne = (char *)pszHostName;
while (*pOne)
{
if (nDotCount == nBaseDot)
{
pszHostName = pOne;
break;
}
if (*pOne == '.')
nDotCount--;
pOne++;
}
#ifdef WITH_PORT
strcpy(pszDest, pszHostName); // ex) www.domain.com:8080 -> domain.com:8080
#else
const char * pOffset = strchr(pszHostName, ':');
if (pOffset)
{
// ex) www.domain.com:8080 -> domain.com
size_t nLength = pOffset - pszHostName;
strncpy(pszDest, pszHostName, nLength);
pszDest[nLength] = '\0';
}
else
{
strcpy(pszDest, pszHostName);
}
#endif
}
const char * GetDomainNamePtr(const char * pszHostName)
{
if (IsIpString(pszHostName))
return pszHostName;
int nDotCount = 0;
char * pOne = (char *)pszHostName;
while (*pOne)
{
if (*pOne == '.')
nDotCount++;
pOne++;
}
if (nDotCount <= 1)
return pszHostName;
int nBaseDot = 1;
for (unsigned i = 0; i < ARRAYCOUNT(SecondLevelDomain); i++)
{
if (strstr(pszHostName, SecondLevelDomain[i].pszSecondLevelDomain) != NULL)
{
nBaseDot = SecondLevelDomain[i].nBaseDot;
break;
}
}
pOne = (char *)pszHostName;
while (*pOne)
{
if (nDotCount == nBaseDot)
{
pszHostName = pOne;
break;
}
if (*pOne == '.')
nDotCount--;
pOne++;
}
return pszHostName;
}
const char * GetRequestUriPtr(const char * pszUrl)
{
int nCount = 0;
if (strnicmp(pszUrl, "http", 4) != 0 && pszUrl[0] != '/' && pszUrl[1] != '/')
nCount = 2;
for (const char * p = pszUrl; *p; p++)
{
if (*p == '/')
{
if (nCount++ == 2)
return p;
}
}
return pszUrl;
}
bool ExtractHostNameFromUrl(HString * pstrHostName, const char * pszUrl)
{
const char * pszRequestUri = GetRequestUriPtr(pszUrl);
if (strnicmp(pszUrl, "http://", 7) == 0)
pszUrl += 7;
else if (strnicmp(pszUrl, "https://", 8) == 0)
pszUrl += 8;
else if (strncmp(pszUrl, "//", 2) == 0)
pszUrl += 2;
if (pszUrl >= pszRequestUri)
return false;
pstrHostName->Assign(pszUrl, pszRequestUri - pszUrl);
return true;
}
const char * GetNextLevelHostName(const char * pszHostName, bool bIncludeDot)
{
const char * p = pszHostName;
while (*p)
{
if (*p == '.')
{
if (bIncludeDot)
return p;
return ++p;
}
p++;
}
return pszHostName;
}
int EncodeURIComponent(char * pszDst, const char * pszSrc)
{
int nLength = 0;
char * pOffset = pszDst;
while (*pszSrc)
{
if ((*pszSrc > 47 && *pszSrc < 57) ||
(*pszSrc > 64 && *pszSrc < 92) ||
(*pszSrc > 96 && *pszSrc < 123) ||
*pszSrc == '-' || *pszSrc == '.' || *pszSrc == '_')
{
*pOffset = *pszSrc;
}
else
{
sprintf(pOffset, "%%%02X", *pszSrc);
pOffset += 2;
nLength += 2;
}
pszSrc++;
pOffset++;
nLength++;
}
pszDst[nLength] = '\0';
return nLength;
}
int DecodeURIComponent(char * pszDst, char * pszSrc)
{
int i, nNum = 0, nLength = 0;
int nTemp = 0;
while (*pszSrc)
{
if (*pszSrc == '%')
{
nNum = 0;
nTemp = 0;
for (i = 0; i < 2; i++)
{
pszSrc++;
if (*(pszSrc) < ':')
{
nNum = *(pszSrc) - 48;
}
else if (*(pszSrc) > '@' && *(pszSrc) < '[')
{
nNum = (*(pszSrc) - 'A') + 10;
}
else
{
nNum = (*(pszSrc) - 'a') + 10;
}
if ((16*(1-i)))
nNum = (nNum*16);
nTemp += nNum;
}
pszDst[nLength] = nTemp;
nLength++;
}
else
{
pszDst[nLength] = *pszSrc;
nLength++;
}
pszSrc++;
}
pszDst[nLength] = '\0';
return nLength;
}
// base64 part
static const std::string strBase64Char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static inline bool IsBase64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
int EncodeBase64(std::string * pstrEncoded, const unsigned char * pszSrc, unsigned int nSrcLen)
{
int i = 0, j = 0;
unsigned char bufTemp1[3], bufTemp2[4];
*pstrEncoded = "";
while (nSrcLen--) {
bufTemp1[i++] = *(pszSrc++);
if (i == 3) {
bufTemp2[0] = (bufTemp1[0] & 0xfc) >> 2;
bufTemp2[1] = ((bufTemp1[0] & 0x03) << 4) + ((bufTemp1[1] & 0xf0) >> 4);
bufTemp2[2] = ((bufTemp1[1] & 0x0f) << 2) + ((bufTemp1[2] & 0xc0) >> 6);
bufTemp2[3] = bufTemp1[2] & 0x3f;
for(i = 0; (i <4) ; i++)
*pstrEncoded += strBase64Char[bufTemp2[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
bufTemp1[j] = '\0';
bufTemp2[0] = (bufTemp1[0] & 0xfc) >> 2;
bufTemp2[1] = ((bufTemp1[0] & 0x03) << 4) + ((bufTemp1[1] & 0xf0) >> 4);
bufTemp2[2] = ((bufTemp1[1] & 0x0f) << 2) + ((bufTemp1[2] & 0xc0) >> 6);
bufTemp2[3] = bufTemp1[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
*pstrEncoded += strBase64Char[bufTemp2[j]];
while((i++ < 3))
*pstrEncoded += '=';
}
return pstrEncoded->length();
}
int DecodeBase64(std::string * pstrDecoded, const unsigned char * pszSrc, unsigned int nSrcLen)
{
int i = 0, j = 0, pos = 0;
unsigned char bufTemp2[4], bufTemp1[3];
*pstrDecoded = "";
while (nSrcLen-- && ( pszSrc[pos] != '=') && IsBase64(pszSrc[pos])) {
bufTemp2[i++] = pszSrc[pos]; pos++;
if (i ==4) {
for (i = 0; i <4; i++)
bufTemp2[i] = strBase64Char.find(bufTemp2[i]);
bufTemp1[0] = (bufTemp2[0] << 2) + ((bufTemp2[1] & 0x30) >> 4);
bufTemp1[1] = ((bufTemp2[1] & 0xf) << 4) + ((bufTemp2[2] & 0x3c) >> 2);
bufTemp1[2] = ((bufTemp2[2] & 0x3) << 6) + bufTemp2[3];
for (i = 0; (i < 3); i++)
*pstrDecoded += bufTemp1[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
bufTemp2[j] = 0;
for (j = 0; j <4; j++)
bufTemp2[j] = strBase64Char.find(bufTemp2[j]);
bufTemp1[0] = (bufTemp2[0] << 2) + ((bufTemp2[1] & 0x30) >> 4);
bufTemp1[1] = ((bufTemp2[1] & 0xf) << 4) + ((bufTemp2[2] & 0x3c) >> 2);
bufTemp1[2] = ((bufTemp2[2] & 0x3) << 6) + bufTemp2[3];
for (j = 0; (j < i - 1); j++) *pstrDecoded += bufTemp1[j];
}
return pstrDecoded->length();
}
void DecodeUriBase64(HString & strDst, const HString & strSrc)
{
if (strSrc.GetLength() <= 0)
return;
std::string strTemp;
DecodeBase64(&strTemp, (const unsigned char *)strSrc.psz(), strSrc.GetLength());
HDynamicArray<char> dszUriDecode(strTemp.length() * 2);
DecodeURIComponent(dszUriDecode.m_p, (char *)strTemp.c_str());
strDst = dszUriDecode.m_p;
}
void DecodeUriBase64(HString & strSelf)
{
if (strSelf.GetLength() <= 0)
return;
std::string strTemp;
DecodeBase64(&strTemp, (const unsigned char *)strSelf.psz(), strSelf.GetLength());
HDynamicArray<char> dszUriDecode(strTemp.length() * 2);
DecodeURIComponent(dszUriDecode.m_p, (char *)strTemp.c_str());
strSelf = dszUriDecode.m_p;
}