mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 23:00:56 +01:00
2f1333a116
server sends HTTP status "400 Bad Request" with JSON payload with "error" and "errno" attributes. error is json_last_error_msg() prefixed with "JSON ". Not yet implemented is resending the request (max. twice) for JSON parsing errors to try to work around network problems
142 lines
4.6 KiB
PHP
142 lines
4.6 KiB
PHP
<?php
|
|
/**
|
|
* EGroupware - general JSON handler for EGroupware
|
|
*
|
|
* @link http://www.egroupware.org
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
* @package api
|
|
* @subpackage ajax
|
|
* @author Andreas Stoeckel <as@stylite.de>
|
|
*/
|
|
|
|
use EGroupware\Api;
|
|
use EGroupware\Api\Egw;
|
|
use EGroupware\Api\Json;
|
|
|
|
/**
|
|
* callback if the session-check fails, redirects to login.php, if no valid basic auth credentials given
|
|
*
|
|
* @param array &$anon_account anon account_info with keys 'login', 'passwd' and optional 'passwd_type'
|
|
* @return boolean|string true if we allow anon access and anon_account is set, a sessionid or false otherwise
|
|
*/
|
|
function login_redirect(&$anon_account)
|
|
{
|
|
// allow to make json calls via basic auth
|
|
if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW']) &&
|
|
($session_id = Api\Header\Authenticate::autocreate_session_callback($anon_account)))
|
|
{
|
|
return $session_id;
|
|
}
|
|
Json\Request::isJSONRequest(true); // because Api\Json\Request::parseRequest() is not (yet) called
|
|
$response = Json\Response::get();
|
|
$response->redirect($GLOBALS['egw_info']['server']['webserver_url'].'/login.php?cd=10', true);
|
|
|
|
exit();
|
|
}
|
|
|
|
/**
|
|
* Exception handler for xajax, return the message (and trace, if enabled) as alert() to the user
|
|
*
|
|
* Does NOT return!
|
|
*
|
|
* @param Exception|Error $e
|
|
*/
|
|
function ajax_exception_handler($e)
|
|
{
|
|
// handle redirects without logging
|
|
if (is_a($e, 'EGroupware\\Api\\Exception\\Redirect'))
|
|
{
|
|
Egw::redirect($e->url, $e->app);
|
|
}
|
|
// logging all exceptions to the error_log
|
|
$message = null;
|
|
if (function_exists('_egw_log_exception'))
|
|
{
|
|
_egw_log_exception($e,$message);
|
|
}
|
|
$response = Json\Response::get();
|
|
$message .= ($message ? "\n\n" : '').$e->getMessage();
|
|
|
|
// only show trace (incl. function arguments) if explicitly enabled, eg. on a development system
|
|
if ($GLOBALS['egw_info']['server']['exception_show_trace'])
|
|
{
|
|
$message .= "\n\n".$e->getTraceAsString();
|
|
}
|
|
$response->alert($message);
|
|
|
|
exit;
|
|
}
|
|
|
|
// set our own exception handler, to not get the html from eGW's default one
|
|
set_exception_handler('ajax_exception_handler');
|
|
|
|
try {
|
|
if (!isset($_GET['menuaction']))
|
|
{
|
|
throw new InvalidArgumentException('Missing menuaction GET parameter', 998);
|
|
}
|
|
if (strpos($_GET['menuaction'],'::') !== false && strpos($_GET['menuaction'],'.') === false) // static method name app_something::method
|
|
{
|
|
@list($className,$functionName,$handler) = explode('::',$_GET['menuaction']);
|
|
|
|
if (substr($className, 0, 11) == 'EGroupware\\')
|
|
{
|
|
list(,$appName) = explode('\\', strtolower($className));
|
|
}
|
|
else
|
|
{
|
|
list($appName) = explode('_',$className);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
@list($appName, $className, $functionName, $handler) = explode('.',$_GET['menuaction']);
|
|
}
|
|
//error_log("json.php: appName=$appName, className=$className, functionName=$functionName, handler=$handler");
|
|
|
|
$GLOBALS['egw_info'] = array(
|
|
'flags' => array(
|
|
'currentapp' => $appName,
|
|
'noheader' => True,
|
|
'disable_Template_class' => True,
|
|
'autocreate_session_callback' => 'login_redirect',
|
|
'no_exception_handler' => true, // we already installed our own
|
|
// only log ajax requests which represent former GET requests or submits
|
|
// cuts down updates to egw_access_log table
|
|
'no_dla_update' => !preg_match('/(Etemplate::ajax_process_content|\.jdots_framework\.ajax_exec\.template)$/', $_GET['menuaction']),
|
|
)
|
|
);
|
|
include_once('./header.inc.php');
|
|
|
|
|
|
//Create a new json handler
|
|
$json = new Json\Request();
|
|
|
|
//Check whether the request data is set
|
|
if (isset($GLOBALS['egw_unset_vars']['_POST[json_data]']))
|
|
{
|
|
$json->isJSONRequest(true); // otherwise exception is not send back to client, as we have not yet called parseRequest()
|
|
throw new Json\Exception\ScriptTags("JSON Data contains script tags. Aborting...");
|
|
}
|
|
// check if we have a real json request
|
|
if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') === 0)
|
|
{
|
|
$json->parseRequest($_GET['menuaction'], file_get_contents('php://input'));
|
|
}
|
|
else
|
|
{
|
|
$json->parseRequest($_GET['menuaction'], $_REQUEST['json_data']);
|
|
}
|
|
Json\Response::get();
|
|
exit();
|
|
}
|
|
// missing menuaction GET parameter or request:parameters object or unparsable JSON
|
|
catch (\InvalidArgumentException $e) {
|
|
if (isset($json)) $json->isJSONRequest(false); // no regular json request processing
|
|
|
|
// give a proper HTTP status 400 Bad Request with some JSON payload explaining the problem
|
|
http_response_code(400);
|
|
header('Content-Type: application/json');
|
|
echo json_encode(array('error' => $e->getMessage(), 'errno' => $e->getCode()));
|
|
}
|
|
// other exceptions are handled by our ajax_exception_handler sending them back as alerts to client-side
|