Retrieving and Specifying Client Cookies
A Windows Media server can recognize HTTP and RTSP cookies from a client, and a cache proxy plug-in can modify them. Cookie modification can be used to stop recursive redirection. That is, you can create plug-ins that read the cookie, recognize that the client has already been redirected, and then do not request the same redirection.
When specifying a cookie value, you must indicate whether it is a persistent or a session-based cookie. A client remembers a session-based cookie only as long as the client is running. Also, each instance of the client has a unique cookie. Persistent cookies, on the other hand, remain after the client shuts down and are shared among clients. You can create a persistent cookie by appending an expiration date to the end of a cookie value. The date has the following format:
; expires = DDD dd-MMM-yyyy hh:mm:ss GMT
The following table identifies the values in the expiration date string.
Value |
Description |
---|---|
DDD |
Day of the week (Sun, Mon, Tue, Wed, Thu, Fri, or Sat) |
dd |
Day of the month (01-31) |
MMM |
Month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) |
yyyy |
Year (use all four digits) |
hh |
Hour (00-23) |
mm |
Minute (00-59) |
ss |
Second (00-59) |
GMT |
Greenwich Mean Time |
The following example code illustrates how to retrieve and specify a cookie. Because other plug-ins can specify cookie values, you must first retrieve the Set-Cookie value from the response context and concatenate it with your cookie before specifying the value. You must use semicolons to separate cookie values.
Note
Cookies are supported only by Windows Media Player 9 Series and later versions.
C++ Example
// Declarations.
HRESULT hr = S_OK;
IWMSHeaderLine *pHeaderLine = NULL;
IWMSContext *pRequestContext = NULL;
IWMSContext *pResponseContext = NULL;
CComBSTR bstrCookie;
CComBSTR bstrNewSetCookie;
CComBSTR bstrOrigSetCookie;
hr = pCommandCtx->GetCommandRequest( &pRequestContext );
if (FAILED(hr))
return(hr);
hr = pCommandCtx->GetCommandResponse( &pResponseContext );
if (FAILED(hr))
return(hr);
// Retrieve a pointer to the IWMSHeaderLine interface.
// Specify the cookie value of the request context.
hr = pRequestContext->GetAndQueryIUnknownValue(
L"Cookie",
WMS_CONTEXT_NO_NAME_HINT,
IID_IWMSHeaderLine,
(IUnknown**) &pHeaderLine,
0);
if (FAILED(hr))
return(hr);
// Retrieve the cookie.
hr = pHeaderLine->GetValue( &bstrCookie );
if (FAILED(hr))
return(hr);
// If this is an authorization plug-in, you can add a Set-Cookie header
// to the response. This cannot be done from an event plug-in, however,
// because the response may already have been sent by the time the code
// is executed.
// TODO: You can modify the cookie here.
// Retrieve the "Set-Cookie" value from the response context if it
// already exists. Do not overwrite the existing value.
hr = pResponseContext->GetStringValue( L"Set-Cookie",
WMS_CONTEXT_NO_NAME_HINT,
&bstrOrigSetCookie,
0 );
if( SUCCEEDED( hr ) )
{
// The response already contains a Set-Cookie header. Concatenate
// your cookie to the existing value.
bstrNewSetCookie.AssignBSTR( bstrOrigSetCookie );
if( !bstrNewSetCookie )
{
return( E_OUTOFMEMORY );
}
bstrNewSetCookie.Append( L", " );
if( !bstrNewSetCookie )
{
return( E_OUTOFMEMORY );
}
bstrNewSetCookie.AppendBSTR( bstrCookie );
if( !bstrNewSetCookie )
{
return( E_OUTOFMEMORY );
}
}
else
{
// The response does not already contain a Set-Cookie header.
hr = S_OK;
bstrNewSetCookie.AssignBSTR( bstrCookie );
if( !bstrNewSetCookie )
{
return( E_OUTOFMEMORY );
}
}
// Specify the new cookie.
hr = pResponseContext->SetStringValue( L"Set-Cookie",
WMS_CONTEXT_NO_NAME_HINT,
bstrNewSetCookie,
0 );
if (FAILED(hr))
return(hr);
// Release the pointers.