php4handler.cpp

来自「mini http server,可以集成嵌入到程序中,实现简单的web功能」· C++ 代码 · 共 908 行 · 第 1/2 页

CPP
908
字号
/*____________________________________________________________________________*\
 *

 Copyright (c) 1999 Holger Zimmermann, John Roy. All rights reserved.

 These sources, libraries and applications are
 FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
 as long as the following conditions are adhered to.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer. 

 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution.

 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission. 

 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHORS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.

 *____________________________________________________________________________*|
 *
 * $Source: /cvsroot/pi3web/Pi3Web_200/Source/PHP4/PHP4Handler.cpp,v $
 * $Date: 2003/05/13 18:42:08 $
 *
 Description:
	Execute an PHP4 script.

\*____________________________________________________________________________*/
//$SourceTop:$

#include <iostream.h>
#include <stdio.h>
#if WIN32
#include <windows.h>
#else
#include <ctype.h>
#endif

#include "pi3web_sapi.h"

#include "HandBase.h"
#include "HTTPCore.h"
#include "HTTPUtil.h"
#include "PIStrStr.h"
#include "DeQuote.h"
#include "Base64.h"


/*____________________________________________________________________________*\
 *
 Description:
\*____________________________________________________________________________*/
#define KEY_CONF_EXTRAHDRPREFIX		"ExtraHeadersPrefix"
#define KEY_CONF_BEHAVIOR			"PHPMode"

/*
** #define D { cerr << __FILE__ << ": " << __LINE__ << endl; }
*/
#define D

/*____________________________________________________________________________*\
 *
 Description:
\*____________________________________________________________________________*/
#if 0
	/*
	** HTML documentation for this handler
	*/
/*___+++HTMLDOC_BEGIN+++___*/
Name:
	PHP4

Description:
	Wrapper for the PHP4 embedded script interpreter.

</PRE>
	The PHP4 Pi3 component is implemented using PHP4 Core Web Server API
	(SAPI), thus -
<PRE>
   &quot;This product includes software written by the PHP Development Team.&quot;
</PRE>

Options:

<TABLE BORDER=1>
<TH>Option
<TH>Default
<TH>Values
<TH>Short Description
<TH>Example(s)

<TR>
<TD>ExtraHeadersPrefix
<TD>-
<TD>"HTTP_"
<TD>Prefix for HTTP extra request headers
<TD>ExtraHeadersPrefix "HTTP_"

<TR>
<TD>PHPMode
<TD>-
<TD>Either "Standard", "Highlight",  "Indent" or "SyntaxCheck"
<TD>Switch PHP to intended or highlight mode
<TD>PHPMode "Highlight"

</TABLE>
<STRONG>-</STRONG> in the <IT>default</IT> indicates no default<BR>
<STRONG>+</STRONG> in the <IT>default</IT> indicates the field is mandatory<BR>

<H4>Description of Options</H4>
<H5>ExtraHeadersPrefix</H5>
The value is added before any HTTP extra header. The request header "User-Agent ..."
i.e. will generate a server variable "HTTP_USER-AGENT".

<H5>PHPMode</H5>
This value is used as a flag to control the general behaviour of PHP. The flag
is optional.
<ul>
<li><i>Standard:</i> If the <i>PHPMode</i> option is omitted, the <i>Standard</i>
mode is assumed and the script will be parsed as usual.
<li><i>Highlight:</i> In this mode the syntax highlighted source code will be send
to the client. The highlight colors are adjusted in <i>php.ini</i>.
<li><i>Indent:</i> The script source code is printed plain but with correct intended
lines.
<li><i>SyntaxCheck:</i> The script is only parsed for syntax errors and the result is
written to the client.
</ul>

Phase:
	HANDLE

Returns:
	PIAPI_COMPLETED, PIAPI_CONTINUE, PIAPI_ERROR, or INT_REDIRECT according
	to the status returned by the interpreter.

Note:
	This handler requires php4ts.dll 4.04 or greater from the PHP4 Win32 binary
      distribution.

<H5>PHP4 extensions</H5>
	The following PHP4 extensions are included in the PHP4-module:
	calendar
	crypt
	dbase
	filepro
	gd
	imap
	ldap
	msql
	mssql
	mysql
	odbc
	standard
	zlib
<H5>Server variables</H5>
	The following server variables are supported. "ALL_HTTP" will hold all
	request headers except of the values stored in other server variables.
	<P>AUTH_TYPE<BR>
	CONTENT_LENGTH<BR>
	CONTENT_TYPE<BR>
	GATEWAY_INTERFACE<BR>
	PATH_INFO<BR>
	PATH_TRANSLATED<BR>
	QUERY_STRING<BR>
	REQUEST_METHOD<BR>
	REMOTE_ADDR<BR>
	REMOTE_HOST<BR>
	REMOTE_USER<BR>
	SCRIPT_NAME<BR>
	SERVER_NAME<BR>
	SERVER_PORT<BR>
	SERVER_PROTOCOL<BR>
	SERVER_SOFTWARE<BR>
	ALL_HTTP


Example:
	<PRE>
	&lt;Object&gt;
		Name PHP4
		Class PHP4Class
	&lt;/Object&gt;

	&lt;Object&gt;
		...
		Handle Condition="&cmp($c,text/x-php3)" PHP4
		...
	&lt;/Object&gt;

	</PRE>

/*___+++HTMLDOC_END+++___*/
#endif

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Prototypes for callback functions
\*____________________________________________________________________________*/

BOOL fnGetServerVariable( HCONN hConn,
					LPSTR	lpszVariableName,
					LPVOID	lpvBuffer,
					LPDWORD	lpdwSize );

BOOL fnWriteClient( HCONN ConnID,
					LPVOID	Buffer,
					LPDWORD	lpdwBytes,
					DWORD	dwReserved );

BOOL fnReadClient( HCONN ConnID,
					LPVOID	lpvBuffer,
					LPDWORD	lpdwSize );

BOOL fnSendHeaderFunction( HCONN hConn,
					LPDWORD	lpdwSize,
					LPDWORD	lpdwDataType );

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	structure for PHP4 parameter mapping
\*____________________________________________________________________________*/
struct {
	const char *pName;
	int iFlag;
} aFlagMap[] =
	{
	{ "Standard",		PHP_MODE_STANDARD },
	{ "Highlight",		PHP_MODE_HIGHLIGHT },
	{ "Indent",			PHP_MODE_INDENT },
	{ "SyntaxCheck",	PHP_MODE_LINT },

	/* --- leave this last always --- */
	{ 0, 0 }
	};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Class for PHP4 context
\*____________________________________________________________________________*/
class PHP4;
class PHP4Context : public CONTROL_BLOCK
{
public:
	PHP4 *pPHP4;
	PIHTTP *pPIHTTP;
	int iRc;
private:
	inline char *DBL( PIDB *pDB, int iType, const char *pKey )
		{
		return (char *)PIDB_lookup( pDB, iType, pKey, 0 );
		};
	inline int SetAuth( PIHTTP *pPIHTTP)
		{
		/* --- test if remote_user already exists --- */
		const char *pAuthenticate  = DBL( pPIHTTP->pResponseDB, PIDBTYPE_STRING,
			KEY_INT_REMOTEUSER );
		/* --- if Pi3Web has already done basic auth stuff --- */
		if ( pAuthenticate ) return PIAPI_COMPLETED;
		/* --- Get browser authentication string --- */
		pAuthenticate = DBL( pPIHTTP->pRequestDB, PIDBTYPE_RFC822,
			KEY_HTTP_AUTHORIZATION );
		if ( pAuthenticate )
			{
			/* --- Check authentication string --- */
			if ( !strncmp( pAuthenticate, "Basic ", 6 ) )
				{
				PIDB_replace( pPIHTTP->pResponseDB, PIDBTYPE_STRING,
					KEY_INT_AUTHTYPE, (void *)"Basic", 0 );

				/* --- base64 decoding stuff --- */
				const char *pBase64 = &( pAuthenticate[6] );
				char auth[256];
				Base64Decode( pBase64, auth, sizeof( auth ));
				/* --- split of authentication token --- */
				char *tok = strtok( auth, ":" );
				if ( tok != NULL )
					{
					PIDB_replace( pPIHTTP->pResponseDB, PIDBTYPE_STRING,
						KEY_INT_REMOTEUSER, tok, 0 );
					tok = strtok( NULL, ":" );
					if ( tok != NULL )
						{
						PIDB_replace( pPIHTTP->pResponseDB, PIDBTYPE_STRING,
							KEY_INT_AUTHPASS, tok, 0 );
						};
					};
				};
			};
			return PIAPI_COMPLETED;
		};
public:
	PHP4Context( PHP4 *pThePHP4, PIHTTP *pThePIHTTP, int iBehavior )
	:	pPHP4( pThePHP4 ), pPIHTTP( pThePIHTTP ), iRc( PIAPI_COMPLETED )
		{
		/* --- locals --- */
		PIDB *pQ = pPIHTTP->pRequestDB;
		PIDB *pR = pPIHTTP->pResponseDB;

		/* --- initialize member data --- */
		cbSize = sizeof( CONTROL_BLOCK );
		ConnID = (HCONN)this;
		dwHttpStatusCode = 0;
		*lpszLogData = '\0';

		/* --- input variables --- */
		lpszMethod = DBL( pQ, PIDBTYPE_STRING, KEY_HTTP_METHOD );
		lpszQueryString = DBL( pQ, PIDBTYPE_STRING, KEY_HTTP_QUERYSTRING );
		lpszPathInfo = DBL( pR, PIDBTYPE_STRING, KEY_INT_PATHINFO );
		lpszPathTranslated = DBL( pR, PIDBTYPE_STRING, KEY_INT_PATHTRANSLATED );
		lpszUri = DBL( pQ, PIDBTYPE_STRING, KEY_HTTP_URI );
		lpszReq = DBL( pQ, PIDBTYPE_STRING, KEY_HTTP_CLF );
		lpszFileName = DBL( pR, PIDBTYPE_STRING, KEY_INT_PATH );
		lpszContentType = DBL( pQ, PIDBTYPE_RFC822, KEY_HTTP_CONTENTTYPE );
		dwBehavior = iBehavior;

		/* --- get user/passwd for basic auth with php --- */
		SetAuth( pPIHTTP );
		lpszUser = DBL( pR, PIDBTYPE_STRING, KEY_INT_REMOTEUSER );
		lpszPassword = DBL( pR, PIDBTYPE_STRING, KEY_INT_AUTHPASS );

		/* --- check for stdin --- */
		cbAvailable = 0;
		lpbData = NULL;
		cbTotalBytes = 0;
		const char *pContentLength = DBL( pQ, PIDBTYPE_RFC822,
			KEY_HTTP_CONTENTLENGTH );
		cbTotalBytes = pContentLength && pContentLength[0] ? atol( pContentLength ) : 0;

		/* --- callback functions --- */
		GetServerVariable = fnGetServerVariable;
		WriteClient = fnWriteClient;
		ReadClient = fnReadClient;
		SendHeaderFunction = fnSendHeaderFunction;
		};
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class PHP4 : public HandlerBasePHP4
{
private:
	/* ---
	Configuration data
	--- */
	PIDB *pTypes;					/* DB for variable types */
   	PIString sExtraHeadersPrefix;	/* Extra Header for environment values, */
									/* by default "HTTP_" */
	int iBehavior;					/* PHP4 mode */
protected:
	/* ---
	Lookup functions (for GetServerVariable)
	--- */
	typedef BOOL (* PMFN)( PHP4 *pThis, PIHTTP *, LPVOID, LPDWORD );

	static BOOL fnAllHttp( PHP4 *pThis, PIHTTP *pPIHTTP,  char *lpvBuffer, LPDWORD lpdwSize )													
		{																		
		PIDB *pQ = pPIHTTP->pRequestDB;											
		int i = 0;																
		/* --- loop over all RFC822 headers in request block --- */				
		PIDBIterator *pIter = PIDB_getIterator( pQ, PIDBTYPE_RFC822, 0, 0 );	
		if ( !pIter )															
			{
				*lpdwSize = 0;
				PIPlatform_setLastError(PIAPI_INTERNALERROR);
				return -1;
			};														
		for(; PIDBIterator_atValidElement( pIter ); PIDBIterator_next( pIter ) )
			{																
			const char *pKey;													
			const char *pValue = (const char *)PIDBIterator_current( pIter,	&pKey );
			assert( pKey && pValue );											

			if ( !pKey || !pValue )												
				{ /* sanity */ continue; };										

			PMFN fnEnv = (PMFN)PIDB_lookup( pThis->pTypes, PIDBTYPE_OPAQUE, pKey, 0 );
			if ( fnEnv ) { continue; };

			int iVarLen = strlen( pKey );										
			int iVarPos = pThis->sExtraHeadersPrefix.Len();								
			int iValSize = strlen( pValue );									

			if ( (iVarPos+iValSize+i+3) < *lpdwSize )							
				{																
				memcpy( &(lpvBuffer[i]), pThis->sExtraHeadersPrefix, iVarPos );
				i += iVarPos;
				for( int j=0; j<iVarLen; j++, i++ )							
					{																
					if ( isalnum( pKey[j] ) )										
						{ lpvBuffer[i]=toupper(pKey[j]); }						
					else															
						{ lpvBuffer[i]='_'; };									
					};
				lpvBuffer[i++] = ':';
				lpvBuffer[i++] = ' ';
				memcpy( &(lpvBuffer[i]), pValue, iValSize ); i+=iValSize;		
				lpvBuffer[i++] = '\n';											
				}																
			else																
				{																
				PIDBIterator_delete( pIter );									
				*lpdwSize = 0;
				PIPlatform_setLastError(PIAPI_EINVAL);
				return PIAPI_FALSE;													
				};																
			};
		PIDBIterator_delete( pIter );
		*lpdwSize = i;
		return PIAPI_TRUE;															
		};

# define FN_DB_STR( name, db, type, key ) \
	static BOOL (name)( PHP4 *, PIHTTP *pPIHTTP, LPVOID lpvBuffer,		\
			LPDWORD lpdwSize )											\
		{																\
		const char *pValue = (const char *)PIDB_lookup( pPIHTTP->db,	\
			type, key, 0 );												\
		if ( !pValue )													\
			{															\
			pValue = ""; 												\
			};															\
		int iToCopy = strlen( pValue ) + 1;								\
		if ( DWORD(iToCopy)>*lpdwSize || !lpvBuffer )					\
			{															\
			*lpdwSize = iToCopy;										\
			PIPlatform_setLastError( PIAPI_EINVAL );					\
			return PIAPI_FALSE;											\
			};															\

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?