Example #1
0
/**
*	_getOptionArgs
*
*		Returns the address of an OPTIONS struct with all supported options decoded. 
*		Two types of optional parameters are supported, that is, 'queryOptions' and
*		'options'.
*
*			query-options	:== 'queryOptions' '=' '{' (object (',' object)*))? '}'
*			options			:== 'options' '=' '[' (string (',' string)*)? ']'
*			object			:== '{' (property (',' property)*)? '}'
*			property		:== string ':' value
*			array			:== '[' (value (',' value)*)? ']'
*			value			:== string | number | object | array | 'true' | 'false'
*			string			:== '"' char* '"'
*
*		Example:
*
*			queryOptions={"deep":true, "ignoreCase":false}
*			options=["dirsOnly", "showHiddenFiles"]
*
*	@note:	Strict JSON encoding rules are enforced when decoding parameters.
*
*	@param	pGET			Address of a variable data type. (php style $_GET variable)
*	@param	piResult		Address integer receiving the final result code:
*							HTTP_V_OK, HTTP_V_BAD_REQUEST or HTTP_V_SERVER_ERROR
*
*	@return		On success the address of an OPTIONS struct otherwise NULL
**/
static OPTIONS * _getOptionArgs( DATA *pGET, int *piResult )
{
	OPTIONS	*pOptions;
	DATA	*ptQueryOptions,
			*ptOptions;
			
	if( (pOptions = (OPTIONS *)calloc(1, sizeof(OPTIONS))) )
	{
		if( hasProperty( "options", pGET ) )
		{
			if( (ptOptions = jsonDecode( varGetProperty("options", pGET))) )
			{
				pOptions->bShowHiddenFiles = varInArray("showHiddenFiles", ptOptions);
				pOptions->bDebug		   = varInArray("debug", ptOptions);

				destroy( ptOptions );
			}
			else // Ill formatted JSON array
			{
				cbtDebug( "options parameter is not a valid JSON object." );
				*piResult = HTTP_V_BAD_REQUEST;
				destroy( pOptions );
				return NULL;
			}
		}

		if( hasProperty( "queryOptions", pGET ) )
		{
			if( (ptQueryOptions = jsonDecode( varGetProperty("queryOptions", pGET))) )
			{
				pOptions->bIgnoreCase = (bool)varGet( varGetProperty("ignoreCase", ptQueryOptions) );
				pOptions->bDeep		  = (bool)varGet( varGetProperty("deep", ptQueryOptions) );
				destroy( ptQueryOptions );
			}
			else // Ill formatted JSON object
			{
				cbtDebug( "queryOptions parameter is not a valid JSON object." );
				*piResult = HTTP_V_BAD_REQUEST;
				destroy( pOptions );
				return NULL;
			}
		}
		*piResult = HTTP_V_OK;	// Success
	}
	else // Out of memory...
	{
		*piResult = HTTP_V_SERVER_ERROR;
	}
	return pOptions;
}
Example #2
0
bool Debugger::Cmd_Var(int argc, const char **argv) {
	switch (argc) {
	case 2:
		varGet(atoi(argv[1]));
		break;
	case 3:
		varSet(atoi(argv[1]), atoi(argv[2]));
		break;
	default:
		DebugPrintf("Usage: %s number value\n", argv[0]);
		break;
	}

	return true;
}
Example #3
0
/**
*	cgiInit
*
*		Load the available CGI variables and create the PHP style _SERVER and _GET
*		dynamic variables. Both variables are created as associative arrays.
**/
int cgiInit()
{
	METHOD	*pMethod;
	DATA	*ptContent,
			*ptQuery,
			*ptArgs,
			*ptSERVER,
			*ptCBTREE,
			*ptGET,
			*ptPOST;
	char	cProperty[MAX_BUF_SIZE],
			cValue[MAX_BUF_SIZE],
			cArgm[MAX_BUF_SIZE],
			*pcAllowed,
			*pcSrc,
			*pcArgm;
	int		iArgCount,
			iSep,
			i;
	
	phResp = stdout;
	
	cgiEnvironment = newArray(NULL);

	// Setup a PHP style '$_SERVER' variable.
	if( (ptSERVER = newArray( "_SERVER" )) )
	{
		for( i=0; cgiVarNames[i]; i++)
		{
			varNewProperty( cgiVarNames[i],  getenv(cgiVarNames[i]), ptSERVER );
		}
		varPush( cgiEnvironment, ptSERVER );
	}

	/**
	*	 Setup a PHP style '$_CBTREE' variable.
	*
	*	NOTE:	On Apache HTTP servers any non CGI variables must be passed explicitly
	*			using the 'SetEnv' or 'PassEnv' directive. For example in httpd.conf
	*			add:
	*
	*				PassEnv CBTREE_METHODS
	**/
	if( (ptCBTREE = newArray( "_CBTREE" )) )
	{
		for( i=0; cgiCbtreeNames[i]; i++)
		{
			varNewProperty( cgiCbtreeNames[i],  getenv(cgiCbtreeNames[i]), ptCBTREE );
		}
		varPush( cgiEnvironment, ptCBTREE );
	}
	
#ifdef _DEBUG
	varSet( cgiGetProperty("QUERY_STRING"), cDbgQS );
#endif

	switch( cgiGetMethodId() )
	{
		case HTTP_V_DELETE:
		case HTTP_V_GET:
			if( (ptGET = newArray( "_GET" )) )
			{
				if( (ptQuery = cgiGetProperty("QUERY_STRING")) )
				{
					// Get the list of HTTP query arguments as a new array.
					ptArgs = varSplit( ptQuery, "&", false );
					ptGET  = newArray( "_GET" );
					if( (iArgCount = varCount( ptArgs )) )
					{
						for( i=0; i < iArgCount; i++ )
						{
							if( (pcArgm = varGet(varGetByIndex( i, ptArgs ))) )
							{
								// Decode special characters and treat each argument as a new property.
								pcSrc  = decodeURI( pcArgm, cArgm, sizeof(cArgm)-1 );
								iSep   = strcspn( pcSrc, "=" );
								strncpyz( cProperty, pcSrc, iSep );
								pcSrc += pcSrc[iSep] ? iSep + 1: iSep;
								strcpy( cValue, pcSrc );
								
								varNewProperty( cProperty, cValue, ptGET );
							}
						}
					}
					destroy( ptArgs );
				}
				varPush( cgiEnvironment, ptGET );
			}
			break;
			
		case HTTP_V_POST:
			if( (ptPOST = newArray( "_POST" )) )
			{
				// Read the content from stdin
				if( fgets(cArgm, sizeof(cArgm)-1, stdin) )
				{
					ptContent = newString( "CONTENT", cArgm );
					ptArgs	  = varSplit( ptContent, "&", false );
					if( (iArgCount = varCount( ptArgs )) )
					{
						for( i=0; i < iArgCount; i++ )
						{
							if( (pcArgm = varGet(varGetByIndex( i, ptArgs ))) )
							{
								// Decode special characters and treat each argument as a new property.
								pcSrc  = decodeURI( pcArgm, cArgm, sizeof(cArgm)-1 );
								iSep   = strcspn( pcSrc, "=" );
								strncpyz( cProperty, pcSrc, iSep );
								pcSrc += pcSrc[iSep] ? iSep + 1: iSep;
								strcpy( cValue, pcSrc );
								
								varNewProperty( cProperty, cValue, ptPOST );
							}
						}
					}
					destroy( ptArgs );
				}
				varPush( cgiEnvironment, ptPOST );
			}
			break;
	}
	// Define which HTTP methods are allowed.
	if( ptCBTREE )
	{
		pcAllowed = varGet(varGetProperty("CBTREE_METHODS", ptCBTREE));
		snprintf( cProperty, sizeof(cProperty)-1,"GET,%s", (pcAllowed ? pcAllowed : "") );
		pcArgm = strtok( cProperty, ", " );
		while( pcArgm )
		{
			strtrim( pcArgm, TRIM_M_WSP );
			if( *pcArgm )
			{
				if( (pMethod = _cgiGetMethodByName( pcArgm )) )
				{
					pMethod->bAllowed = true;
				}
			}
			pcArgm = strtok( NULL, ", " );
		}
	}
	return 1;
}
Example #4
0
/**
*	getArguments
*
*		Returns the address of an ARGS struct with all HTTP query string parameters
*		extracted and decoded. The query string parameters (args) supported are:
*
*			query-string  ::= (qs-param ('&' qs-param)*)?
*			qs-param	  ::= authToken | basePath | path | query | queryOptions | options | 
*							  start | count |sort
*			authToken	  ::= 'authToken' '=' json-object
*			basePath	  ::= 'basePath' '=' path-rfc3986
*			path		  ::= 'path' '=' path-rfc3986
*			query		  ::= 'query' '=' object
*			query-options ::= 'queryOptions' '=' object
*			options		  ::= 'options' '=' array
*			start		  ::= 'start' '=' number
*			count		  ::= 'count' '=' number
*			sort		  ::= 'sort' '=' array
*
*	@note:	All of the above parameters are optional.
*
*	@param	piResult		Address integer receiving the final result code:
*							HTTP_V_OK, HTTP_V_BAD_REQUEST or HTTP_V_SERVER_ERROR
*
*	@return		On success the address of an ARGS struct otherwise NULL
**/
ARGS *getArguments( int *piResult )
{
	ARGS	*pArgs;
	DATA	*pCBTREE = NULL;
	DATA	*ptARGS = NULL,
			*ptArg;
	int		iResult = HTTP_V_OK;	// Assume success
	
	if( (pArgs = (ARGS *)calloc(1, sizeof(ARGS))) )
	{
		pCBTREE = cgiGetProperty("_CBTREE");	// Get CBTREE environment variables.
		switch( cgiGetMethodId() ) 
		{
			case HTTP_V_DELETE:
				if( (ptARGS = cgiGetProperty( "_GET" )) )
				{
					if( !hasProperty("path", ptARGS) )
					{
						iResult = HTTP_V_BAD_REQUEST;
					}
				}
				pArgs->pOptions = _getOptionArgs( NULL, &iResult ); 
				break;
				
			case HTTP_V_GET:
				if( (ptARGS = cgiGetProperty( "_GET" )) )
				{
					// Parse the general options, if any..
					if( !(pArgs->pOptions = _getOptionArgs( ptARGS, &iResult )) )
					{
						destroyArguments( &pArgs );
						return NULL;
					}
				}
				else // No QUERY-STRING
				{
					// We need at least an empty options struct.
					pArgs->pOptions = _getOptionArgs( NULL, &iResult ); 
				}
				break;

			case HTTP_V_POST:
				if( (ptARGS = cgiGetProperty( "_POST" )) )
				{
					if( hasProperty("newValue", ptARGS) &&
						hasProperty("path", ptARGS) )
					{
						ptArg = varGetProperty("newValue", ptARGS);
						if( isString(ptArg) )
						{
							pArgs->pcNewValue = varGet( ptArg );
						}
						else
						{
							iResult = HTTP_V_BAD_REQUEST;
						}
					}
					else // Missing parameter
					{
						iResult = HTTP_V_BAD_REQUEST;
					}
				}
				else // _POST is missing
				{
					iResult = HTTP_V_BAD_REQUEST;
				}
				pArgs->pOptions = _getOptionArgs( NULL, &iResult ); 
				break;
		}

		if( iResult == HTTP_V_OK )
		{		
			// Get and validate the basePath if any.
			pArgs->pcBasePath = varGet(varGetProperty("CBTREE_BASEPATH", pCBTREE));
			if( !pArgs->pcBasePath )
			{
				if((ptArg = varGetProperty("basePath", ptARGS)) )
				{
					if( isString(ptArg) )
					{
						pArgs->pcBasePath = varGet( ptArg );
					}
					else
					{
						iResult = HTTP_V_BAD_REQUEST;
					}
				}
			}
			// Validate the path if any.
			if( (ptArg = varGetProperty("path", ptARGS)) )
			{
				if( isString(ptArg) )
				{
					pArgs->pcPath = varGet( ptArg );
				}
				else
				{
					iResult = HTTP_V_BAD_REQUEST;
				}
			}
			if( hasProperty( "authToken", ptARGS ) )
			{
				if( (ptArg = jsonDecode(varGetProperty("authToken", ptARGS))) && isObject(ptArg) )
				{
					pArgs->pAuthToken = ptArg;
				}
				else
				{
					cbtDebug( "authToken parameter is not a valid JSON object" );
					iResult = HTTP_V_BAD_REQUEST;
				}
			}
		}
		if( iResult != HTTP_V_OK )
		{
			destroyArguments( &pArgs );
			*piResult = iResult;
			return NULL;
		}
		*piResult = HTTP_V_OK;

	}
	else  // Out of memory
	{
		*piResult = HTTP_V_SERVER_ERROR;
	}
	return pArgs;
}