📄 psphandler.cpp
字号:
enum { BUF_SIZE=2100 }; // 2048 from PIIOBuf.h plus some bytes
pData = (char *)PIUtil_malloc(BUF_SIZE);
int iLen = 0;
for( ; iRead<iContentLength && (iLen=PIIOBuffer_readToBuffer(pBuffer,pData,BUF_SIZE - 1))>0; ) {
HTTPCore_logDebug( DBG_LOW, "PSP: Read %d bytes from client.", iLen );
pData[iLen] = 0;
sv_catpv(tmp, pData);
iRead += iLen;
}
PIUtil_free( pData );
if ( pContentType && !PIUtil_stricmp( pContentType, "application/x-www-form-urlencoded" )) {
/* --- urldecode and add to Hash pspForm --- */
eval_pv( SPLIT_HASH("pspForm"), FALSE );
/* --- cleanup --- */
// sv_clear(tmp);
// sv_free(get_sv("pair", FALSE ));
// sv_free(get_sv("name", FALSE ));
// sv_free(get_sv("value", FALSE ));
HTTPCore_logDebug( DBG_LOW,
"PSP: %d bytes POST data of type '%s' added to form hash.",
iRead, pContentType );
} else {
/* --- simple scalar pspPlain --- */
HTTPCore_logDebug( DBG_LOW,
"PSP: %d bytes POST data of type '%s' added to scalar variable.",
iRead, pContentType );
}
}
} else {
const char *pQueryString = (const char *)PIDB_lookup( pQ, PIDBTYPE_STRING,
pFKQueryString, PIDBFLAG_FASTKEY );
if (pQueryString) {
SV *tmp = get_sv("pspPlain", TRUE);
sv_catpv(tmp, pQueryString);
/* --- urldecode and add to Hash pspForm --- */
eval_pv( SPLIT_HASH("pspQueryString"), FALSE );
/* --- cleanup --- */
// sv_clear(tmp);
// sv_free(get_sv("pair", FALSE ));
// sv_free(get_sv("name", FALSE ));
// sv_free(get_sv("value", FALSE ));
HTTPCore_logDebug( DBG_LOW,
"PSP: QueryString from '%s' request added to form hash.", pMethod );
};
}
#undef SPLIT_HASH
if (!get_cv("pspSetResponse", FALSE)) return PIAPI_COMPLETED;
/* --- Invoke pspSetResponse() --- */
char *args[] = { NULL };
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* ...is a temporary variable. */
PUSHMARK(SP); /* remember the stack pointer */
SV *ref = sv_setref_iv(newSViv(0), "const PIObjectPtr", (long)Object());
XPUSHs(sv_2mortal(ref));
SV *ref1 = sv_setref_iv(newSViv(0), "PIHTTPPtr", (long)pPIHTTP);
XPUSHs(sv_2mortal(ref1));
SV *ref2 = sv_setref_iv(newSViv(0), "PIIOBufferPtr", (long)pBuffer);
XPUSHs(sv_2mortal(ref2));
PUTBACK; /* make local stack pointer global */
if ( call_pv("pspSetResponse", G_SCALAR) != 1 ) /* call the function */
{
/* --- an error occurred --- */
HTTPCore_logError( pPIHTTP, "PSP: \
'pspSetResponse()' returned wrong number of arguments in file %s.", pPath );
return HTTPUtil_doHTTPError( pPIHTTP, ST_INTERNALERROR );
};
SPAGAIN; /* refresh stack pointer */
int iRet = POPi; /* pop the return value from stack */
PUTBACK;
FREETMPS; /* free that return value */
LEAVE;
switch (iRet) {
case PIAPI_ERROR:
HTTPCore_logError( pPIHTTP, "PSP: \
'pspSetResponse()' returned with PIAPI_ERROR.");
iRet = 1;
break;
case PIAPI_COMPLETED:
{
/* --- Read %pspResponse --- */
if (reqHash) {
hv_iterinit(reqHash);
long iKeyLen;
unsigned int iValLen;
SV* sValue = hv_iternextsv(reqHash, (char **)&pKey, &iKeyLen);
while (sValue) {
char *pValue = SvPV(sValue, iValLen);
PIDB_replace( pR, PIDBTYPE_RFC822, pKey, pValue, 0 );
HTTPCore_logDebug( DBG_LOW,
"PSP: Variable Response|RFC822|%s|%s written back to DB.",
pKey, pValue );
sValue = hv_iternextsv(reqHash, (char **)&pKey, &iKeyLen);
};
};
/* --- Read %pspResponseStatus --- */
SV* resStatus = get_sv("pspResponseStatus", FALSE);
if (resStatus) {
pPIHTTP->iStatus = SvIV(resStatus);
HTTPCore_logDebug( DBG_LOW,
"PSP: StatusCode %d written back to HTTP object.",
pPIHTTP->iStatus );
};
break;
}
default:
HTTPCore_logError( pPIHTTP, "PSP: \
'pspSetResponse()' returned unknown returncode '%d'.", iRet );
iRet = 1;
};
return iRet;
};
int OnLoad( PerlInterpreter *my_perl, PIHTTP *pPIHTTP, PIIOBuffer *pBuffer ) {
PIDB *pQ = pPIHTTP->pRequestDB;
PIDB *pR = pPIHTTP->pResponseDB;
const char *pPath = (const char *)PIDB_lookup( pR, PIDBTYPE_STRING,
pFKPath, PIDBFLAG_FASTKEY );
/* --- Invoke pspLoad() --- */
char *args[] = { NULL };
PERL_SET_CONTEXT(my_perl);
if (!get_cv("pspLoad", FALSE)) return PIAPI_COMPLETED;
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* ...is a temporary variable. */
PUSHMARK(SP); /* remember the stack pointer */
SV *ref = sv_setref_iv(newSViv(0), "const PIObjectPtr", (long)Object());
XPUSHs(sv_2mortal(ref));
PUTBACK; /* make local stack pointer global */
if ( call_pv("pspLoad", G_SCALAR) != 1 ) /* call the function */
{
/* --- an error occurred --- */
HTTPCore_logError( pPIHTTP, "PSP: \
'pspLoad()' returned wrong number of arguments." );
return PIAPI_ERROR;
};
SPAGAIN; /* refresh stack pointer */
int iRet = POPi; /* pop the return value from stack */
PUTBACK;
FREETMPS; /* free that return value */
LEAVE;
switch (iRet) {
case PIAPI_ERROR:
HTTPCore_logError( pPIHTTP, "PSP: \
'pspLoad()' returned with PIAPI_ERROR.");
iRet = 1;
break;
case PIAPI_COMPLETED:
break;
default:
HTTPCore_logError( pPIHTTP, "PSP: \
'pspLoad()' returned unknown returncode '%d'.", iRet);
iRet = 1;
};
return iRet;
};
int OnUnload( PerlInterpreter *my_perl, const char *pPath ) {
PIOStrStream os;
os << "PSP: ";
/* --- Invoke pspUnload() --- */
char *args[] = { NULL };
PERL_SET_CONTEXT(my_perl);
if (!get_cv("pspUnload", FALSE)) return PIAPI_COMPLETED;
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* ...is a temporary variable. */
PUSHMARK(SP); /* remember the stack pointer */
SV *ref = sv_setref_iv(newSViv(0), "const PIObjectPtr", (long)Object());
XPUSHs(sv_2mortal(ref));
PUTBACK; /* make local stack pointer global */
if ( call_pv("pspUnload", G_SCALAR) != 1 ) /* call the function */
{
/* --- an error occurred --- */
os << "'pspUnload()' returned wrong number of arguments.";
CONFIG_ERR( Object(), os.str() );
return PIAPI_ERROR;
};
SPAGAIN; /* refresh stack pointer */
int iRet = POPi; /* pop the return value from stack */
PUTBACK;
FREETMPS; /* free that return value */
LEAVE;
switch (iRet) {
case PIAPI_ERROR:
os << "'pspUnload()' returned with PIAPI_ERROR.";
CONFIG_ERR( Object(), os.str() );
iRet = 1;
break;
case PIAPI_COMPLETED:
break;
default:
os << "'pspUnload()' returned returned unknown returncode '"
<< iRet << "'.";
CONFIG_ERR( Object(), os.str() );
iRet = 1;
};
return iRet;
};
protected:
int Parameter( const char *pVariable, const char *pValue,
const char *pWhere )
{
assert( pVariable && pValue );
PIOStrStream os;
os << pWhere << "PSP: ";
if ( !PIUtil_stricmp( KEY_CONF_DESTRUCTLEVEL, pVariable ) )
{
iDestructLevel = atoi( pValue );
}
else
{
os << "Unknown directive '" << pVariable << "'" << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
};
return 1;
};
public:
PspHandler( PIObject *pObject, int iArgc, const char *ppArgv[] )
: HandlerBasePi3Perl( pObject ),
pContextDB( PIDB_new( 0, "PSP_Context" ) ),
pFKPath( PIDB_getFastKey( KEY_INT_PATH, PIDBTYPE_STRING ) ),
pFKContentType( PIDB_getFastKey( KEY_HTTP_CONTENTTYPE, PIDBTYPE_RFC822 ) ),
pFKContentLength( PIDB_getFastKey( KEY_HTTP_CONTENTLENGTH, PIDBTYPE_RFC822 ) ),
pFKMethod( PIDB_getFastKey( KEY_HTTP_METHOD, PIDBTYPE_STRING ) ),
pFKQueryString( PIDB_getFastKey( KEY_HTTP_QUERYSTRING, PIDBTYPE_STRING ) ),
iDestructLevel( 0 ),
pMutex ( PIPlatform_allocLocalMutex())
{
ReadParameters( iArgc, ppArgv );
};
~PspHandler()
{
/* ---
iterate through the Context DB and free context
--- */
const char *pKey;
PerlInterpreter *pPerl;
PIDBIterator *pIter;
pIter = PIDB_getIterator( pContextDB, PIDBTYPE_OPAQUE, 0, 0 );
if ( pIter ) {
for( ; PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter )) {
pPerl = (PerlInterpreter *)PIDBIterator_current( pIter, &pKey );
PERL_SET_CONTEXT(pPerl);
if (iDestructLevel == 1) {
perl_destruct(pPerl);
perl_free(pPerl);
};
};
PIDBIterator_delete( pIter );
};
PIDB_delete( pContextDB );
};
int Handle( int iPhase, PIHTTP &tPIHTTP, PIIOBuffer &tBuffer )
{
if (iPhase != PH_HANDLE) return PIAPI_ERROR;
PIDB *pR = tPIHTTP.pResponseDB;
const char *pPath = (const char *)PIDB_lookup( pR, PIDBTYPE_STRING,
pFKPath, PIDBFLAG_FASTKEY );
int iNew = 0;
PerlInterpreter *pPerl = getPerl(pPath, &iNew);
if (!pPerl) {
HTTPCore_logError( &tPIHTTP, "PSP: \
Fatal error, couldn't allocate Perl interpreter." );
return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
};
/* --- transfer-encoding --- */
int iFlags = (!PIHTTP_isChild( &tPIHTTP) && (int)PIDB_lookup( tPIHTTP.pRequestDB,
PIDBTYPE_OPAQUE, KEY_HTTP_PROTOCOL, 0 ) == 3 ) ? PIIOBUF_CHUNKED : PIIOBUF_NONE;
if ( iFlags & PIIOBUF_CHUNKED )
{
PIDB_replace( pR, PIDBTYPE_RFC822, KEY_HTTP_TRANSFERENCODING,
(void *)KEY_HTTP_CHUNKED, 0 );
};
thePSPParser Parser = thePSPParser( pPath, pPerl, tPIHTTP, tBuffer, iFlags );
int iRet = PIAPI_COMPLETED;
PISync_lock( pMutex );
if (Parser.exec()) iRet = HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
if (Parser.getParsedLen()) {
char szBuf[15];
sprintf(szBuf,"%ul",Parser.getContentLen());
PIDB_replace( pR, PIDBTYPE_RFC822, KEY_HTTP_CONTENTLENGTH, (void *)szBuf, 0 );
};
if ( iNew && OnLoad( pPerl, &tPIHTTP, &tBuffer )) iRet = HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
if ( SetResponse( pPerl, &tPIHTTP, &tBuffer )) iRet = HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
HTTPCore_sendGeneralHeaders(&tPIHTTP);
HTTPCore_sendEntityHeaders(&tPIHTTP, pR);
if ( iFlags & PIIOBUF_CHUNKED ) PIIOBuffer_flush( &tBuffer );
Parser.prepare_next_pass();
Parser.exec();
PISync_unlock( pMutex );
PIIOBuffer_flush( &tBuffer );
return iRet;
};
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int PSP_constructor( PIObject *pObj,
int iArgc, const char *ppArgv[] )
{
return HandlerBasePi3Perl_constructor( pObj, PI_NEW( PspHandler( pObj,
iArgc, ppArgv ) ) );
}
#if 0
/*___+++CNF_BEGIN+++___*/
<Class>
Name PSPClass
Type LogicExtension
Library Pi3Perl
OnClassLoad HandlerBasePi3Perl_onClassLoad
Constructor PSP_constructor
CopyConstructor HandlerBasePi3Perl_copyConstructor
Destructor HandlerBasePi3Perl_destructor
Execute HandlerBasePi3Perl_execute
</Class>
<Object>
Name PerlSrvPages
Class PSPClass
</Object>
/*___+++CNF_END+++___*/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -