148 lines
5.6 KiB
C++
148 lines
5.6 KiB
C++
/*
|
|
*
|
|
* @APPLE_LICENSE_HEADER_START@
|
|
*
|
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
|
* file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_END@
|
|
*
|
|
*/
|
|
/*
|
|
File: QTSSWebDebugModule.cpp
|
|
|
|
Contains: Implements web debug module
|
|
|
|
|
|
*/
|
|
|
|
#include "QTSSWebDebugModule.h"
|
|
#include "OS.h"
|
|
#include "OSMemory.h"
|
|
#include "StrPtrLen.h"
|
|
#include "ev.h"
|
|
|
|
// STATIC DATA
|
|
|
|
static QTSS_AttributeID sStateAttr = qtssIllegalAttrID;
|
|
|
|
static StrPtrLen sRequestHeader("GET /debug HTTP");
|
|
|
|
#if MEMORY_DEBUGGING
|
|
static char* sResponseHeader = "HTTP/1.0 200 OK\r\nServer: TimeShare/1.0\r\nConnection: Close\r\nContent-Type: text/html\r\n\r\n";
|
|
static char* sResponseEnd = "</BODY></HTML>";
|
|
#endif
|
|
|
|
// FUNCTION PROTOTYPES
|
|
|
|
QTSS_Error QTSSWebDebugModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams);
|
|
static QTSS_Error Register(QTSS_Register_Params* inParams);
|
|
static QTSS_Error Filter(QTSS_Filter_Params* inParams);
|
|
|
|
QTSS_Error QTSSWebDebugModule_Main(void* inPrivateArgs)
|
|
{
|
|
return _stublibrary_main(inPrivateArgs, QTSSWebDebugModuleDispatch);
|
|
}
|
|
|
|
QTSS_Error QTSSWebDebugModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams)
|
|
{
|
|
switch (inRole)
|
|
{
|
|
case QTSS_Register_Role:
|
|
return Register(&inParams->regParams);
|
|
case QTSS_RTSPFilter_Role:
|
|
return Filter(&inParams->rtspFilterParams);
|
|
}
|
|
return QTSS_NoErr;
|
|
}
|
|
|
|
QTSS_Error Register(QTSS_Register_Params* inParams)
|
|
{
|
|
// Do role & attribute setup
|
|
(void)QTSS_AddRole(QTSS_RTSPFilter_Role);
|
|
|
|
// Register an attribute
|
|
static char* sStateName = "QTSSWebDebugModuleState";
|
|
(void)QTSS_AddStaticAttribute(qtssRTSPRequestObjectType, sStateName, NULL, qtssAttrDataTypeUInt32);
|
|
(void)QTSS_IDForAttr(qtssRTSPRequestObjectType, sStateName, &sStateAttr);
|
|
|
|
// Tell the server our name!
|
|
static char* sModuleName = "QTSSWebDebugModule";
|
|
::strcpy(inParams->outModuleName, sModuleName);
|
|
|
|
return QTSS_NoErr;
|
|
}
|
|
|
|
QTSS_Error Filter(QTSS_Filter_Params* inParams)
|
|
{
|
|
UInt32 theLen = 0;
|
|
char* theFullRequest = NULL;
|
|
(void)QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqFullRequest, 0, (void**)&theFullRequest, &theLen);
|
|
|
|
if ((theFullRequest == NULL) || (theLen < sRequestHeader.Len))
|
|
return QTSS_NoErr;
|
|
if (::memcmp(theFullRequest, sRequestHeader.Ptr, sRequestHeader.Len) != 0)
|
|
return QTSS_NoErr;
|
|
|
|
#if MEMORY_DEBUGGING
|
|
UInt32* theStateVal = NULL;
|
|
(void)QTSS_GetValuePtr(inParams->inRTSPRequest, sStateAttr, 0, (void**)&theStateVal, &theLen);
|
|
//if ((theStateVal == NULL) || (theLen != sizeof(UInt32)))
|
|
//{
|
|
Bool16 theFalse = false;
|
|
(void)QTSS_SetValue(inParams->inRTSPRequest, qtssRTSPReqRespKeepAlive, 0, &theFalse, sizeof(theFalse));
|
|
|
|
// Begin writing the HTTP response. We don't need to worry about flow control
|
|
// because we're using the QTSS_RTSPRequestObject for the response, which does buffering
|
|
(void)QTSS_Write(inParams->inRTSPRequest, sResponseHeader, ::strlen(sResponseHeader), &theLen, 0);
|
|
|
|
//QTSS_EventContextRef* theContext = NULL;
|
|
//(void)QTSS_GetValuePtr(inParams->inRTSPSession, qtssRTSPSesEventCntxt, 0, (void**)&theContext, &theLen);
|
|
//Assert(theContext != NULL);
|
|
//Assert(theLen == sizeof(QTSS_EventContextRef));
|
|
|
|
//(void)QTSS_RequestEvent(*theContext, EV_WR);
|
|
|
|
// UInt32 theValue = 4;
|
|
// (void)QTSS_SetValue(inParams->inRTSPRequest, sStateAttr, 0, &theValue, sizeof(theValue));
|
|
// return QTSS_NoErr;
|
|
//}
|
|
|
|
//we must hold the tagQueue mutex for the duration of this exercise because
|
|
//we don't want any of the values we are reporting to change
|
|
OSMutexLocker locker(OSMemory::GetTagQueueMutex());
|
|
|
|
//write out header and total allocated memory
|
|
char buffer[1024];
|
|
qtss_sprintf(buffer, "<HTML><TITLE>TimeShare Debug Page</TITLE><BODY>Total dynamic memory allocated: %"_S32BITARG_"<P>List of objects:<BR>", OSMemory::GetAllocatedMemory());
|
|
(void)QTSS_Write(inParams->inRTSPRequest, buffer, ::strlen(buffer), &theLen, 0);
|
|
|
|
//now report the list of tags:
|
|
for (OSQueueIter iter(OSMemory::GetTagQueue()); !iter.IsDone(); iter.Next())
|
|
{
|
|
OSMemory::TagElem* elem = (OSMemory::TagElem*)iter.GetCurrent()->GetEnclosingObject();
|
|
Assert(elem != NULL);
|
|
if (elem->numObjects > 0)
|
|
{
|
|
qtss_sprintf(buffer, "Object allocated at: %s, %d. Number of currently allocated objects: %"_S32BITARG_", Total size: %"_S32BITARG_"<BR>", elem->fileName, elem->line, elem->numObjects, elem->totMemory);
|
|
(void)QTSS_Write(inParams->inRTSPRequest, buffer, ::strlen(buffer), &theLen, 0);
|
|
}
|
|
}
|
|
(void)QTSS_Write(inParams->inRTSPRequest, sResponseEnd, ::strlen(sResponseEnd), &theLen, 0);
|
|
#endif
|
|
return QTSS_NoErr;
|
|
}
|