QTSS_Error FilterRequest(QTSS_Filter_Params* inParams)
{
    UInt8 sParamStopMask[] =
    {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-9      //stop unless a '\t', ' ', or '&'
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-19  
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
        0, 0, 0, 0, 0, 0, 0, 0, 1, 0, //30-39   
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-49
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-59
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //60-69
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //90-99
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
        0, 0, 0, 0, 0, 1             //250-255
    };


    //check to see if we should handle this request. Invokation is triggered
    //by a "GET /" request
    
    QTSS_RTSPRequestObject theRequest = inParams->inRTSPRequest;
    
    StrPtrLen theFullRequest;
    (void)QTSS_GetValuePtr(theRequest, qtssRTSPReqFullRequest, 0, (void**)&theFullRequest.Ptr, &theFullRequest.Len);

    StringParser fullRequest(&theFullRequest);
    
    StrPtrLen   strPtr;
    StrPtrLen   paramName;
    StrPtrLen   fieldsList;
    
    fullRequest.ConsumeWord(&strPtr);
    if ( strPtr.Equal(StrPtrLen("GET")) )   //it's a "Get" request
    {
        fullRequest.ConsumeWhitespace();
        if ( fullRequest.Expect('/') )
        {
            UInt32  refreshInterval = 0;
            Bool16  displayHelp = false;
            
            
            OSCharArrayDeleter theWebStatsURL(GetPrefAsString(sPrefs, sDefaultURLPrefName));
            StrPtrLen theWebStatsURLPtr(theWebStatsURL.GetObject());
            
            // If there isn't any web stats URL, we can just return at this point
            if (theWebStatsURLPtr.Len == 0)
                return QTSS_NoErr;
                
            fullRequest.ConsumeUntil(&strPtr, StringParser::sEOLWhitespaceQueryMask);
            if ( strPtr.Len != 0 && strPtr.Equal(theWebStatsURLPtr) )   //it's a "stats" request
            {
                if ( fullRequest.Expect('?') )
                {
                    do {
                        fullRequest.ConsumeWord(&paramName);
                        
                        if( paramName.Len != 0)
                        {
                            
                            if ( paramName.Equal(StrPtrLen("refresh",strlen("refresh"))) )
                            {
                                if (fullRequest.Expect('='))
                                    refreshInterval  = fullRequest.ConsumeInteger(NULL);
                            }
                            else if ( paramName.Equal(StrPtrLen("help",strlen("help"))) )
                            {
                                displayHelp = true;
                            }
                            else if ( paramName.Equal(StrPtrLen("fields",strlen("fields"))) )
                            {
                                if (fullRequest.Expect('='))
                                    fullRequest.ConsumeUntil(&fieldsList, (UInt8*)sParamStopMask);
                                
                            }
                        }
                    } while ( paramName.Len != 0 && fullRequest.Expect('&') );
                }
                
                // Before sending a response, set keep alive to off for this connection
                (void)QTSS_SetValue(theRequest, qtssRTSPReqRespKeepAlive, 0, &sFalse, sizeof(sFalse));
                SendStats(inParams->inRTSPRequest, refreshInterval, displayHelp, (fieldsList.Len != 0) ? &fieldsList : NULL);
            }
        }
    }
    return QTSS_NoErr;
}
QTSS_Error FilterRequest(QTSS_Filter_Params* inParams)
{
    if (NULL == inParams || NULL == inParams->inRTSPSession || NULL == inParams->inRTSPRequest)
    {   Assert(0);
        return QTSS_NoErr;
    }

    OSMutexLocker locker(sAdminMutex);
    //check to see if we should handle this request. Invokation is triggered
    //by a "GET /" request
    
    QTSS_Error err = QTSS_NoErr;
    QTSS_RTSPRequestObject theRequest = inParams->inRTSPRequest;

    UInt32 paramLen = sizeof(sSessID);
    err = QTSS_GetValue(inParams->inRTSPSession, qtssRTSPSesID, 0, (void*)&sSessID, &paramLen);     
    if (err != QTSS_NoErr) 
        return QTSS_NoErr;

    StrPtrLen theFullRequest;
    err = QTSS_GetValuePtr(theRequest, qtssRTSPReqFullRequest, 0, (void**)&theFullRequest.Ptr, &theFullRequest.Len);
    if (err != QTSS_NoErr) 
        return QTSS_NoErr;
        
    
    StringParser fullRequest(&theFullRequest);
        
    if ( !IsAdminRequest(&fullRequest) ) 
        return QTSS_NoErr;
        
    if ( !AcceptSession(inParams->inRTSPSession) )
    {   (void)QTSS_Write(inParams->inRTSPRequest, sPermissionDeniedHeader, ::strlen(sPermissionDeniedHeader), NULL, 0);     
        (void)QTSS_Write(inParams->inRTSPRequest, sHTMLBody, ::strlen(sHTMLBody), NULL, 0);
        KeepSession(theRequest,false);
        return QTSS_NoErr;
    }
    
    if(!GetRequestAuthenticatedState(inParams)) // must authenticate before handling
    {
        if(QTSS_IsGlobalLocked()) // must NOT be global locked
            return QTSS_RequestFailed;
            
        if (!IsAuthentic(inParams,&fullRequest)) 
        {  
            (void)QTSS_Write(inParams->inRTSPRequest, sUnauthorizedResponseHeader, ::strlen(sUnauthorizedResponseHeader), NULL, 0);     
            (void)QTSS_Write(inParams->inRTSPRequest, sHTMLBody, ::strlen(sHTMLBody), NULL, 0);
            KeepSession(theRequest,false);
            return QTSS_NoErr;
        }
        
    }
    
    if (GetRequestFlushState(inParams)) 
    {   StillFlushing(inParams,true);
        return QTSS_NoErr;
    }
        
    if (!QTSS_IsGlobalLocked())
    {       
        if (InWaitInterval(inParams)) 
            return QTSS_NoErr; 

        //qtss_printf("New Request Wait for GlobalLock session=%"_U32BITARG_"\n",sSessID);
        (void)QTSS_RequestGlobalLock();
        KeepSession(theRequest,true);
        return QTSS_NoErr; 
    }
    
    //qtss_printf("Handle request session=%"_U32BITARG_"\n",sSessID);
    APITests_DEBUG();
    
    if (sQueryPtr != NULL) 
    {   delete sQueryPtr;
        sQueryPtr = NULL;   
    }
    sQueryPtr = NEW QueryURI(&theFullRequest);
    if (sQueryPtr == NULL) return QTSS_NoErr;
    
    ShowQuery_DEBUG();
    
    if (sAdminPtr != NULL) 
    {   delete sAdminPtr;
        sAdminPtr = NULL;
    }
    UInt32 result = sQueryPtr->EvalQuery(NULL, NULL);
    if (result == 0) do
    {
        if( ElementNode_CountPtrs() > 0)
        {   ElementNode_ShowPtrs();
            Assert(0);
        }
            
        GetQueryData(theRequest);
        
        SendResult(theRequest); 
        delete sAdminPtr;
        sAdminPtr = NULL;
        
        if (sQueryPtr && !sQueryPtr->QueryHasReponse())
        {   UInt32 err = 404;
            (void) sQueryPtr->EvalQuery(&err,NULL);
            ReportErr(inParams, err);
            break;
        }

        if (sQueryPtr && sQueryPtr->QueryHasReponse())
        {   ReportErr(inParams, sQueryPtr->GetEvaluResult());
        }
        
        if (sQueryPtr->fIsPref && sQueryPtr->GetEvaluResult() == 0)
        {   QTSS_ServiceID id;
            (void) QTSS_IDForService(QTSS_REREAD_PREFS_SERVICE, &id);           
            (void) QTSS_DoService(id, NULL);
        }
    } while(false);
    else
    {
        SendHeader(theRequest);         
        ReportErr(inParams, sQueryPtr->GetEvaluResult());
    }
    
    if (sQueryPtr != NULL) 
    {   delete sQueryPtr;
        sQueryPtr = NULL;
    }
    
    (void) StillFlushing(inParams,true);
    return QTSS_NoErr;

}
QTSS_Error FilterRequest(QTSS_Filter_Params* inParams)
{
#if HTTP_FILE_DEBUGGING
    qtss_printf("FilterRequest\n");
#endif

    static Bool16 sFalse = false;

    QTSS_RTSPRequestObject theRequest = inParams->inRTSPRequest;
    
    // Initial state.   
    StrPtrLen theFullRequest;
    StrPtrLen reqMethod;
    StrPtrLen reqStr;
    StrPtrLen httpVersion;
    
    (void)QTSS_GetValuePtr(theRequest, qtssRTSPReqFullRequest, 0, (void**)&theFullRequest.Ptr, &theFullRequest.Len);
    StringParser fullRequest(&theFullRequest);

    // Parsing the HTTP request
    fullRequest.ConsumeWord(&reqMethod);
    if ( !(reqMethod.Equal(StrPtrLen("GET")) || reqMethod.Equal(StrPtrLen("HEAD"))) )
        // It's not a "Get" or a "Head" request 
        return QTSS_NoErr;
     
    fullRequest.ConsumeWhitespace();
    if ( !fullRequest.Expect('/') )
        // Improperly formed request
        return QTSS_NoErr;
            
    fullRequest.ConsumeUntil(&reqStr, StringParser::sEOLWhitespaceMask);
    if( reqStr.Len == 0 )
        //if a file or directory name is not given, return
        return QTSS_NoErr;
        
    if ( !reqStr.Equal(StrPtrLen("Popular.smil")) )
        return QTSS_NoErr;
    
    // If it's a "Head" request send the Head response header back and just return
    if ( reqMethod.Equal(StrPtrLen("HEAD")) )
    {
        QTSS_Write(theRequest, sResponseHeader, ::strlen(sResponseHeader), NULL, 0);    
        return QTSS_NoErr;
    }

    // Create a buffer to store data.
    char theFileBuffer[8192];
    char contentLength[256];
        
    // Before sending any response, set keep alive to off for this connection
    // Regardless of what the client sends, the server always closes the connection after sending the file
    (void)QTSS_SetValue(theRequest, qtssRTSPReqRespKeepAlive, 0, &sFalse, sizeof(sFalse));
    
#if HTTP_FILE_DEBUGGING
    qtss_printf("Creating a smil file\n");   
#endif
    // Create a ref movie buffer for the single file. It is of the form:
    //  rtsptext\r
    //  rtsp://servername/filepath
    char smilFileBuf[8192] = {0};

    GenerateHotHitSMIL(smilFileBuf);
                
    qtss_sprintf(contentLength, "%lu", strlen(smilFileBuf));
    // Allocate memory for theFileBuffer
    // Write the HTTP header prefix into the buffer
    ::strcpy(theFileBuffer, sRespHeaderPrefix.Ptr);
    ::strcat(theFileBuffer, sContentLengthHeaderTag.Ptr);
    // Write the remaining part of the HTTP header into the file buffer
    ::strcat(theFileBuffer, contentLength);
    ::strcat(theFileBuffer, sContentTypeHeaderTag.Ptr);
    ::strcat(theFileBuffer, sSmilMimeType.Ptr);
    ::strcat(theFileBuffer, "\r\n\r\n");
    
    // Write the smil file created above to the file buffer
    ::strcat(theFileBuffer, smilFileBuf);
    
    // Write the contents of the file buffer to the request stream and return
    QTSS_Write(theRequest, theFileBuffer, strlen(theFileBuffer), NULL, 0);
    
#if HTTP_FILE_DEBUGGING
    qtss_printf("Wrote the smil file to the request stream. Successful!\n"); 
#endif

    return QTSS_NoErr;
}