📄 hxurl.cpp
字号:
::SaveStringToHeader(m_pProperties, PROPERTY_RESOURCE, m_pszResource);
::StrAllocCopy(pResource, m_pszResource);
pszTemp = ::HXFindChar(pResource, '?');
if (pszTemp)
{
*pszTemp = '\0';
}
pFullPath = new char[strlen(pResource) + 2];
SafeSprintf(pFullPath, strlen(pResource)+2, "/%s", pResource);
::SaveStringToHeader(m_pProperties, PROPERTY_FULLPATH, pFullPath);
pszTemp = ::HXReverseFindChar(pResource, '/');
if (pszTemp)
{
*pszTemp = '\0';
pPath = new char[strlen(pResource)+2];
SafeSprintf(pPath, strlen(pResource)+2, "/%s", pResource);
::SaveStringToHeader(m_pProperties, PROPERTY_PATH, pPath);
}
else
{
::SaveStringToHeader(m_pProperties, PROPERTY_PATH, "/");
}
HX_VECTOR_DELETE(pFullPath);
HX_VECTOR_DELETE(pPath);
HX_VECTOR_DELETE(pResource);
}
else if (m_unProtocol == rtspProtocol)
{
::SaveStringToHeader(m_pProperties, PROPERTY_RESOURCE, "\0");
::SaveStringToHeader(m_pProperties, PROPERTY_FULLPATH, "\0");
::SaveStringToHeader(m_pProperties, PROPERTY_PATH, "\0");
}
}
HX_RESULT
CHXURL::GeneratePrefixRootFragment(const char* pURL, CHXString& urlPrefix,
CHXString& urlRoot, char*& pURLFragment)
{
BOOL bHasHost = FALSE;
CHXURL urlObj(pURL);
IHXValues* pHeader = urlObj.GetProperties();
if(!pHeader)
{
return HXR_FAIL;
}
IHXBuffer* pBuffer = 0;
ULONG32 ulTemp;
if(HXR_OK == pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer))
{
urlPrefix = (const char*)pBuffer->GetBuffer();
urlPrefix += "://";
pBuffer->Release();
}
if(HXR_OK == pHeader->GetPropertyBuffer(PROPERTY_HOST, pBuffer))
{
urlPrefix += (const char*)pBuffer->GetBuffer();
pBuffer->Release();
bHasHost = TRUE;
}
if(HXR_OK == pHeader->GetPropertyULONG32(PROPERTY_PORT, ulTemp))
{
char szTemp[10]; /* Flawfinder: ignore */
SafeSprintf(szTemp, sizeof(szTemp), ":%d", (UINT16)ulTemp);
urlPrefix += szTemp;
}
// set root
urlRoot = urlPrefix;
if(bHasHost)
{
urlPrefix += "/";
}
if(HXR_OK == pHeader->GetPropertyBuffer(PROPERTY_RESOURCE, pBuffer))
{
const char* pResource = (const char*)pBuffer->GetBuffer();
const char cDelimiter1 = '/';
const char cDelimiter2 = '\\';
const char cOSDelimiter = OS_SEPARATOR_CHAR;
CHXString strURLWork = pResource;
char* pFirstChar = strURLWork.GetBuffer(strURLWork.GetLength());
char* pLastChar = NULL;
char* pOptions = NULL;
char* pFragment = NULL;
pOptions = strchr(pFirstChar, '?');
if (pOptions)
{
pLastChar = pOptions -1;
}
else
{
pLastChar = pFirstChar + strlen(pFirstChar)-1;
}
while ((pLastChar > pFirstChar) &&
(*pLastChar != cDelimiter1) && (*pLastChar != cDelimiter2) &&
(*pLastChar != cOSDelimiter))
{
pLastChar--;
}
// If we hit a delimiter before hitting the end, back up one character!
if(pLastChar > pFirstChar)
{
*(++pLastChar) = '\0';
urlPrefix += pFirstChar;
}
pBuffer->Release();
}
if(HXR_OK == pHeader->GetPropertyBuffer(PROPERTY_FRAGMENT, pBuffer))
{
const char* pFragment = (const char*)pBuffer->GetBuffer();
pURLFragment = new_string(pFragment);
pBuffer->Release();
}
HX_RELEASE(pHeader);
return HXR_OK;
}
BOOL
CHXURL::CompressURL(const char* pURL, char*& pCompressURL)
{
HX_ASSERT(pURL != NULL);
if (!pURL)
{
return FALSE;
}
pCompressURL = NULL;
BOOL bNeedToCompress = FALSE;
char separator1 = '\\';
char separator2 = '/';
char* pWalker = (char*) pURL;
while (*pWalker)
{
/*
* /./ || /.\ || \./ || \.\ ||
* /../ || /..\ || \../ || \..\
*/
if ((*pWalker == separator1 || *pWalker == separator2) &&
(*(pWalker+1) == '.') &&
((*(pWalker+2) == separator1 || *(pWalker+2) == separator2) ||
((*(pWalker+2) == '.') &&
(*(pWalker+3) == separator1 || *(pWalker+3) == separator2))))
{
// we need to commpress it
bNeedToCompress = TRUE;
break;
}
/* Do not process options in the URL (stuff after ?) */
if (*pWalker == '?')
{
break;
}
pWalker++;
}
if (!bNeedToCompress)
{
return FALSE;
}
UINT32 ulURLLength;
char* pTempURL;
char* pOptions;
ulURLLength = strlen(pURL) + 1;
pTempURL = new char[ulURLLength];
::strcpy(pTempURL, pURL); /* Flawfinder: ignore */
pOptions = strchr(pTempURL, '?');
/* We will only compress till before the options and then paste the options
* at the end
*/
if (pOptions)
{
*pOptions = '\0';
}
CHXSimpleList* pList;
char* pToken;
UINT16 uNumToBeDiscarded;
CHXSimpleList* pNewList;
pList = new CHXSimpleList;
pNewList = new CHXSimpleList;
uNumToBeDiscarded = 0;
pWalker = pToken = pTempURL;
while (*pWalker)
{
if (*pWalker == '/' || *pWalker == '\\')
{
*pWalker = '\0';
pList->AddTail(pToken);
pToken = pWalker+1;
}
pWalker++;
}
pList->AddTail(pToken);
while (pList->GetCount() > 0)
{
pToken = (char*) pList->RemoveTail();
if (::strcmp(pToken, ".") == 0)
{
/* ignore it */
}
else if (::strcmp(pToken, "..") == 0)
{
uNumToBeDiscarded++;
}
else if (uNumToBeDiscarded > 0)
{
uNumToBeDiscarded--;
}
else
{
pNewList->AddTail(pToken);
}
}
// /Valid content that starts with "../../" will trigger this, so turn it off
// unless someone wants to refine it:
#if defined(ALLOW_IRRITATING_ASSERTS_FOR_VALID_CONTENT)
// This will trigger with malformed urls with two additional ellipses(..)
HX_ASSERT(uNumToBeDiscarded == 0 && pNewList->GetCount() > 0);
#endif
if (uNumToBeDiscarded > 0 || pNewList->GetCount() == 0)
{
bNeedToCompress = FALSE;
goto exit;
}
pCompressURL = new char[ulURLLength];
*pCompressURL = '\0';
while (pNewList->GetCount() > 0)
{
pToken = (char*) pNewList->RemoveTail();
SafeStrCat(pCompressURL, (const char*) pToken, ulURLLength);
if (!pNewList->IsEmpty())
{
SafeStrCat(pCompressURL, "/", ulURLLength);
}
}
if (pOptions)
{
SafeStrCat(pCompressURL, "?", ulURLLength);
SafeStrCat(pCompressURL, (const char*) (pOptions+1), ulURLLength);
}
exit:
HX_VECTOR_DELETE(pTempURL);
HX_DELETE(pList);
HX_DELETE(pNewList);
return bNeedToCompress;
}
HX_RESULT
CHXURL::encodeURL(const char* pURL, CHXString& encodedURL)
{
HX_RESULT rc = HXR_OK;
char hexBuf[3] = {0}; /* Flawfinder: ignore */
char* pEncodeBuf = new char[(strlen(pURL)+1)*3]; // overkill
char* pEncodePtr = pEncodeBuf;
const char* pURLPtr = pURL;
while(*pURLPtr)
{
// according to the URL encoding spec. from
// http://www.isi.edu/in-notes/rfc1738.txt
if (*pURLPtr <= 0x1f ||
*pURLPtr >= 0x7f ||
HXIsEqual(pURLPtr, ' ') ||
// HXIsEqual(pURLPtr, '<') ||
// HXIsEqual(pURLPtr, '>') ||
// HXIsEqual(pURLPtr, '"') ||
// HXIsEqual(pURLPtr, '#') ||
// HXIsEqual(pURLPtr, '%') ||
HXIsEqual(pURLPtr, '{') ||
HXIsEqual(pURLPtr, '}') ||
HXIsEqual(pURLPtr, '|') ||
HXIsEqual(pURLPtr, '\\') ||
HXIsEqual(pURLPtr, '^') ||
HXIsEqual(pURLPtr, '~') ||
HXIsEqual(pURLPtr, '[') ||
HXIsEqual(pURLPtr, ']') ||
HXIsEqual(pURLPtr, '`') ||
HXIsEqual(pURLPtr, ',') ||
HXIsEqual(pURLPtr, ';'))
{
SafeSprintf(hexBuf, sizeof(hexBuf), "%02x", (UCHAR)*pURLPtr);
*pEncodePtr++ = '%';
*pEncodePtr++ = hexBuf[0];
*pEncodePtr++ = hexBuf[1];
if (HXIsLeadByte(*pURLPtr))
{
SafeSprintf(hexBuf, sizeof(hexBuf), "%02x", (UCHAR)*(pURLPtr+1));
*pEncodePtr++ = '%';
*pEncodePtr++ = hexBuf[0];
*pEncodePtr++ = hexBuf[1];
}
}
else
{
*pEncodePtr++ = *pURLPtr;
}
pURLPtr = HXGetNextChar(pURLPtr) ;
}
*pEncodePtr = '\0';
encodedURL = pEncodeBuf;
delete[] pEncodeBuf;
return rc;
}
HX_RESULT
CHXURL::decodeURL(const char* pURL, CHXString& decodedURL)
{
HX_RESULT rc = HXR_OK;
//XXXBAB - reimplement using CHXString::GetBuffer()/SetBuffer()
// to avoid memcpy
char* pDecodeBuf = new char[strlen(pURL)+1];
char* pDecodePtr = pDecodeBuf;
const char* pURLPtr = pURL;
while(*pURLPtr)
{
switch(*pURLPtr)
{
case '%':
{
char hexBuf[3]; /* Flawfinder: ignore */
if(pURLPtr[1] && // check for overbound condition
pURLPtr[2])
{
pURLPtr++; // walk past '%'
hexBuf[0] = *pURLPtr++;
hexBuf[1] = *pURLPtr;
hexBuf[2] = '\0';
*pDecodePtr++ = (char)strtol(hexBuf, NULL, 16);
}
}
break;
default:
{
*pDecodePtr++ = *pURLPtr;
}
break;
}
pURLPtr++;
}
*pDecodePtr = '\0';
decodedURL = pDecodeBuf;
delete[] pDecodeBuf;
return rc;
}
const char* CHXURL::FindURLSchemeEnd(const char *pszURL)
{
const char *pszTemp;
for (pszTemp = pszURL; *pszTemp; pszTemp++)
{
if(*pszTemp == ':')
{
return pszTemp;
}
else if(*pszTemp == '$' ||
*pszTemp == '#' ||
*pszTemp == '?' ||
*pszTemp == '/' ||
*pszTemp == '\\')
{
return NULL;
}
}
return NULL;
}
void
CHXURL::Unescape(char* s)
{
/*
* Remove URL hex escapes from s... done in place. The basic concept for
* this routine is borrowed from the WWW library HTUnEscape() routine.
*/
char* p = NULL;
BOOL bProcessingOptionsPastQuestionMark = FALSE;
for (p = s; *s != '\0'; ++s)
{
if ( (!bProcessingOptionsPastQuestionMark) && (*s == '%') )
{
if (*++s != '\0')
{
*p = Unhex( *s ) << 4;
}
if (*++s != '\0')
{
*p++ += Unhex( *s );
}
}
else
{
if (*s == '?')
{
bProcessingOptionsPastQuestionMark = TRUE;
}
*p++ = *s;
}
}
*p = '\0';
}
int
CHXURL::Unhex(char c)
{
return (c >= '0' && c <= '9' ? c - '0'
: c >= 'A' && c <= 'F' ? c - 'A' + 10
: c - 'a' + 10 );
}
void
CHXURL::TestCompressURL()
{
#ifdef _DEBUG
/* Brad made me do it...:( */
char* pTestCompressURL = NULL;
BOOL bTestCompress = FALSE;
CHXURL url("blah");
HX_VERIFY(url.CompressURL("http://blah.real.com/test/../foo.smi", pTestCompressURL) == TRUE &&
::strcmp(pTestCompressURL, "http://blah.real.com/foo.smi") == 0);
HX_VECTOR_DELETE(pTestCompressURL);
HX_VERIFY(url.CompressURL("http://blah.real.com/test/foo.smi?foo/../.", pTestCompressURL) == FALSE);
HX_VECTOR_DELETE(pTestCompressURL);
HX_VERIFY(url.CompressURL("http://blah.real.com/test/./foo.smi", pTestCompressURL) == TRUE &&
::strcmp(pTestCompressURL, "http://blah.real.com/test/foo.smi") == 0);
HX_VECTOR_DELETE(pTestCompressURL);
HX_VERIFY(url.CompressURL("http://blah.real.com/test/.blah/foo.smi", pTestCompressURL) == FALSE);
HX_VECTOR_DELETE(pTestCompressURL);
HX_VERIFY(url.CompressURL("http://blah.real.com/test/..foo.smi", pTestCompressURL) == FALSE);
HX_VECTOR_DELETE(pTestCompressURL);
HX_VERIFY(url.CompressURL("rtsp://blah.real.com/test/blah/../../foo.smi?end=./../blah", pTestCompressURL) == TRUE &&
::strcmp(pTestCompressURL, "rtsp://blah.real.com/foo.smi?end=./../blah") == 0);
HX_VECTOR_DELETE(pTestCompressURL);
#endif
}
IHXCommonClassFactory* CHXURL::CreateCCF()
{
return new CHXMiniCCF();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -