php4handler.cpp
来自「mini http server,可以集成嵌入到程序中,实现简单的web功能」· C++ 代码 · 共 908 行 · 第 1/2 页
CPP
908 行
*lpdwSize = iToCopy; \
strncpy( (char *)lpvBuffer, pValue, iToCopy ); \
return PIAPI_TRUE; \
};
# define FN_STRING( name, value ) \
static BOOL (name)( PHP4 *, PIHTTP *pPIHTTP, LPVOID lpvBuffer, \
LPDWORD lpdwSize ) \
{ \
const char *pValue = (value); \
if ( !pValue ) \
{ \
pValue = ""; \
}; \
int iToCopy = strlen( pValue ) + 1; \
if ( (DWORD)iToCopy>*lpdwSize || !lpvBuffer ) \
{ \
*lpdwSize = iToCopy; \
PIPlatform_setLastError( PIAPI_EINVAL ); \
return PIAPI_FALSE; \
}; \
*lpdwSize = iToCopy; \
strncpy( (char *)lpvBuffer, pValue, iToCopy ); \
return PIAPI_TRUE; \
};
FN_DB_STR( fnAuthType, pResponseDB, PIDBTYPE_STRING, KEY_INT_AUTHTYPE );
FN_DB_STR( fnContentLength, pRequestDB, PIDBTYPE_RFC822, KEY_HTTP_CONTENTLENGTH );
FN_DB_STR( fnContentType, pRequestDB, PIDBTYPE_RFC822, KEY_HTTP_CONTENTTYPE );
FN_STRING( fnGatewayInterface, "CGI/1.1" );
FN_DB_STR( fnPathInfo, pResponseDB, PIDBTYPE_STRING, KEY_INT_PATHINFO );
FN_DB_STR( fnPathTranslated, pResponseDB, PIDBTYPE_STRING, KEY_INT_PATHTRANSLATED );
FN_DB_STR( fnQueryString, pRequestDB, PIDBTYPE_STRING, KEY_HTTP_QUERYSTRING );
FN_DB_STR( fnRemoteAddr, pConnectionDB, PIDBTYPE_STRING, KEY_INT_REMOTEADDR );
FN_DB_STR( fnRemoteHost, pConnectionDB, PIDBTYPE_STRING, KEY_INT_REMOTEHOST );
FN_DB_STR( fnRemoteUser, pResponseDB, PIDBTYPE_STRING, KEY_INT_REMOTEUSER );
FN_DB_STR( fnRequestMethod, pRequestDB, PIDBTYPE_STRING, KEY_HTTP_METHOD );
FN_DB_STR( fnScriptName, pResponseDB, PIDBTYPE_STRING, KEY_INT_SCRIPTNAME );
FN_DB_STR( fnServerProtocol, pRequestDB, PIDBTYPE_STRING, KEY_HTTP_PROTOCOL );
FN_DB_STR( fnCookie, pRequestDB, PIDBTYPE_RFC822, KEY_HTTP_COOKIE );
FN_STRING( fnServerName, HTTPUtil_getHostName(pPIHTTP) );
FN_STRING( fnServerPort, HTTPUtil_getHostPort(pPIHTTP) );
FN_STRING( fnServerSoftware, HTTPCore_getServerStamp() );
#undef FN_DB_STR
#undef FN_STRING
int Parameter( const char *pVariable, const char *pValue,
const char *pWhere )
{
assert( pVariable && pValue );
PIOStrStream os;
os << pWhere << "PHP4: ";
if ( !PIUtil_stricmp( KEY_CONF_EXTRAHDRPREFIX, pVariable ) )
{
sExtraHeadersPrefix = (const char *)DeQuote( pValue );
}
else if ( !PIUtil_stricmp( KEY_CONF_BEHAVIOR, pVariable ) )
{
/* ---
cycle through the list of available flags
comparing them with this one
--- */
int i=0;
for( ; aFlagMap[i].pName; i++ )
{
if ( !PIUtil_stricmp( aFlagMap[i].pName,
DeQuote( pValue ))) { break; };
};
if ( !aFlagMap[i].pName )
{
/* --- flag not found --- */
os << "Unknown PHP4 mode '" << pValue << "'." << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
};
iBehavior = aFlagMap[i].iFlag;
}
else
{
os << "Unknown directive '" << pVariable <<
"'" << ends;
CONFIG_ERR( Object(), os.str() );
return 0;
};
return 1;
};
public:
PHP4( PIObject *pObject, int iArgc, const char *ppArgv[] )
: HandlerBasePHP4( pObject ),
pTypes( PIDB_new( 0, "Types" )),
iBehavior( PHP_MODE_STANDARD )
{
ReadParameters( iArgc, ppArgv );
/* ---
Insert DB types for 'GetServerVariable'
--- */
#define AT( name, function ) \
PIDB_add( pTypes, PIDBTYPE_OPAQUE, (name), (void *)function, 0 );
AT( "ALL_HTTP", fnAllHttp );
AT( "AUTH_TYPE", fnAuthType );
AT( "CONTENT_LENGTH", fnContentLength );
AT( "CONTENT_TYPE", fnContentType );
AT( "GATEWAY_INTERFACE", fnGatewayInterface );
AT( "PATH_INFO", fnPathInfo );
AT( "PATH_TRANSLATED", fnPathTranslated );
AT( "QUERY_STRING", fnQueryString );
AT( "REMOTE_ADDR", fnRemoteAddr );
AT( "REMOTE_HOST", fnRemoteHost );
AT( "REMOTE_USER", fnRemoteUser );
AT( "REQUEST_METHOD", fnRequestMethod );
AT( "SCRIPT_NAME", fnScriptName );
AT( "SERVER_NAME", fnServerName );
AT( "SERVER_PORT", fnServerPort );
AT( "SERVER_PROTOCOL", fnServerProtocol );
AT( "SERVER_SOFTWARE", fnServerSoftware );
AT( "HTTP_COOKIE", fnCookie );
#undef AT
};
virtual ~PHP4()
{
PIDB_delete( pTypes );
};
int Handle( int iPhase, PIHTTP &tPIHTTP, PIIOBuffer &/* tBuffer */ )
{
if ( iPhase != PH_HANDLE) return PIAPI_ERROR;
/* ---
Create new PHP4 context
--- */
PHP4Context tContext( this, &tPIHTTP, iBehavior );
const char *pPath = (const char *)PIDB_lookup( tPIHTTP.pResponseDB,
PIDBTYPE_STRING, KEY_INT_PATH, 0 );
/* ---
Read in stdin (if any)
--- */
if ( tContext.cbTotalBytes )
{
/* ---
See how much we can read on the first pass and leave the
extension for call ReadClient() for the rest
--- */
int iRead = 0;
const char *pBuffer = PIIOBuffer_read( tPIHTTP.pBuffer, &iRead );
if ( !pBuffer || !iRead )
{
/* ---
This is an error
--- */
HTTPCore_logError( &tPIHTTP, "PHP4: Could not read stdin \
(%ld bytes) for PHP3 script '%s'.", (long)tContext.cbTotalBytes, pPath );
return HTTPUtil_doHTTPError( &tPIHTTP, ST_INTERNALERROR );
};
/* ---
Allocate a buffer and put data in it, buffer size will be
no more that internal buffer in PIIOBuffer object.
(usually between 4 and 16 K).
--- */
tContext.lpbData = (LPBYTE)PIHTTP_allocMem( &tPIHTTP, iRead );
memcpy( tContext.lpbData, pBuffer, iRead );
tContext.cbAvailable = iRead;
};
/* ---
Fire off PHP4 Wrapper
--- */
int iRet = PHP4_wrapper( &tContext );
/* ---
Check for error message
--- */
if ( tContext.lpszLogData && *(tContext.lpszLogData) )
{
HTTPCore_logError( &tPIHTTP, "PHP4: Script with path '%s' \
logged an error message: ________________________________________________________________________________\n%s\n________________________________________________________________________________", pPath, tContext.lpszLogData );
};
tPIHTTP.iStatus = tContext.dwHttpStatusCode;
switch( iRet )
{
case PIAPI_COMPLETED:
if (iBehavior == PHP_MODE_LINT )
{
#define MSG "\
<BODY BGCOLOR=\"#FFFFFF\" BACKGROUND=\"/icons/Pi3Tile.gif\">\
<H2>PHP4 Syntax correct</H2>\
The syntax check for the called PHP4 resource succeeded.</BODY>"
unsigned long ulLen;
ulLen = sizeof(MSG)-1;
char szBuf[16];
sprintf( szBuf, "%lu", ulLen );
PIDB_replace( tPIHTTP.pResponseDB, PIDBTYPE_RFC822,
KEY_HTTP_CONTENTLENGTH, szBuf, 0 );
PIIOBuffer_write( tPIHTTP.pBuffer, MSG, ulLen, PIIOBUF_NONE );
PIIOBuffer_flush( tPIHTTP.pBuffer );
#undef MSG
}
break;
case PIAPI_ERROR:
if (iBehavior == PHP_MODE_LINT)
{
#define MSG "\
<BODY BGCOLOR=\"#FFFFFF\" BACKGROUND=\"/icons/Pi3Tile.gif\">\
<H2>PHP4 Syntax error</H2>\
The syntax check for the called PHP4 resource failed.</BODY>"
unsigned long ulLen = sizeof(MSG)-1;
char szBuf[16];
sprintf( szBuf, "%lu", ulLen );
PIDB_replace( tPIHTTP.pResponseDB, PIDBTYPE_RFC822,
KEY_HTTP_CONTENTLENGTH, szBuf, 0 );
PIIOBuffer_write( tPIHTTP.pBuffer, MSG, ulLen, PIIOBUF_NONE );
PIIOBuffer_flush( tPIHTTP.pBuffer );
#undef MSG
}
else
{
HTTPCore_logError( &tPIHTTP, "PHP4: Script wrapper with path %s \
returned with a general error.", pPath );
};
break;
default:
HTTPCore_logError( &tPIHTTP, "PHP4: Script wrapper with path %s \
returned an unknown code.", pPath );
};
return tContext.iRc;
};
BOOL GetServerVariable( PIHTTP *pPIHTTP, LPSTR lpszVariableName,
LPVOID lpvBuffer, LPDWORD lpdwSize )
{
if ( !lpszVariableName || !lpdwSize )
{
PIPlatform_setLastError( PIAPI_EINVAL );
return PIAPI_FALSE;
};
/* ---
Convert variable to upper case
--- */
PIString sTmp( lpszVariableName );
sTmp.ConvertToUpperCase();
/* ---
Lookup function corresponding to this environment variable
--- */
PMFN fnEnv = (PMFN)PIDB_lookup( pTypes, PIDBTYPE_OPAQUE, sTmp, 0 );
/* ---
No lookup function?
--- */
if ( !fnEnv )
{
PIPlatform_setLastError( PIAPI_EINVAL );
return PIAPI_FALSE;
};
return (fnEnv)( this, pPIHTTP, lpvBuffer, lpdwSize );
};
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
BOOL fnGetServerVariable( HCONN hConn, LPSTR lpszVariableName,
LPVOID lpvBuffer, LPDWORD lpdwSize )
{
PHP4Context *pContext = (PHP4Context *)hConn;
int iRet = pContext->pPHP4->GetServerVariable( pContext->pPIHTTP,
lpszVariableName, lpvBuffer, lpdwSize );
if ( HTTPCore_debugEnabled() )
{
HTTPCore_logDebug( DBG_MED, "PHP4: Return code<%d>, variable<%s>, \
value<%x>, size<%d>.",
iRet, lpszVariableName ? lpszVariableName : "",
(void *)lpvBuffer, lpdwSize ? *lpdwSize : 0 );
};
return iRet;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
BOOL fnWriteClient( HCONN ConnID, LPVOID Buffer, LPDWORD lpdwBytes,
DWORD dwReserved )
{
if ( !ConnID || !lpdwBytes || !Buffer )
{
PIPlatform_setLastError( PIAPI_EINVAL );
return PIAPI_FALSE;
};
PHP4Context *pContext = (PHP4Context *)ConnID;
int iWritten = PIIOBuffer_write( pContext->pPIHTTP->pBuffer,
(char *)Buffer, *lpdwBytes, PIIOBUF_NONE );
if ( iWritten==-1 )
{
/*
** Socket must have been closed
*/
PIPlatform_setLastError( PIAPI_EINVAL );
return PIAPI_FALSE;
};
*lpdwBytes = iWritten;
return PIAPI_TRUE;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
BOOL fnReadClient( HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize )
{
if ( !ConnID || !lpdwSize )
{
PIPlatform_setLastError( PIAPI_EINVAL );
return PIAPI_FALSE;
};
PHP4Context *pContext = (PHP4Context *)ConnID;
int iRet = PIIOBuffer_readToBuffer( pContext->pPIHTTP->pBuffer,
(char *)lpvBuffer, *lpdwSize );
if ( iRet>0 )
{
*lpdwSize = iRet;
return PIAPI_TRUE;
}
else
{
return PIAPI_FALSE;
};
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
BOOL fnSendHeaderFunction( HCONN ConnID, LPDWORD lpdwSize, LPDWORD lpdwDataType )
{
if ( !ConnID )
{
PIPlatform_setLastError( PIAPI_EINVAL );
return PIAPI_FALSE;
};
PHP4Context *pContext = (PHP4Context *)ConnID;
PIHTTP *pPIHTTP = pContext->pPIHTTP;
// switch( pContext->dwHttpStatusCode )
// {
// case ST_PERMANENTREDIRECT:
// case 302:
// PIDB_replace( pPIHTTP->pResponseDB, PIDBTYPE_RFC822,
// KEY_HTTP_LOCATION, (void *)"302", 0 );
// pContext->dwHttpStatusCode = ST_PERMANENTREDIRECT;
// pContext->iRc = PIAPI_COMPLETED;
// return PIAPI_TRUE;
// default:
/*
** Assume Content-Length could not be set, disable keep open
*/
PIDB_replace( pPIHTTP->pConnectionDB, PIDBTYPE_OPAQUE,
KEY_INT_KEEPOPEN, 0, 0 );
pPIHTTP->iStatus = pContext->dwHttpStatusCode;
pContext->iRc = PIAPI_COMPLETED;
/*
** Send server specific headers
*/
if ( HTTPCore_sendGeneralHeaders( pPIHTTP ) != PIAPI_COMPLETED )
{
return PIAPI_FALSE;
}
if ( lpdwSize && *lpdwSize && lpdwDataType )
{
if ( PIIOBuffer_write( pPIHTTP->pBuffer, (const char *)lpdwDataType,
*lpdwSize, PIIOBUF_NONE ) != *lpdwSize ) return PIAPI_FALSE;
};
return PIAPI_TRUE;
// };
// return PIAPI_FALSE;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int PHP4_constructor( PIObject *pObj,
int iArgc, const char *ppArgv[] )
{
return HandlerBasePHP4_constructor( pObj, PI_NEW( PHP4( pObj,
iArgc, ppArgv ) ) );
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int PHP4_destructor( PIObject *pObj, int,
const char *[] )
{
delete (PHP4 *)PIObject_getUserData( pObj );
return PIAPI_COMPLETED;
}
#if 0
/*___+++CNF_BEGIN+++___*/
<Class>
Name PHP4Class
Type LogicExtension
Library PHP4Wrapper
OnClassLoad HandlerBasePHP4_onClassLoad
Constructor PHP4_constructor
CopyConstructor HandlerBasePHP4_copyConstructor
Destructor PHP4_destructor
Execute HandlerBasePHP4_execute
</Class>
<Object>
Name PHP4
Class PHP4Class
ExtraHeadersPrefix "HTTP_"
# PHPMode "Highlight"
</Object>
/*___+++CNF_END+++___*/
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?