📄 cookies.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
* Phil Dibowitz
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
#include "hxtypes.h"
#include "hlxclib/string.h"
// #include "hlxclib/stdio.h"
#include "safestring.h"
#ifdef _MACINTOSH
#ifdef _CARBON
#ifdef _MAC_MACHO
#include <sys/stat.h>
#else
#include <stat.h>
#endif
#else /* _CARBON */
#include <stat.mac.h>
#endif /* _CARBON */
#else /* _MACINTOSH */
#include "hlxclib/sys/types.h"
#include "hlxclib/sys/stat.h"
#endif /* _MACINTOSH */
#include "hlxclib/time.h"
#if defined(_AIX)
#include <ctype.h>
#endif
#ifdef _WINDOWS
#include "hlxclib/windows.h"
#include <wininet.h>
#include "hlxclib/io.h"
#endif /* _WINDOWS */
#if defined(_CARBON) || defined(_MAC_MACHO)
#include "hxver.h" // for HXVER_SDK_PRODUCT
#endif
#ifdef _CARBON
#include "cfwrappers.h"
#endif
#include "hxresult.h"
#include "hxslist.h"
#include "chxpckts.h"
#include "hxstrutl.h"
#include "dbcs.h"
#include "dllpath.h"
#include "hxprefs.h"
#include "hxthread.h"
#include "ihxcookies.h"
#include "cookhlpr.h"
#include "ihxcookies2.h"
#include "hxdate.h"
#include "cookies.h"
#include "md5.h"
#include "filespecutils.h"
#ifdef _UNIX
#include <sys/types.h>
#include <sys/stat.h>
#endif
#if defined (_UNIX) && !defined(_SUN) && !defined(_HPUX) && !defined(_IRIX) && !defined(_OSF1)
#include <sys/file.h>
#endif /* UNIX */
#define RM_COOKIE_CAPTION "# Helix Cookie File\n# http://www.netscape.com/newsref/std/cookie_spec.html\n# This is a generated file! Do not edit.\n\n"
#ifdef _UNIX
# define RM_COOKIE_FILE_NAME "Cookies_6_0"
#else
# define RM_COOKIE_FILE_NAME "cookies.txt"
#endif
/* We should really define it in a common header file */
#if defined (_WINDOWS ) || defined (WIN32) || defined(_SYMBIAN)
#define OS_SEPARATOR_CHAR '\\'
#define OS_SEPARATOR_STRING "\\"
#elif defined (_UNIX) || defined (_OPENWAVE)
#define OS_SEPARATOR_CHAR '/'
#define OS_SEPARATOR_STRING "/"
#elif defined (_MACINTOSH)
#define OS_SEPARATOR_CHAR ':'
#define OS_SEPARATOR_STRING ":"
#endif /* defined (_WINDOWS ) || defined (WIN32) */
HXCookies::HXCookies(IUnknown* pContext, BOOL bMemoryOnly)
: m_lRefCount(0)
, m_bSaveCookies(FALSE)
, m_bMemoryOnly(bMemoryOnly)
, m_pNSCookiesPath(NULL)
, m_pNSCookies(NULL)
, m_pRMCookiesPath(NULL)
, m_pRMCookies(NULL)
, m_pCookiesHelper(NULL)
, m_pPreferences(NULL)
, m_bInitialized(FALSE)
, m_lastModification(0)
, m_pContext(NULL)
#ifdef _WINDOWS
, m_hLib(NULL)
, m_pLock(NULL)
, _pInternetSetCookie(NULL)
, _pInternetGetCookie(NULL)
#elif _UNIX
, m_fileID(0)
#endif /* _WINDOWS */
{
if (pContext)
{
m_pContext = pContext;
m_pContext->AddRef();
}
}
HXCookies::~HXCookies()
{
Close();
}
STDMETHODIMP
HXCookies::QueryInterface(REFIID riid, void**ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), this },
{ GET_IIDHANDLE(IID_IHXCookies), (IHXCookies*) this },
{ GET_IIDHANDLE(IID_IHXCookies2), (IHXCookies2*) this }
};
if (QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj) == HXR_OK)
{
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXCookiesHelper) && m_pCookiesHelper)
{
return m_pCookiesHelper->QueryInterface(riid, ppvObj);
}
*ppvObj = NULL;
return HXR_NOINTERFACE;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32)
HXCookies::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32)
HXCookies::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
HX_RESULT
HXCookies::Initialize(void)
{
HX_RESULT hr = HXR_OK;
if (!m_pContext || !IsCookieEnabled())
{
hr = HXR_FAILED;
goto cleanup;
}
m_pContext->QueryInterface(IID_IHXCookiesHelper, (void**) &m_pCookiesHelper);
if (!m_pCookiesHelper)
{
HXCookiesHelper* pHelper = new HXCookiesHelper();
if (pHelper)
{
pHelper->QueryInterface(IID_IHXCookiesHelper, (void**) &m_pCookiesHelper);
}
}
if (!m_bMemoryOnly)
{
#ifdef _WINDOWS
if (m_hLib = LoadLibrary(OS_STRING("wininet.dll")))
{
_pInternetSetCookie = (INTERNETSETCOOKIE)GetProcAddress(m_hLib, OS_STRING("InternetSetCookieA"));
_pInternetGetCookie = (INTERNETGETCOOKIE)GetProcAddress(m_hLib, OS_STRING("InternetGetCookieA"));
}
#endif /* _WINDOWS */
PrepareCookiesPath();
if (m_pNSCookiesPath)
{
OpenCookies(m_pNSCookiesPath, FALSE, m_pNSCookies);
}
if (m_pRMCookiesPath)
{
OpenCookies(m_pRMCookiesPath, TRUE, m_pRMCookies);
}
}
m_bInitialized = TRUE;
cleanup:
return hr;
}
void
HXCookies::Close(void)
{
if (m_bSaveCookies && !m_bMemoryOnly)
{
SaveCookies();
}
ResetCookies(m_pNSCookies);
ResetCookies(m_pRMCookies);
HX_DELETE(m_pNSCookies);
HX_DELETE(m_pRMCookies);
HX_VECTOR_DELETE(m_pNSCookiesPath);
HX_VECTOR_DELETE(m_pRMCookiesPath);
HX_RELEASE(m_pPreferences);
HX_RELEASE(m_pCookiesHelper);
HX_RELEASE(m_pContext);
m_bInitialized = FALSE;
#ifdef _WINDOWS
if (m_hLib)
{
FreeLibrary(m_hLib);
m_hLib = NULL;
}
HX_DELETE(m_pLock);
#endif /* _WINDOWS */
}
STDMETHODIMP
HXCookies::SetCookies(const char* pHost, const char* pPath, IHXBuffer* pCookies)
{
HX_RESULT hr = HXR_OK;
int host_length = 0;
int path_length = 0;
int domain_length = 0;
char* pURL = NULL;
char* path_from_header = NULL;
char* domain_from_header = NULL;
char* name_from_header = NULL;
char* cookie_from_header = NULL;
char* dot = NULL;
char* slash = NULL;
BOOL bIsDomain = FALSE;
time_t expires=0;
IHXBuffer* pBuffer = NULL;
IHXValues* pValues = NULL;
CookieStruct* pNewCookie = NULL;
if (!IsCookieEnabled())
{
goto cleanup;
}
if (!m_bInitialized)
{
hr = Initialize();
if (HXR_OK != hr)
{
goto cleanup;
}
}
if (!m_pCookiesHelper || !pCookies || !pHost)
{
hr = HXR_FAILED;
goto cleanup;
}
if (HXR_OK != m_pCookiesHelper->Pack(pCookies, pValues))
{
hr = HXR_FAILED;
goto cleanup;
}
if (HXR_OK == pValues->GetPropertyBuffer("path", pBuffer) && pBuffer)
{
::StrAllocCopy(path_from_header, (char*)pBuffer->GetBuffer());
}
HX_RELEASE(pBuffer);
if (HXR_OK == pValues->GetPropertyBuffer("domain", pBuffer) && pBuffer)
{
// verify that this host has the authority to set for
// this domain. We do this by making sure that the
// host is in the domain
// We also require that a domain have at least two
// periods to prevent domains of the form ".com"
// and ".edu"
//
// also make sure that there is more stuff after
// the second dot to prevent ".com."
::StrAllocCopy(domain_from_header, (char*)pBuffer->GetBuffer());
dot = strchr(domain_from_header, '.');
if(dot)
{
dot = strchr(dot+1, '.');
}
if(!dot || *(dot+1) == '\0')
{
// did not pass two dot test. FAIL
hr = HXR_FAILED;
goto cleanup;
}
domain_length = strlen(domain_from_header);
host_length = strlen(pHost);
// check to see if the host is in the domain
if(domain_length > host_length ||
strcasecmp(domain_from_header, &pHost[host_length-domain_length]))
{
hr = HXR_FAILED;
goto cleanup;
}
bIsDomain = TRUE;
}
HX_RELEASE(pBuffer);
if (HXR_OK == pValues->GetPropertyBuffer("name", pBuffer) && pBuffer)
{
::StrAllocCopy(name_from_header, (char*)pBuffer->GetBuffer());
}
HX_RELEASE(pBuffer);
if (HXR_OK == pValues->GetPropertyBuffer("value", pBuffer) && pBuffer)
{
::StrAllocCopy(cookie_from_header, (char*)pBuffer->GetBuffer());
}
HX_RELEASE(pBuffer);
if (HXR_OK == pValues->GetPropertyBuffer("expires", pBuffer) && pBuffer)
{
expires = ::ParseDate((char*)pBuffer->GetBuffer());
}
HX_RELEASE(pBuffer);
if(!path_from_header && pPath)
{
// strip down everything after the last slash
// to get the path.
CHXString strPath = pPath;
INT32 nIndex = strPath.ReverseFind('/');
if (nIndex != -1)
{
strPath = strPath.Left(nIndex + 1);
}
::StrAllocCopy(path_from_header, (char*) (const char*) strPath);
}
if(!domain_from_header && pHost)
{
::StrAllocCopy(domain_from_header, (char*)pHost);
}
m_bSaveCookies = TRUE;
// We have decided we are going to insert a cookie into the list
// Get the cookie lock so that we can munge on the list
pNewCookie = CheckForPrevCookie(path_from_header,
domain_from_header,
name_from_header);
if(pNewCookie)
{
HX_DELETE(pNewCookie->pCookieValue);
HX_DELETE(pNewCookie->pCookieName);
HX_DELETE(pNewCookie->pPath);
HX_DELETE(pNewCookie->pHost);
pNewCookie->pCookieValue = new CHXString(cookie_from_header);
pNewCookie->pCookieName = new CHXString(name_from_header);
pNewCookie->pPath = new CHXString(path_from_header);
pNewCookie->pHost = new CHXString(domain_from_header);
pNewCookie->expires = expires;
pNewCookie->bIsDomain = bIsDomain;
pNewCookie->bMemoryOnly = TRUE;
}
else
{
pNewCookie = new CookieStruct;
// copy
pNewCookie->pCookieValue = new CHXString(cookie_from_header);
pNewCookie->pCookieName = new CHXString(name_from_header);
pNewCookie->pPath = new CHXString(path_from_header);
pNewCookie->pHost = new CHXString(domain_from_header);
pNewCookie->expires = expires;
pNewCookie->bIsDomain = bIsDomain;
pNewCookie->bMemoryOnly = TRUE;
if (!m_pRMCookies)
{
m_pRMCookies = new CHXSimpleList();
}
hr = AddCookie(pNewCookie, m_pRMCookies);
}
#ifdef _WINDOWS
if (!m_bMemoryOnly)
{
if (!_pInternetSetCookie)
{
goto cleanup;
}
host_length = strlen(pHost);
if (pPath)
{
path_length = strlen(pPath);
}
pURL = new char[host_length + path_length + 8];
sprintf(pURL, "http://%s%s", pHost, pPath); /* Flawfinder: ignore */
_pInternetSetCookie(pURL, NULL, (const char*)pCookies->GetBuffer());
}
#endif /* _WINDOWS */
cleanup:
HX_RELEASE(pBuffer);
HX_RELEASE(pValues);
HX_VECTOR_DELETE(pURL);
HX_VECTOR_DELETE(path_from_header);
HX_VECTOR_DELETE(domain_from_header);
HX_VECTOR_DELETE(name_from_header);
HX_VECTOR_DELETE(cookie_from_header);
return hr;
}
STDMETHODIMP
HXCookies::GetCookies(const char* pHost, const char* pPath, REF(IHXBuffer*) pCookies)
{
IHXBuffer* pPlayerCookies = NULL;
HX_RESULT res = GetCookiesInternal(pHost, pPath, pCookies, pPlayerCookies);
HX_RELEASE(pPlayerCookies);
return res;
}
STDMETHODIMP HXCookies::GetCookies(const char* pHost,
const char* pPath,
REF(IHXBuffer*) pCookies,
REF(IHXBuffer*) pPlayerCookies)
{
return GetCookiesInternal(pHost, pPath, pCookies, pPlayerCookies);
}
#if defined(_CARBON) || defined(_MAC_MACH)
#define REPORT_COOKIES 1
#endif
HX_RESULT HXCookies::GetCookiesInternal(const char* pHost,
const char* pPath,
REF(IHXBuffer*) pCookies,
REF(IHXBuffer*) pPlayerCookies)
{
HX_RESULT hr = HXR_OK;
char* cp = NULL;
char* pComma = NULL;
char* pEqualSign = NULL;
char* pData = NULL;
char* pURL = NULL;
int l = 0;
int host_length = 0;
int path_length = 0;
BOOL bAdded = FALSE;
UINT32 dwSize = 0;
time_t cur_time = time(NULL);
CookieStruct* pTempCookie = NULL;
CookieStruct* pNewCookie = NULL;
CHXSimpleList* pCookiesFound1 = NULL;
CHXSimpleList* pCookiesFound2 = NULL;
CHXSimpleList* pCookiesList = NULL;
IHXValues* pValues = NULL;
CHXSimpleList::Iterator i;
CHXString cHostCopy;
INT32 lColon;
BOOL bIsPlayerCookieList = FALSE;
CHXString strPlayerCookies;
#ifdef REPORT_COOKIES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -