/*=================================================================== Microsoft Denali Microsoft Confidential. Copyright 1996 Microsoft Corporation. All Rights Reserved. Component: Request, Response objects File: cookies.h Owner: DGottner This file contains the definiton of the CCookie class, which contains all of the state for an HTTP cookie ===================================================================*/ #include "denpre.h" #pragma hdrstop #include "asptlb.h" #include "dispatch.h" #include "hashing.h" #include "memcls.h" class CCookie; // Type for an object-destroyed callback typedef void (*PFNDESTROYED)(void); /* C C o o k i e P a i r * * Implements a name/value pair in the Cookie dictionary */ class CCookiePair : public CLinkElem { public: char *m_szValue; BOOL m_fDuplicate; // TRUE if we have a strdup'ed copy of m_pKey, m_szValue HRESULT Init(const char *szKey, const char *szValue, BOOL fDuplicate = FALSE); CCookiePair(); ~CCookiePair(); }; /* * C C o o k i e S u p p o r t E r r * * Implements ISupportErrorInfo for the CCookie class. The CSupportError class * is not adequate because it will only report a max of one interface which * supports error info. (We have two) */ class CCookieSupportErr : public ISupportErrorInfo { private: CCookie * m_pCookie; public: CCookieSupportErr(CCookie *pCookie); // IUnknown members that delegate to m_pCookie // STDMETHODIMP QueryInterface(const GUID &, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // ISupportErrorInfo members // STDMETHODIMP InterfaceSupportsErrorInfo(const GUID &); }; /* * C W r i t e C o o k i e * * Implements IWriteCookie which is the interface that Response.Cookies * returns. */ class CWriteCookie : public IWriteCookieImpl { private: CCookie * m_pCookie; public: CWriteCookie(CCookie *); // The Big Three // STDMETHODIMP QueryInterface(const IID &rIID, void **ppvObj); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // IWriteCookie implementation // STDMETHODIMP put_Item(VARIANT varKey, BSTR bstrValue); STDMETHODIMP put_Expires(DATE dtExpires); STDMETHODIMP put_Domain(BSTR bstrDomain); STDMETHODIMP put_Path(BSTR bstrPath); STDMETHODIMP put_Secure(VARIANT_BOOL fSecure); STDMETHODIMP get_HasKeys(VARIANT_BOOL *pfHasKeys); STDMETHODIMP get__NewEnum(IUnknown **ppEnum); }; /* * C R e a d C o o k i e * * Implements IReadCookie which is the interface that Request.Cookies * returns. */ class CReadCookie : public IReadCookieImpl { private: CCookie * m_pCookie; public: CReadCookie(CCookie *); // The Big Three // STDMETHODIMP QueryInterface(const IID &rIID, void **ppvObj); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // IReadCookie implementation // STDMETHODIMP get_Item(VARIANT i, VARIANT *pVariantReturn); STDMETHODIMP get_HasKeys(VARIANT_BOOL *pfHasKeys); STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn); STDMETHODIMP get_Count(int *pcValues); STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar); }; /* * C C o o k i e * * Implements CCookie, which is the object stored in the Request.Cookies * dictionary. */ class CCookie : public IUnknown { friend class CWriteCookie; friend class CReadCookie; friend class CCookieIterator; protected: ULONG m_cRefs; // reference count PFNDESTROYED m_pfnDestroy; // To call on closure private: CWriteCookie m_WriteCookieInterface; // implementation of IWriteCookie CReadCookie m_ReadCookieInterface; // implementation of IStringList CCookieSupportErr m_CookieSupportErrorInfo; // implementation of ISupportErrorInfo CIsapiReqInfo * m_pIReq; // pointer to CIsapiReqInfo for this cookie UINT m_lCodePage; // code page used for UNICODE conversions char * m_szValue; // value of cookie when not a dictionary CHashTableMBStr m_mpszValues; // dictionary of values for the cookie time_t m_tExpires; // date & time when cookie expires char * m_szDomain; // Cookie's domain CHAR * m_szPath; // Cookie's path (If UNICODE, stored as UTF-8) VARIANT_BOOL m_fSecure:1; // does cookie require security? BOOL m_fDirty:1; // does cookie need to be sent? BOOL m_fDuplicate:1; // does cookie contain dynamically allocated string? public: CCookie(CIsapiReqInfo *, UINT lCodePage, IUnknown * = NULL, PFNDESTROYED = NULL); ~CCookie(); HRESULT AddValue(char *szValue, BOOL fDuplicate = FALSE); HRESULT AddKeyAndValue(char *szKey, char *szValue, BOOL fDuplicate = FALSE); size_t GetHTTPCookieSize(); // return information on how big a buffer should be char * GetHTTPCookie(char *szBuffer); // return the cookie value HTTP encoded size_t GetCookieHeaderSize(const char *szName); // return buffer size needed for Set-Cookie header char *GetCookieHeader(const char *szName, char *szBuffer); // return cookie header BOOL IsDirty() { return m_fDirty; } HRESULT Init(); // The Big Three // STDMETHODIMP QueryInterface(const GUID &Iid, void **ppvObj); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // Cache on per-class basis ACACHE_INCLASS_DEFINITIONS() }; /* * C C o o k i e I t e r a t o r * * IEnumVariant implementation for Cookie dictionaries */ class CCookieIterator : public IEnumVARIANT { public: CCookieIterator(CCookie *pCookie); ~CCookieIterator(); // The Big Three STDMETHODIMP QueryInterface(const GUID &, void **); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // standard methods for iterators STDMETHODIMP Clone(IEnumVARIANT **ppEnumReturn); STDMETHODIMP Next(unsigned long cElements, VARIANT *rgVariant, unsigned long *pcElementsFetched); STDMETHODIMP Skip(unsigned long cElements); STDMETHODIMP Reset(); private: ULONG m_cRefs; // reference count CCookie *m_pCookie; // pointer to iteratee CCookiePair *m_pCurrent; // pointer to current item };