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.

See Also

Concepts

Custom Plug-in Basics

IWMSHeaderLine Interface

IWMSHeaderLine Object (C#)

IWMSHeaderLine Object (Visual Basic .NET)