PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Server/SWXPHP/Prior Releases/1.01/php/core/amf/app/Gateway.php

http://swx-format.googlecode.com/
PHP | 406 lines | 225 code | 44 blank | 137 comment | 24 complexity | 5b183c2e9a1d6cef2efa8517c07bf0fc MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  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"]) && $GLOBALS["HTTP_RAW_POST_DATA"] != "")
  133. {
  134. //Start NetDebug
  135. NetDebug::initialize();
  136. error_reporting($GLOBALS['amfphp']['errorLevel']);
  137. //Enable loose mode if requested
  138. if($this->_looseMode)
  139. {
  140. ob_start();
  141. }
  142. $amf = new AMFObject($GLOBALS["HTTP_RAW_POST_DATA"]); // create the amf object
  143. if($this->incomingMessagesFolder != NULL)
  144. {
  145. $mt = microtime();
  146. $pieces = explode(' ', $mt);
  147. file_put_contents($this->incomingMessagesFolder .
  148. 'in.' . $pieces[1] . '.' . substr($pieces[0], 2) . ".amf",
  149. $GLOBALS["HTTP_RAW_POST_DATA"]);
  150. }
  151. foreach($this->filters as $key => $filter)
  152. {
  153. $filter($amf); // invoke the first filter in the chain
  154. }
  155. $output = $amf->outputStream; // grab the output stream
  156. //Clear the current output buffer if requested
  157. if($this->_looseMode)
  158. {
  159. ob_end_clean();
  160. }
  161. //Send content length header
  162. //Thanks to Alec Horley for pointing out the necessity
  163. //of this for FlashComm support
  164. header(AMFPHP_CONTENT_TYPE); // define the proper header
  165. if(Headers::getHeader('serviceBrowser') == true)
  166. {
  167. //Add the total time header
  168. $toAddPos = strpos($output, "\301\260\0\0\1\0\0\0");
  169. $time = (int) ((microtime_float() - $GLOBALS['amfphp']['startTime'])*1000);
  170. $b = pack("d", $time); // pack the bytes
  171. if (AMFPHP_BIG_ENDIAN) { // if we are a big-endian processor
  172. $r = strrev($b);
  173. } else { // add the bytes to the output
  174. $r = $b;
  175. }
  176. $output = substr($output, 0, $toAddPos) . $r . substr($output, $toAddPos + 8);
  177. }
  178. //Send expire header, apparently helps for SSL
  179. //Thanks to Gary Rogers for that
  180. //And also to Lucas Filippi from openAMF list
  181. //And to Robert Reinhardt who appears to be the first who
  182. //documented the bug
  183. //Finally to Gary who appears to have find a solution which works even more reliably
  184. $dateStr = date("D, j M Y ") . date("H:i:s", strtotime("-2 days"));
  185. header("Expires: $dateStr GMT");
  186. header("Pragma: no-store");
  187. header("Cache-Control: no-store");
  188. //else don't send any special headers at all
  189. if($this->outgoingMessagesFolder != NULL)
  190. {
  191. $mt = microtime();
  192. $pieces = explode(' ', $mt);
  193. file_put_contents($this->outgoingMessagesFolder .
  194. 'out.' . $pieces[1] . '.' . substr($pieces[0], 2) . ".amf", $output);
  195. }
  196. $doCompress = false;
  197. $outputCompression = @ini_get("zlib.output_compression");
  198. if(!$outputCompression)
  199. {
  200. if(strlen($output) > $this->_gzipCompressionThreshold &&
  201. extension_loaded("zlib") &&
  202. strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE &&
  203. $this->_enableGzipCompression)
  204. {
  205. $doCompress = true;
  206. ob_start();
  207. ob_start('ob_gzhandler');
  208. }
  209. else
  210. {
  211. header("Content-length: " . strlen($output));
  212. }
  213. }
  214. print($output); // flush the binary data
  215. if($doCompress)
  216. {
  217. ob_end_flush();
  218. header("Content-length: " . ob_get_length());
  219. ob_end_flush();
  220. }
  221. }
  222. else
  223. {
  224. echo("<p>amfphp and this gateway are installed correctly. You may now connect " .
  225. "to this gateway from Flash.</p>");
  226. if(function_exists("amf_decode"))
  227. {
  228. echo("<p>AMF C Extension is loaded " .
  229. ($GLOBALS['amfphp']['native'] ? "and enabled." : "but disabled") .
  230. "</p>");
  231. }
  232. echo "<p>Note: If you're reading an " .
  233. "old tutorial, it will tell you that you should see a download ".
  234. "window instead of this message. This confused people so this is " .
  235. "the new behaviour starting from amfphp 1.2.</p><p>" .
  236. "<a href='http://www.amfphp.org/docs'>View the amfphp documentation</p>" .
  237. "<p><a href='browser'>Load the service browser</a></p>";
  238. echo "<pre>";
  239. }
  240. }
  241. /**
  242. * Setter for error handling
  243. *
  244. * @param the error handling level
  245. */
  246. function setErrorHandling($level)
  247. {
  248. $GLOBALS['amfphp']['errorLevel'] = $level;
  249. }
  250. /**
  251. * Sets the base path for loading service methods.
  252. *
  253. * Call this method to define the directory to look for service classes in.
  254. * Relative or full paths are acceptable
  255. *
  256. * @param string $path The path the the service class directory
  257. */
  258. function setClassPath($value) {
  259. $path = realpath($value . '/') . '/';
  260. $GLOBALS['amfphp']['classPath'] = $path;
  261. }
  262. /**
  263. * Sets the base path for loading service methods.
  264. *
  265. * Call this method to define the directory to look for service classes in.
  266. * Relative or full paths are acceptable
  267. *
  268. * @param string $path The path the the service class directory
  269. */
  270. function setClassMappingsPath($value) {
  271. $path = realpath($value . '/') . '/';
  272. $GLOBALS['amfphp']['customMappingsPath'] = $path;
  273. }
  274. /**
  275. * Sets the loose mode. This will enable outbut buffering
  276. * And flushing and set error_reporting to 0. The point is if set to true, a few
  277. * of the usual NetConnection.BadVersion error should disappear
  278. * Like if you try to echo directly from your function, if you are issued a
  279. * warning and such. Errors should still be logged to the error log though.
  280. *
  281. * @example In gateway.php, before $gateway->service(), use $gateway->setLooseMode(true)
  282. * @param bool $mode Enable or disable loose mode
  283. */
  284. function setLooseMode($paramLoose = true) {
  285. $this->_looseMode = $paramLoose;
  286. }
  287. function enableGzipCompression($threshold = 30100)
  288. {
  289. $this->_enableGzipCompression = true;
  290. $this->_gzipCompressionThreshold = $threshold;
  291. }
  292. /**
  293. * Sets the charset handler.
  294. * The charset handler handles reencoding from and to a specific charset
  295. * for PHP and SQL resources.
  296. *
  297. * @param $method The method used for reencoding, either "none", "iconv" or "runtime"
  298. * @param $php The internal encoding that is assumed for PHP (typically ISO-8859-1)
  299. * @param $sql The internal encoding that is assumed for SQL resources
  300. */
  301. function setCharsetHandler($method = "none", $php, $sql) {
  302. $this->_charsetMethod = $method;
  303. $this->_charsetPhp = $php;
  304. $this->_charsetSql = $sql;
  305. }
  306. /**
  307. * disableTrace will ignore any calls to NetDebug::trace
  308. *
  309. * @param bool $bool Whether to disable tracing
  310. */
  311. function disableDebug($value = true) {
  312. $GLOBALS['amfphp']['disableDebug'] = $value;
  313. }
  314. /**
  315. * Disable native extension will disable the native C extension
  316. */
  317. function disableNativeExtension()
  318. {
  319. $GLOBALS['amfphp']['native'] = false;
  320. }
  321. /**
  322. * Log incoming messages to the specified folder
  323. */
  324. function logIncomingMessages($folder = NULL)
  325. {
  326. $this->incomingMessagesFolder = realpath($folder) . '/';
  327. }
  328. /**
  329. * Log outgoing messages to the specified folder
  330. */
  331. function logOutgoingMessages($folder = NULL)
  332. {
  333. $this->outgoingMessagesFolder = realpath($folder) . '/';
  334. }
  335. /**
  336. * Dumps data to a file
  337. *
  338. * @param string $filepath The location of the dump file
  339. * @param string $data The data to insert into the dump file
  340. */
  341. function _saveRawDataToFile($filepath, $data) {
  342. if (!$handle = fopen($filepath, 'w')) {
  343. exit;
  344. }
  345. if (!fwrite($handle, $data)) {
  346. exit;
  347. }
  348. fclose($handle);
  349. }
  350. /**
  351. * Appends data to a file
  352. *
  353. * @param string $filepath The location of the dump file
  354. * @param string $data The data to append to the dump file
  355. */
  356. function _appendRawDataToFile($filepath, $data) {
  357. $handle = fopen($filepath, 'a');
  358. fwrite($handle, $data);
  359. fclose($handle);
  360. }
  361. }
  362. ?>