PageRenderTime 25ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/amfphp/core/amf/app/Gateway.php

https://gitlab.com/endomorphosis/suschu
PHP | 410 lines | 228 code | 45 blank | 137 comment | 25 complexity | 351f525e2932275fc73744069f1882e6 MD5 | raw file
  1. <?php
  2. /**
  3. * The Gateway class is the main facade for the AMFPHP remoting service.
  4. *
  5. * The developer will instantiate a new gateway instance and will interface with
  6. * the gateway instance to control how the gateway processes request, securing the
  7. * gateway with instance names and turning on additional functionality for the gateway
  8. * instance.
  9. *
  10. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  11. * @copyright (c) 2003 amfphp.org
  12. * @package flashservices
  13. * @subpackage app
  14. * @author Musicman original design
  15. * @author Justin Watkins Gateway architecture, class structure, datatype io additions
  16. * @author John Cowen Datatype io additions, class structure,
  17. * @author Klaasjan Tukker Modifications, check routines, and register-framework
  18. * @version $Id: Gateway.php,v 1.45 2005/07/22 10:58:09 pmineault Exp $
  19. */
  20. /**
  21. * AMFPHP_BASE is the location of the flashservices folder in the files system.
  22. * It is used as the absolute path to load all other required system classes.
  23. */
  24. define("AMFPHP_BASE", realpath(dirname(dirname(dirname(__FILE__)))) . "/");
  25. /**
  26. * required classes for the application
  27. */
  28. require_once(AMFPHP_BASE . "shared/app/Constants.php");
  29. require_once(AMFPHP_BASE . "shared/app/Globals.php");
  30. if(AMFPHP_PHP5)
  31. {
  32. require_once(AMFPHP_BASE . "shared/util/CompatPhp5.php");
  33. }
  34. else
  35. {
  36. require_once(AMFPHP_BASE . "shared/util/CompatPhp4.php");
  37. }
  38. require_once(AMFPHP_BASE . "shared/util/CharsetHandler.php");
  39. require_once(AMFPHP_BASE . "shared/util/NetDebug.php");
  40. require_once(AMFPHP_BASE . "shared/util/Headers.php");
  41. require_once(AMFPHP_BASE . "shared/exception/MessageException.php");
  42. require_once(AMFPHP_BASE . "shared/app/BasicActions.php");
  43. require_once(AMFPHP_BASE . "amf/util/AMFObject.php");
  44. require_once(AMFPHP_BASE . "amf/util/WrapperClasses.php");
  45. require_once(AMFPHP_BASE . "amf/app/Filters.php");
  46. require_once(AMFPHP_BASE . "amf/app/Actions.php");
  47. class Gateway {
  48. var $_looseMode = false;
  49. var $_charsetMethod = "none";
  50. var $_charsetPhp = "";
  51. var $_charsetSql = "";
  52. var $exec;
  53. var $filters;
  54. var $actions;
  55. var $outgoingMessagesFolder = NULL;
  56. var $incomingMessagesFolder = NULL;
  57. var $useSslFirstMethod = true;
  58. var $_enableGzipCompression = false;
  59. /**
  60. * The Gateway constructor method.
  61. *
  62. * The constructor method initializes the executive object so any configurations
  63. * can immediately propogate to the instance.
  64. */
  65. function Gateway() {
  66. //Include right executive for php version
  67. //Try catch are not syntactically correct in PHP4, so we can't even include
  68. //them in PHP 4.
  69. if(AMFPHP_PHP5)
  70. {
  71. //Set gloriously nice error handling
  72. include_once(AMFPHP_BASE . "shared/app/php5Executive.php");
  73. include_once(AMFPHP_BASE . "shared/exception/php5Exception.php");
  74. }
  75. else
  76. {
  77. //Cry
  78. include_once(AMFPHP_BASE . "shared/app/php4Executive.php");
  79. include_once(AMFPHP_BASE . "shared/exception/php4Exception.php");
  80. }
  81. $this->exec = new Executive();
  82. $this->filters = array();
  83. $this->actions = array();
  84. $this->registerFilterChain();
  85. $this->registerActionChain();
  86. }
  87. /**
  88. * Create the chain of filters
  89. * Subclass gateway and overwrite to create a custom gateway
  90. */
  91. function registerFilterChain()
  92. {
  93. //filters
  94. $this->filters['deserial'] = 'deserializationFilter';
  95. $this->filters['auth'] = 'authenticationFilter';
  96. $this->filters['batch'] = 'batchProcessFilter';
  97. $this->filters['debug'] = 'debugFilter';
  98. $this->filters['serialize'] = 'serializationFilter';
  99. }
  100. /**
  101. * Create the chain of actions
  102. * Subclass gateway and overwrite to create a custom gateway
  103. */
  104. function registerActionChain()
  105. {
  106. $this->actions['adapter'] = 'adapterAction';
  107. $this->actions['class'] = 'classLoaderAction';
  108. $this->actions['security'] = 'securityAction';
  109. $this->actions['exec'] = 'executionAction';
  110. }
  111. /**
  112. * The service method runs the gateway application. It turns the gateway 'on'. You
  113. * have to call the service method as the last line of the gateway script after all of the
  114. * gateway configuration properties have been set.
  115. *
  116. * Right now the service method also includes a very primitive debugging mode that
  117. * just dumps the raw amf input and output to files. This may change in later versions.
  118. * The debugging implementation is NOT thread safe so be aware of file corruptions that
  119. * may occur in concurrent environments.
  120. */
  121. function service() {
  122. //Set the parameters for the charset handler
  123. CharsetHandler::setMethod($this->_charsetMethod);
  124. CharsetHandler::setPhpCharset($this->_charsetPhp);
  125. CharsetHandler::setSqlCharset($this->_charsetSql);
  126. //Attempt to call charset handler to catch any uninstalled extensions
  127. $ch = new CharsetHandler('flashtophp');
  128. $ch->transliterate('?');
  129. $ch2 = new CharsetHandler('sqltophp');
  130. $ch2->transliterate('?');
  131. $GLOBALS['amfphp']['actions'] = $this->actions;
  132. if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])){
  133. $GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');
  134. }
  135. if(isset($GLOBALS["HTTP_RAW_POST_DATA"]) && $GLOBALS["HTTP_RAW_POST_DATA"] != "")
  136. {
  137. //Start NetDebug
  138. NetDebug::initialize();
  139. error_reporting($GLOBALS['amfphp']['errorLevel']);
  140. //Enable loose mode if requested
  141. if($this->_looseMode)
  142. {
  143. ob_start();
  144. }
  145. $amf = new AMFObject($GLOBALS["HTTP_RAW_POST_DATA"]); // create the amf object
  146. if($this->incomingMessagesFolder != NULL)
  147. {
  148. $mt = microtime();
  149. $pieces = explode(' ', $mt);
  150. file_put_contents($this->incomingMessagesFolder .
  151. 'in.' . $pieces[1] . '.' . substr($pieces[0], 2) . ".amf",
  152. $GLOBALS["HTTP_RAW_POST_DATA"]);
  153. }
  154. foreach($this->filters as $key => $filter)
  155. {
  156. $filter($amf); // invoke the first filter in the chain
  157. }
  158. $output = $amf->outputStream; // grab the output stream
  159. //Clear the current output buffer if requested
  160. if($this->_looseMode)
  161. {
  162. ob_end_clean();
  163. }
  164. //Send content length header
  165. //Thanks to Alec Horley for pointing out the necessity
  166. //of this for FlashComm support
  167. header(AMFPHP_CONTENT_TYPE); // define the proper header
  168. if(Headers::getHeader('serviceBrowser') == true)
  169. {
  170. //Add the total time header
  171. $toAddPos = strpos($output, "\301\260\0\0\1\0\0\0");
  172. $time = (int) ((microtime_float() - $GLOBALS['amfphp']['startTime'])*1000);
  173. $b = pack("d", $time); // pack the bytes
  174. if (AMFPHP_BIG_ENDIAN) { // if we are a big-endian processor
  175. $r = strrev($b);
  176. } else { // add the bytes to the output
  177. $r = $b;
  178. }
  179. $output = substr($output, 0, $toAddPos) . $r . substr($output, $toAddPos + 8);
  180. }
  181. //Send expire header, apparently helps for SSL
  182. //Thanks to Gary Rogers for that
  183. //And also to Lucas Filippi from openAMF list
  184. //And to Robert Reinhardt who appears to be the first who
  185. //documented the bug
  186. //Finally to Gary who appears to have find a solution which works even more reliably
  187. $dateStr = date("D, j M Y ") . date("H:i:s", strtotime("-2 days"));
  188. header("Expires: $dateStr GMT");
  189. header("Pragma: no-store");
  190. header("Cache-Control: no-store");
  191. //else don't send any special headers at all
  192. if($this->outgoingMessagesFolder != NULL)
  193. {
  194. $mt = microtime();
  195. $pieces = explode(' ', $mt);
  196. file_put_contents($this->outgoingMessagesFolder .
  197. 'out.' . $pieces[1] . '.' . substr($pieces[0], 2) . ".amf", $output);
  198. }
  199. $doCompress = false;
  200. $outputCompression = @ini_get("zlib.output_compression");
  201. if(!$outputCompression)
  202. {
  203. if(strlen($output) > $this->_gzipCompressionThreshold &&
  204. extension_loaded("zlib") &&
  205. strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE &&
  206. $this->_enableGzipCompression)
  207. {
  208. $doCompress = true;
  209. ob_start();
  210. ob_start('ob_gzhandler');
  211. }
  212. else
  213. {
  214. header("Content-length: " . strlen($output));
  215. }
  216. }
  217. print($output); // flush the binary data
  218. if($doCompress)
  219. {
  220. ob_end_flush();
  221. header("Content-length: " . ob_get_length());
  222. ob_end_flush();
  223. }
  224. }
  225. else
  226. {
  227. echo("<p>amfphp and this gateway are installed correctly. You may now connect " .
  228. "to this gateway from Flash.</p>");
  229. if(function_exists("amf_decode"))
  230. {
  231. echo("<p>AMF C Extension is loaded " .
  232. ($GLOBALS['amfphp']['native'] ? "and enabled." : "but disabled") .
  233. "</p>");
  234. }
  235. echo "<p>Note: If you're reading an " .
  236. "old tutorial, it will tell you that you should see a download ".
  237. "window instead of this message. This confused people so this is " .
  238. "the new behaviour starting from amfphp 1.2.</p><p>" .
  239. "<a href='http://www.amfphp.org/docs'>View the amfphp documentation</p>" .
  240. "<p><a href='browser'>Load the service browser</a></p>";
  241. echo "<pre>";
  242. }
  243. }
  244. /**
  245. * Setter for error handling
  246. *
  247. * @param the error handling level
  248. */
  249. function setErrorHandling($level)
  250. {
  251. $GLOBALS['amfphp']['errorLevel'] = $level;
  252. }
  253. /**
  254. * Sets the base path for loading service methods.
  255. *
  256. * Call this method to define the directory to look for service classes in.
  257. * Relative or full paths are acceptable
  258. *
  259. * @param string $path The path the the service class directory
  260. */
  261. function setClassPath($value) {
  262. $path = realpath($value . '/') . '/';
  263. $GLOBALS['amfphp']['classPath'] = $path;
  264. }
  265. /**
  266. * Sets the base path for loading service methods.
  267. *
  268. * Call this method to define the directory to look for service classes in.
  269. * Relative or full paths are acceptable
  270. *
  271. * @param string $path The path the the service class directory
  272. */
  273. function setClassMappingsPath($value) {
  274. $path = realpath($value . '/') . '/';
  275. $GLOBALS['amfphp']['customMappingsPath'] = $path;
  276. }
  277. /**
  278. * Sets the loose mode. This will enable outbut buffering
  279. * And flushing and set error_reporting to 0. The point is if set to true, a few
  280. * of the usual NetConnection.BadVersion error should disappear
  281. * Like if you try to echo directly from your function, if you are issued a
  282. * warning and such. Errors should still be logged to the error log though.
  283. *
  284. * @example In gateway.php, before $gateway->service(), use $gateway->setLooseMode(true)
  285. * @param bool $mode Enable or disable loose mode
  286. */
  287. function setLooseMode($paramLoose = true) {
  288. $this->_looseMode = $paramLoose;
  289. }
  290. function enableGzipCompression($threshold = 30100)
  291. {
  292. $this->_enableGzipCompression = true;
  293. $this->_gzipCompressionThreshold = $threshold;
  294. }
  295. /**
  296. * Sets the charset handler.
  297. * The charset handler handles reencoding from and to a specific charset
  298. * for PHP and SQL resources.
  299. *
  300. * @param $method The method used for reencoding, either "none", "iconv" or "runtime"
  301. * @param $php The internal encoding that is assumed for PHP (typically ISO-8859-1)
  302. * @param $sql The internal encoding that is assumed for SQL resources
  303. */
  304. function setCharsetHandler($method = "none", $php, $sql) {
  305. $this->_charsetMethod = $method;
  306. $this->_charsetPhp = $php;
  307. $this->_charsetSql = $sql;
  308. }
  309. /**
  310. * disableTrace will ignore any calls to NetDebug::trace
  311. *
  312. * @param bool $bool Whether to disable tracing
  313. */
  314. function disableDebug($value = true) {
  315. $GLOBALS['amfphp']['disableDebug'] = $value;
  316. }
  317. /**
  318. * Disable native extension will disable the native C extension
  319. */
  320. function disableNativeExtension()
  321. {
  322. $GLOBALS['amfphp']['native'] = false;
  323. }
  324. /**
  325. * Log incoming messages to the specified folder
  326. */
  327. function logIncomingMessages($folder = NULL)
  328. {
  329. $this->incomingMessagesFolder = realpath($folder) . '/';
  330. }
  331. /**
  332. * Log outgoing messages to the specified folder
  333. */
  334. function logOutgoingMessages($folder = NULL)
  335. {
  336. $this->outgoingMessagesFolder = realpath($folder) . '/';
  337. }
  338. /**
  339. * Dumps data to a file
  340. *
  341. * @param string $filepath The location of the dump file
  342. * @param string $data The data to insert into the dump file
  343. */
  344. function _saveRawDataToFile($filepath, $data) {
  345. if (!$handle = fopen($filepath, 'w')) {
  346. exit;
  347. }
  348. if (!fwrite($handle, $data)) {
  349. exit;
  350. }
  351. fclose($handle);
  352. }
  353. /**
  354. * Appends data to a file
  355. *
  356. * @param string $filepath The location of the dump file
  357. * @param string $data The data to append to the dump file
  358. */
  359. function _appendRawDataToFile($filepath, $data) {
  360. $handle = fopen($filepath, 'a');
  361. fwrite($handle, $data);
  362. fclose($handle);
  363. }
  364. }
  365. ?>