[FASTCGI] Cookie processing in Fast CGI

Martin Chapman chapmanm at pixia.com
Wed Dec 9 16:08:59 EST 2009


Tom,

I made a mistake in my last email.  The first function should be as follows:

STDMETHODIMP CRequest::ParseCookieString(BSTR sCookieString)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	HRESULT hr = S_OK;

	CString sSub;
	_bstr_t bstrCS(sCookieString);
	CString sCookieStringTemp = (TCHAR*) bstrCS;
    int	nCount = 0;
	BOOL bInCookie = FALSE;
	CComPtr< ICookie> spCookie;
	hr = spCookie.CoCreateInstance(CLSID_Cookie);
	if (FAILED(hr)) return hr;
    
	while (AfxExtractSubString(sSub, sCookieStringTemp, nCount++, ';'))
	{
		int nPos = sSub.Find('=');
		if (nPos != -1)
		{
			CString sName = sSub.Left(nPos);
			sName.TrimLeft();
			sName.TrimRight();

			CString sValue = sSub.Mid(nPos + 1);

			if (sName.IsEmpty())
				continue;

			// check for $Version
			if (sName.CompareNoCase("$Version") == 0)
			{
				// ignore for now...
				continue;
			}

			if (sValue.IsEmpty())
				continue;

			if (sName[0] == '$')
			{
				// invalid cookie string
				if (!bInCookie)
					return E_FAIL; 
				else
				{
					// add attribute to current cookie
					sName.TrimLeft('$');
					hr =
spCookie->AddAttribute(_bstr_t(sName.GetBuffer()),
_bstr_t(sValue.GetBuffer()));
					if (FAILED(hr)) return hr;
				}
			}
			else
			{
				if (!bInCookie)
				{
					bInCookie = TRUE;
					hr =
spCookie->put_Name(_bstr_t(sName.GetBuffer()));
					if (FAILED(hr)) return hr;
					hr =
spCookie->ParseValue(_bstr_t(sValue.GetBuffer()));
					if (FAILED(hr)) return hr;
				}
				else
				{
					// add previous cookie
					_bstr_t sPreviousName;
					hr =
spCookie->get_Name(sPreviousName.GetAddress());
					if (FAILED(hr)) return hr;

					long nIndexOf = 0L;
					hr = m_spCookies->Add(spCookie,
&nIndexOf);
					if (FAILED(hr)) return hr;

					// empty current cookie and start
over
					hr = spCookie->Empty();
					if (FAILED(hr)) return hr;
					hr =
spCookie->put_Name(_bstr_t(sName.GetBuffer()));
					if (FAILED(hr)) return hr;
					hr =
spCookie->ParseValue(_bstr_t(sValue.GetBuffer()));
					if (FAILED(hr)) return hr;
				}
			}
		}
	}

	VARIANT_BOOL bIsEmpty = VARIANT_FALSE;
	hr = spCookie->IsEmpty(&bIsEmpty);
	if (FAILED(hr)) return hr;

	if (bIsEmpty == VARIANT_FALSE)
	{
		_bstr_t sName;
		hr = spCookie->get_Name(sName.GetAddress());
		if (FAILED(hr)) return hr;

		long nIndexOf = 0L;
		hr = m_spCookies->Add(spCookie, &nIndexOf);
		if (FAILED(hr)) return hr;
	} 

	return S_OK;
}

-----Original Message-----
From: fastcgi-developers-bounces+chapmanm=pixia.com at mailman.fastcgi.com
[mailto:fastcgi-developers-bounces+chapmanm=pixia.com at mailman.fastcgi.com]
On Behalf Of Martin Chapman
Sent: Wednesday, December 09, 2009 2:02 PM
To: 'Tom Bowden'; 'FastCGI Developers'
Subject: Re: [FASTCGI] Cookie processing in Fast CGI

Tom,

It's a little ugly because it's COM and if you convert it to FastCGI it
would be cool if you posted it back for the rest of us if you can.  The
entire COM implementation is attached.

General Gist:

1. Get the cookie from the env vars.  Should be called HTTP_COOKIE.

2. Use a method like the one below to parse the cookie value.

STDMETHODIMP CCookie::ParseValue(BSTR sCookie)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	_bstr_t bstrCookie(sCookie);
	if (bstrCookie.length() == 0)
		return E_INVALIDARG;

	CString strCookie = (TCHAR*) bstrCookie;
	LPCSTR pEnd = strCookie;
	LPCSTR pStart = strCookie;
	CString name, value;

	while (*pEnd != '\0')
	{
		while (*pEnd && *pEnd != '=' && *pEnd != '&')
			pEnd++;

		if (*pEnd == '\0' || *pEnd == '&')
		{
			if (pEnd > pStart)
			{
				CopyToCString(value, pStart, pEnd);
			}
			put_Value(_bstr_t(value.GetBuffer()));
			if (*pEnd == '&')
			{
				pEnd++;
				pStart = pEnd;
				continue;
			}
			return S_OK;
		}
		else if (*pEnd == '=' )
		{
			if (pEnd > pStart)
			{
				CopyToCString(name, pStart, pEnd);
			}
			else
			{
				pEnd++;
				pStart = pEnd;
				break;
			}

			pEnd++;
			pStart = pEnd;
			while (*pEnd && *pEnd != '&' && *pEnd != '=')
				pEnd++;
			if (pEnd > pStart)
				CopyToCString(value, pStart, pEnd);

			AddValue(_bstr_t(name.GetBuffer()),
_bstr_t(value.GetBuffer()));
			if (*pEnd != '\0')
				pEnd++;
			
			pStart = pEnd;
		}
	}
	
	return S_OK;
}

3. The following func parses a single cookie value and is used in the func
above.

STDMETHODIMP CCookie::ParseValue(BSTR sCookie)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	_bstr_t bstrCookie(sCookie);
	if (bstrCookie.length() == 0)
		return E_INVALIDARG;

	CString strCookie = (TCHAR*) bstrCookie;
	LPCSTR pEnd = strCookie;
	LPCSTR pStart = strCookie;
	CString name, value;

	while (*pEnd != '\0')
	{
		while (*pEnd && *pEnd != '=' && *pEnd != '&')
			pEnd++;

		if (*pEnd == '\0' || *pEnd == '&')
		{
			if (pEnd > pStart)
			{
				CopyToCString(value, pStart, pEnd);
			}
			put_Value(_bstr_t(value.GetBuffer()));
			if (*pEnd == '&')
			{
				pEnd++;
				pStart = pEnd;
				continue;
			}
			return S_OK;
		}
		else 
		if (*pEnd == '=' )
		{
			if (pEnd > pStart)
			{
				CopyToCString(name, pStart, pEnd);
			}
			else
			{
				pEnd++;
				pStart = pEnd;
				break;
			}

			pEnd++;
			pStart = pEnd;
			while (*pEnd && *pEnd != '&' && *pEnd != '=')
				pEnd++;
			if (pEnd > pStart)
				CopyToCString(value, pStart, pEnd);

			AddValue(_bstr_t(name.GetBuffer()),
_bstr_t(value.GetBuffer()));
			if (*pEnd != '\0')
				pEnd++;
			
			pStart = pEnd;
		}
	}
	
	return S_OK;
}


-----Original Message-----
From: fastcgi-developers-bounces+chapmanm=pixia.com at mailman.fastcgi.com
[mailto:fastcgi-developers-bounces+chapmanm=pixia.com at mailman.fastcgi.com]
On Behalf Of Tom Bowden
Sent: Wednesday, December 09, 2009 1:18 PM
To: FastCGI Developers
Subject: [FASTCGI] Cookie processing in Fast CGI

Is there a thread somewhere that talks about parsing cookies - or, is  
this something that I have to treat like any other header parsing task.

Tom

_______________________________________________
FastCGI-developers mailing list
FastCGI-developers at mailman.fastcgi.com
http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers



More information about the FastCGI-developers mailing list