#include "stringex.h" #include "Defines.h" #include "Common.h" #include "Object.h" #include "String.h" #include "DataStruct.h" #include "NetUtil.h" #ifdef _WIN32 #include #else #include #include #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 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 dszUriDecode(strTemp.length() * 2); DecodeURIComponent(dszUriDecode.m_p, (char *)strTemp.c_str()); strSelf = dszUriDecode.m_p; }