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(¶mName); 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, ¶mLen); 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; }