Пример #1
0
// 
// 解析HTTPRequest对象fRequest报文
QTSS_Error EasyCMSSession::ProcessRequest()
{
	if(NULL == fRequest) return QTSS_BadArgument;

    //解析HTTPRequest报文
    QTSS_Error theErr = fRequest->Parse();
    if (theErr != QTSS_NoErr) return QTSS_BadArgument;

	//获取具体Content json数据部分
	StrPtrLen* lengthPtr = fRequest->GetHeaderValue(httpContentLengthHeader);
	StringParser theContentLenParser(lengthPtr);
    theContentLenParser.ConsumeWhitespace();
    UInt32 content_length = theContentLenParser.ConsumeInteger(NULL);

    if (content_length)
	{	
		qtss_printf("EasyCMSSession::ProcessRequest read content-length:%d \n", content_length);
		// 检查content的fContentBuffer和fContentBufferOffset是否有值存在,如果存在,说明我们已经开始
		// 进行content请求处理,如果不存在,我们需要创建并初始化fContentBuffer和fContentBufferOffset
		if (fContentBuffer == NULL)
		{
			fContentBuffer = NEW char[content_length + 1];
			memset(fContentBuffer,0,content_length + 1);
			fContentBufferOffset = 0;
		}
	    
		UInt32 theLen = 0;
		// 读取HTTP Content报文数据
		theErr = fInputStream.Read(fContentBuffer + fContentBufferOffset, content_length - fContentBufferOffset, &theLen);
		Assert(theErr != QTSS_BadArgument);

		if (theErr == QTSS_RequestFailed)
		{
			OSCharArrayDeleter charArrayPathDeleter(fContentBuffer);
			fContentBufferOffset = 0;
			fContentBuffer = NULL;

			return QTSS_RequestFailed;
		}
	    
		qtss_printf("EasyCMSSession::ProcessRequest() Add Len:%d \n", theLen);
		if ((theErr == QTSS_WouldBlock) || (theLen < ( content_length - fContentBufferOffset)))
		{
			//
			// Update our offset in the buffer
			fContentBufferOffset += theLen;
	       
			Assert(theErr == QTSS_NoErr);
			return QTSS_WouldBlock;
		}

		Assert(theErr == QTSS_NoErr);
	    // 处理完成报文后会自动进行Delete处理
		OSCharArrayDeleter charArrayPathDeleter(fContentBuffer);

		EasyProtocol protocol(fContentBuffer);
		int nNetMsg = protocol.GetMessageType();
		switch (nNetMsg)
		{
		case  MSG_DEV_CMS_REGISTER_RSP:
			//{	
			//	EasyDarwinRegisterRSP rsp_parse(fContentBuffer);

			//	qtss_printf("session id = %s\n", rsp_parse.GetBodyValue("SessionID").c_str());
			//	qtss_printf("device serial = %s\n", rsp_parse.GetBodyValue("DeviceSerial").c_str());
			//}
			break;
		case MSG_CMS_DEV_STREAM_START_REQ:
			{
				//EasyDarwinDeviceStreamReq	startStreamReq(fContentBuffer);
				//qtss_printf("DeviceSerial = %s\n", startStreamReq.GetBodyValue("DeviceSerial").c_str());
				//qtss_printf("CameraSerial = %s\n", startStreamReq.GetBodyValue("CameraSerial").c_str());
				//qtss_printf("DssIP = %s\n", startStreamReq.GetBodyValue("DssIP").c_str());


				//char szIP[16] = {0,};
				//strcpy(szIP, (char*)startStreamReq.GetBodyValue("DssIP").c_str());
				//qtss_printf("szIP = %s\n", szIP);
				//char *ip = (char*)startStreamReq.GetBodyValue("DssIP").c_str();
				//qtss_printf("ip = %s\n", ip);

				//QTSS_RoleParams packetParams;
				//memset(&packetParams, 0x00, sizeof(QTSS_RoleParams));
				//strcpy(packetParams.easyNVRParams.inNVRSerialNumber, (char*)sEasy_Serial);
				//strcpy(packetParams.easyNVRParams.inDeviceSerial, (char*)startStreamReq.GetBodyValue("DeviceSerial").c_str());
				//strcpy(packetParams.easyNVRParams.inCameraSerial, (char*)startStreamReq.GetBodyValue("CameraSerial").c_str());
				//packetParams.easyNVRParams.inStreamID = atoi(startStreamReq.GetBodyValue("StreamID").c_str());
				//strcpy(packetParams.easyNVRParams.inProtocol, (char*)startStreamReq.GetBodyValue("Protocol").c_str());
				//strcpy(packetParams.easyNVRParams.inDssIP, (char*)startStreamReq.GetBodyValue("DssIP").c_str());
				//packetParams.easyNVRParams.inDssPort =atoi(startStreamReq.GetBodyValue("DssPort").c_str());

				//QTSS_Error	errCode = QTSS_NoErr;
				//UInt32 fCurrentModule=0;
				//UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStartStreamRole);
				//for (; fCurrentModule < numModules; fCurrentModule++)
				//{
				//	QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStartStreamRole, fCurrentModule);
				//	errCode = theModule->CallDispatch(Easy_NVRStartStream_Role, &packetParams);
				//}
				//fCurrentModule = 0;

				//EasyJsonValue body;
				//body["DeviceSerial"] = packetParams.easyNVRParams.inDeviceSerial;
				//body["CameraSerial"] = packetParams.easyNVRParams.inCameraSerial;
				//body["StreamID"] = packetParams.easyNVRParams.inStreamID;
				//EasyDarwinDeviceStreamRsp rsp(body, 1, errCode == QTSS_NoErr ? 200 : 404);

				//string msg = rsp.GetMsg();
				//StrPtrLen jsonContent((char*)msg.data());
				//HTTPRequest httpAck(&sServiceStr, httpResponseType);

				//if(httpAck.CreateResponseHeader())
				//{
				//	if (jsonContent.Len)
				//		httpAck.AppendContentLengthHeader(jsonContent.Len);

				//	//Push msg to OutputBuffer
				//	char respHeader[2048] = { 0 };
				//	StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader();
				//	strncpy(respHeader,ackPtr->Ptr, ackPtr->Len);
		
				//	fOutputStream.Put(respHeader);
				//	if (jsonContent.Len > 0) 
				//		fOutputStream.Put(jsonContent.Ptr, jsonContent.Len);
				//}
			}
			break;
		case MSG_CMS_DEV_STREAM_STOP_REQ:
			{
				//EasyDarwinDeviceStreamStop	stopStreamReq(fContentBuffer);

				//QTSS_RoleParams packetParams;
				//memset(&packetParams, 0x00, sizeof(QTSS_RoleParams));
				//strcpy(packetParams.easyNVRParams.inNVRSerialNumber, (char*)sEasy_Serial);
				//strcpy(packetParams.easyNVRParams.inDeviceSerial, (char*)stopStreamReq.GetBodyValue("DeviceSerial").data());
				//strcpy(packetParams.easyNVRParams.inCameraSerial, (char*)stopStreamReq.GetBodyValue("CameraSerial").data());
				//packetParams.easyNVRParams.inStreamID = atoi(stopStreamReq.GetBodyValue("StreamID").data());
				//strcpy(packetParams.easyNVRParams.inProtocol, "");
				//strcpy(packetParams.easyNVRParams.inDssIP, "");
				//packetParams.easyNVRParams.inDssPort = 0;

				//// 需要先判断DeviceSerial与当前设备的sEasy_Serial是否一致
				//// TODO::

				//UInt32 fCurrentModule=0;
				//QTSS_Error err = QTSS_NoErr;
				//UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStopStreamRole);
				//for (; fCurrentModule < numModules; fCurrentModule++)
				//{
				//	QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStopStreamRole, fCurrentModule);
				//	err = theModule->CallDispatch(Easy_NVRStopStream_Role, &packetParams);
				//}
				//fCurrentModule = 0;

				//EasyJsonValue body;
				//body["DeviceSerial"] = packetParams.easyNVRParams.inDeviceSerial;
				//body["CameraSerial"] = packetParams.easyNVRParams.inCameraSerial;
				//body["StreamID"] = packetParams.easyNVRParams.inStreamID;

				//EasyDarwinDeviceStreamStopRsp rsp(body, 1, err == QTSS_NoErr ? 200 : 404);
				//string msg = rsp.GetMsg();

				////回应
				//StrPtrLen jsonContent((char*)msg.data());
				//HTTPRequest httpAck(&sServiceStr, httpResponseType);

				//if(httpAck.CreateResponseHeader())
				//{
				//	if (jsonContent.Len)
				//		httpAck.AppendContentLengthHeader(jsonContent.Len);

				//	//Push msg to OutputBuffer
				//	char respHeader[2048] = { 0 };
				//	StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader();
				//	strncpy(respHeader,ackPtr->Ptr, ackPtr->Len);
		
				//	fOutputStream.Put(respHeader);
				//	if (jsonContent.Len > 0) 
				//		fOutputStream.Put(jsonContent.Ptr, jsonContent.Len);
				//}
			}
			break;
		default:
			break;
		}
	}
Пример #2
0
char* SDPSourceInfo::GetLocalSDP(UInt32* newSDPLen)
{
    Assert(fSDPData.Ptr != NULL);

    bool appendCLine = true;
    UInt32 trackIndex = 0;
    
    char *localSDP = new char[fSDPData.Len * 2];
    OSCharArrayDeleter charArrayPathDeleter(localSDP);
    StringFormatter localSDPFormatter(localSDP, fSDPData.Len * 2);

    StrPtrLen sdpLine;
    StringParser sdpParser(&fSDPData);
    char trackIndexBuffer[50];
    
    // Only generate our own trackIDs if this file doesn't have 'em.
    // Our assumption here is that either the file has them, or it doesn't.
    // A file with some trackIDs, and some not, won't work.
    bool hasControlLine = false;

    while (sdpParser.GetDataRemaining() > 0)
    {
        //stop when we reach an empty line.
        sdpParser.GetThruEOL(&sdpLine);
        if (sdpLine.Len == 0)
            continue;
            
        switch (*sdpLine.Ptr)
        {
            case 'c':
                break;//ignore connection information
            case 'm':
            {
                //append new connection information right before the first 'm'
                if (appendCLine)
                {
                    localSDPFormatter.Put(sCLine);
                    localSDPFormatter.PutEOL();
                   
                    if (!hasControlLine)
                    { 
                      localSDPFormatter.Put(sControlLine);
                      localSDPFormatter.PutEOL();
                    }
                    
                    appendCLine = false;
                }
                //the last "a=" for each m should be the control a=
                if ((trackIndex > 0) && (!hasControlLine))
                {
                    qtss_sprintf(trackIndexBuffer, "a=control:trackID=%" _S32BITARG_ "\r\n",trackIndex);
                    localSDPFormatter.Put(trackIndexBuffer, ::strlen(trackIndexBuffer));
                }
                //now write the 'm' line, but strip off the port information
                StringParser mParser(&sdpLine);
                StrPtrLen mPrefix;
                mParser.ConsumeUntil(&mPrefix, StringParser::sDigitMask);
                localSDPFormatter.Put(mPrefix);
                localSDPFormatter.Put("0", 1);
                (void)mParser.ConsumeInteger(NULL);
                localSDPFormatter.Put(mParser.GetCurrentPosition(), mParser.GetDataRemaining());
                localSDPFormatter.PutEOL();
                trackIndex++;
                break;
            }
            case 'a':
            {
                StringParser aParser(&sdpLine);
                aParser.ConsumeLength(NULL, 2);//go past 'a='
                StrPtrLen aLineType;
                aParser.ConsumeWord(&aLineType);
                if (aLineType.Equal(sControlStr))
                {
                    aParser.ConsumeUntil(NULL, '=');
                    aParser.ConsumeUntil(NULL, StringParser::sDigitMask);
                    
                   StrPtrLen aDigitType;                
                   (void)aParser.ConsumeInteger(&aDigitType);
                    if (aDigitType.Len > 0)
                    {
                      localSDPFormatter.Put("a=control:trackID=", 18);
                      localSDPFormatter.Put(aDigitType);
                      localSDPFormatter.PutEOL();
                      hasControlLine = true;
                      break;
                    }
                }
               
                localSDPFormatter.Put(sdpLine);
                localSDPFormatter.PutEOL();
                break;
            }
            default:
            {
                localSDPFormatter.Put(sdpLine);
                localSDPFormatter.PutEOL();
            }
        }
    }
    
    if ((trackIndex > 0) && (!hasControlLine))
    {
        qtss_sprintf(trackIndexBuffer, "a=control:trackID=%" _S32BITARG_ "\r\n",trackIndex);
        localSDPFormatter.Put(trackIndexBuffer, ::strlen(trackIndexBuffer));
    }
    *newSDPLen = (UInt32)localSDPFormatter.GetCurrentOffset();
    
    StrPtrLen theSDPStr(localSDP, *newSDPLen);//localSDP is not 0 terminated so initialize theSDPStr with the len.
    SDPContainer rawSDPContainer; 
    (void) rawSDPContainer.SetSDPBuffer( &theSDPStr );    
    SDPLineSorter sortedSDP(&rawSDPContainer);

    return sortedSDP.GetSortedSDPCopy(); // return a new copy of the sorted SDP
}
Пример #3
0
QTSS_Error EasyCMSSession::ProcessMessage()
{
	if(NULL == fRequest) return QTSS_BadArgument;

    //解析HTTPRequest报文
    QTSS_Error theErr = fRequest->Parse();
    if (theErr != QTSS_NoErr) return QTSS_BadArgument;

	//获取具体Content json数据部分
	StrPtrLen* lengthPtr = fRequest->GetHeaderValue(httpContentLengthHeader);
	StringParser theContentLenParser(lengthPtr);
    theContentLenParser.ConsumeWhitespace();
    UInt32 content_length = theContentLenParser.ConsumeInteger(NULL);

    if (content_length)
	{	
		qtss_printf("EasyCMSSession::ProcessMessage read content-length:%d \n", content_length);
		// 检查content的fContentBuffer和fContentBufferOffset是否有值存在,如果存在,说明我们已经开始
		// 进行content请求处理,如果不存在,我们需要创建并初始化fContentBuffer和fContentBufferOffset
		if (fContentBuffer == NULL)
		{
			fContentBuffer = NEW char[content_length + 1];
			memset(fContentBuffer,0,content_length + 1);
			fContentBufferOffset = 0;
		}
	    
		UInt32 theLen = 0;
		// 读取HTTP Content报文数据
		theErr = fInputStream.Read(fContentBuffer + fContentBufferOffset, content_length - fContentBufferOffset, &theLen);
		Assert(theErr != QTSS_BadArgument);

		if (theErr == QTSS_RequestFailed)
		{
			OSCharArrayDeleter charArrayPathDeleter(fContentBuffer);
			fContentBufferOffset = 0;
			fContentBuffer = NULL;

			return QTSS_RequestFailed;
		}
	    
		qtss_printf("EasyCMSSession::ProcessMessage() Add Len:%d \n", theLen);
		if ((theErr == QTSS_WouldBlock) || (theLen < ( content_length - fContentBufferOffset)))
		{
			//
			// Update our offset in the buffer
			fContentBufferOffset += theLen;
	       
			Assert(theErr == QTSS_NoErr);
			return QTSS_WouldBlock;
		}

		Assert(theErr == QTSS_NoErr);

	    // 处理完成报文后会自动进行Delete处理
		OSCharArrayDeleter charArrayPathDeleter(fContentBuffer);

		qtss_printf("EasyCMSSession::ProcessMessage() Get Complete Msg:\n%s", fContentBuffer);

		EasyProtocol protocol(fContentBuffer);
		int nNetMsg = protocol.GetMessageType();
		switch (nNetMsg)
		{
		case  MSG_SC_FREE_STREAM_ACK:
			{
				string strErrorNum		=	protocol.GetHeaderValue(EASY_TAG_ERROR_NUM);
				string strSerial		=	protocol.GetBodyValue(EASY_TAG_SERIAL);
				string strChannle		=	protocol.GetBodyValue(EASY_TAG_CHANNEL);
				
				qtss_printf("EasyCMS停止推流响应:%s,Serial=%s,Channel=%s",strErrorNum.c_str(),strSerial.c_str(),strChannle.c_str());
				fLiveSession=false;//进入析构
			}
			break;
		default:
			break;
		}
	}
Пример #4
0
QTSS_Error EasyCMSSession::processMessage()
{
	if (NULL == fRequest) return QTSS_BadArgument;

	QTSS_Error theErr = fRequest->Parse();
	if (theErr != QTSS_NoErr)
		return QTSS_BadArgument;

	//获取具体Content json数据部分
	StrPtrLen* lengthPtr = fRequest->GetHeaderValue(httpContentLengthHeader);
	StringParser theContentLenParser(lengthPtr);
	theContentLenParser.ConsumeWhitespace();
	UInt32 content_length = theContentLenParser.ConsumeInteger(NULL);

	if (content_length)
	{
		qtss_printf("EasyCMSSession::ProcessMessage read content-length:%lu \n", content_length);
		// 检查content的fContentBuffer和fContentBufferOffset是否有值存在,如果存在,说明我们已经开始
		// 进行content请求处理,如果不存在,我们需要创建并初始化fContentBuffer和fContentBufferOffset
		if (fContentBuffer == NULL)
		{
			fContentBuffer = NEW char[content_length + 1];
			memset(fContentBuffer, 0, content_length + 1);
			fContentBufferOffset = 0;
		}

		UInt32 theLen = 0;
		// 读取HTTP Content报文数据
		theErr = fInputStream.Read(fContentBuffer + fContentBufferOffset, content_length - fContentBufferOffset, &theLen);
		Assert(theErr != QTSS_BadArgument);

		if (theErr == QTSS_RequestFailed)
		{
			OSCharArrayDeleter charArrayPathDeleter(fContentBuffer);
			fContentBufferOffset = 0;
			fContentBuffer = NULL;

			return QTSS_RequestFailed;
		}

		qtss_printf("EasyCMSSession::ProcessMessage() Add Len:%lu \n", theLen);
		if ((theErr == QTSS_WouldBlock) || (theLen < (content_length - fContentBufferOffset)))
		{
			//
			// Update our offset in the buffer
			fContentBufferOffset += theLen;

			Assert(theErr == QTSS_NoErr);
			return QTSS_WouldBlock;
		}

		Assert(theErr == QTSS_NoErr);

		// 处理完成报文后会自动进行Delete处理
		OSCharArrayDeleter charArrayPathDeleter(fContentBuffer);

		qtss_printf("EasyCMSSession::ProcessMessage() Get Complete Msg:\n%s", fContentBuffer);

		fNoneACKMsgCount = 0;

		EasyProtocol protocol(fContentBuffer);
		int nNetMsg = protocol.GetMessageType();
		switch (nNetMsg)
		{
		case MSG_SD_REGISTER_ACK:
			{
				EasyMsgSDRegisterACK ack(fContentBuffer);

				qtss_printf("session id = %s\n", ack.GetBodyValue(EASY_TAG_SESSION_ID).c_str());
				qtss_printf("device serial = %s\n", ack.GetBodyValue(EASY_TAG_SERIAL).c_str());
			}
			break;
		case MSG_SD_POST_SNAP_ACK:
			{
				;
			}
			break;
		case MSG_SD_PUSH_STREAM_REQ:
			{
				EasyMsgSDPushStreamREQ	startStreamReq(fContentBuffer);

				string serial = startStreamReq.GetBodyValue(EASY_TAG_SERIAL);
				string ip = startStreamReq.GetBodyValue(EASY_TAG_SERVER_IP);
				string port = startStreamReq.GetBodyValue(EASY_TAG_SERVER_PORT);
				string protocol = startStreamReq.GetBodyValue(EASY_TAG_PROTOCOL);
				string channel = startStreamReq.GetBodyValue(EASY_TAG_CHANNEL);
				string streamID = startStreamReq.GetBodyValue(EASY_TAG_STREAM_ID);
				string reserve = startStreamReq.GetBodyValue(EASY_TAG_RESERVE);

				qtss_printf("Serial = %s\n", serial.c_str());
				qtss_printf("Server_IP = %s\n", ip.c_str());
				qtss_printf("Server_Port = %s\n", port.c_str());

				//TODO::这里需要对传入的Serial/StreamID/Channel做一下容错处理
				if (serial.empty() || ip.empty() || port.empty())
				{
					return QTSS_ValueNotFound;
				}

				QTSS_RoleParams params;

				params.startStreaParams.inIP = ip.c_str();
				params.startStreaParams.inPort = atoi(port.c_str());
				params.startStreaParams.inSerial = serial.c_str();
				params.startStreaParams.inProtocol = protocol.c_str();
				params.startStreaParams.inChannel = channel.c_str();
				params.startStreaParams.inStreamID = streamID.c_str();

				QTSS_Error errCode = QTSS_NoErr;
				UInt32 fCurrentModule = 0;
				UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStartStreamRole);
				for (; fCurrentModule < numModules; ++fCurrentModule)
				{
					QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStartStreamRole, fCurrentModule);
					errCode = theModule->CallDispatch(Easy_StartStream_Role, &params);
				}
				fCurrentModule = 0;

				EasyJsonValue body;
				body[EASY_TAG_SERIAL] = params.startStreaParams.inSerial;
				body[EASY_TAG_CHANNEL] = params.startStreaParams.inChannel;
				body[EASY_TAG_PROTOCOL] = params.startStreaParams.inProtocol;
				body[EASY_TAG_SERVER_IP] = params.startStreaParams.inIP;
				body[EASY_TAG_SERVER_PORT] = params.startStreaParams.inPort;
				body[EASY_TAG_RESERVE] = reserve;

				EasyMsgDSPushSteamACK rsp(body, startStreamReq.GetMsgCSeq(), getStatusNo(errCode));

				string msg = rsp.GetMsg();
				StrPtrLen jsonContent((char*)msg.data());
				HTTPRequest httpAck(&QTSServerInterface::GetServerHeader(), httpResponseType);

				if (httpAck.CreateResponseHeader())
				{
					if (jsonContent.Len)
						httpAck.AppendContentLengthHeader(jsonContent.Len);

					//Push msg to OutputBuffer
					char respHeader[2048] = { 0 };
					StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader();
					strncpy(respHeader, ackPtr->Ptr, ackPtr->Len);

					fOutputStream.Put(respHeader);
					if (jsonContent.Len > 0)
						fOutputStream.Put(jsonContent.Ptr, jsonContent.Len);
				}
			}
			break;
		case MSG_SD_STREAM_STOP_REQ:
			{
				EasyMsgSDStopStreamREQ stopStreamReq(fContentBuffer);

				QTSS_RoleParams params;

				string serial = stopStreamReq.GetBodyValue(EASY_TAG_SERIAL);
				params.stopStreamParams.inSerial = serial.c_str();
				string protocol = stopStreamReq.GetBodyValue(EASY_TAG_PROTOCOL);
				params.stopStreamParams.inProtocol = protocol.c_str();
				string channel = stopStreamReq.GetBodyValue(EASY_TAG_CHANNEL);
				params.stopStreamParams.inChannel = channel.c_str();

				QTSS_Error errCode = QTSS_NoErr;
				UInt32 fCurrentModule = 0;
				UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStopStreamRole);
				for (; fCurrentModule < numModules; ++fCurrentModule)
				{
					QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStopStreamRole, fCurrentModule);
					errCode = theModule->CallDispatch(Easy_StopStream_Role, &params);
				}
				fCurrentModule = 0;

				EasyJsonValue body;
				body[EASY_TAG_SERIAL] = params.stopStreamParams.inSerial;
				body[EASY_TAG_CHANNEL] = params.stopStreamParams.inChannel;
				body[EASY_TAG_PROTOCOL] = params.stopStreamParams.inProtocol;


				EasyMsgDSStopStreamACK rsp(body, stopStreamReq.GetMsgCSeq(), getStatusNo(errCode));
				string msg = rsp.GetMsg();

				//回应
				StrPtrLen jsonContent((char*)msg.data());
				HTTPRequest httpAck(&QTSServerInterface::GetServerHeader(), httpResponseType);

				if (httpAck.CreateResponseHeader())
				{
					if (jsonContent.Len)
						httpAck.AppendContentLengthHeader(jsonContent.Len);

					//Push msg to OutputBuffer
					char respHeader[2048] = { 0 };
					StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader();
					strncpy(respHeader, ackPtr->Ptr, ackPtr->Len);

					fOutputStream.Put(respHeader);
					if (jsonContent.Len > 0)
						fOutputStream.Put(jsonContent.Ptr, jsonContent.Len);
				}
			}
			break;
		default:
			break;
		}
	}