function.fetch.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. /**
  3. * Smarty plugin
  4. *
  5. * @package Smarty
  6. * @subpackage PluginsFunction
  7. */
  8. /**
  9. * Smarty {fetch} plugin
  10. *
  11. * Type: function<br>
  12. * Name: fetch<br>
  13. * Purpose: fetch file, web or ftp data and display results
  14. *
  15. * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
  16. * (Smarty online manual)
  17. * @author Monte Ohrt <monte at ohrt dot com>
  18. * @param array $params parameters
  19. * @param Smarty_Internal_Template $template template object
  20. * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
  21. */
  22. function smarty_function_fetch($params, $template)
  23. {
  24. if (empty($params['file'])) {
  25. trigger_error("[plugin] fetch parameter 'file' cannot be empty",E_USER_NOTICE);
  26. return;
  27. }
  28. $content = '';
  29. if (isset($template->smarty->security_policy) && !preg_match('!^(http|ftp)://!i', $params['file'])) {
  30. if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
  31. return;
  32. }
  33. // fetch the file
  34. if($fp = @fopen($params['file'],'r')) {
  35. while(!feof($fp)) {
  36. $content .= fgets ($fp,4096);
  37. }
  38. fclose($fp);
  39. } else {
  40. trigger_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'',E_USER_NOTICE);
  41. return;
  42. }
  43. } else {
  44. // not a local file
  45. if(preg_match('!^http://!i',$params['file'])) {
  46. // http fetch
  47. if($uri_parts = parse_url($params['file'])) {
  48. // set defaults
  49. $host = $server_name = $uri_parts['host'];
  50. $timeout = 30;
  51. $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  52. $agent = "Smarty Template Engine ". Smarty::SMARTY_VERSION;
  53. $referer = "";
  54. $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
  55. $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
  56. $_is_proxy = false;
  57. if(empty($uri_parts['port'])) {
  58. $port = 80;
  59. } else {
  60. $port = $uri_parts['port'];
  61. }
  62. if(!empty($uri_parts['user'])) {
  63. $user = $uri_parts['user'];
  64. }
  65. if(!empty($uri_parts['pass'])) {
  66. $pass = $uri_parts['pass'];
  67. }
  68. // loop through parameters, setup headers
  69. foreach($params as $param_key => $param_value) {
  70. switch($param_key) {
  71. case "file":
  72. case "assign":
  73. case "assign_headers":
  74. break;
  75. case "user":
  76. if(!empty($param_value)) {
  77. $user = $param_value;
  78. }
  79. break;
  80. case "pass":
  81. if(!empty($param_value)) {
  82. $pass = $param_value;
  83. }
  84. break;
  85. case "accept":
  86. if(!empty($param_value)) {
  87. $accept = $param_value;
  88. }
  89. break;
  90. case "header":
  91. if(!empty($param_value)) {
  92. if(!preg_match('![\w\d-]+: .+!',$param_value)) {
  93. trigger_error("[plugin] invalid header format '".$param_value."'",E_USER_NOTICE);
  94. return;
  95. } else {
  96. $extra_headers[] = $param_value;
  97. }
  98. }
  99. break;
  100. case "proxy_host":
  101. if(!empty($param_value)) {
  102. $proxy_host = $param_value;
  103. }
  104. break;
  105. case "proxy_port":
  106. if(!preg_match('!\D!', $param_value)) {
  107. $proxy_port = (int) $param_value;
  108. } else {
  109. trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE);
  110. return;
  111. }
  112. break;
  113. case "agent":
  114. if(!empty($param_value)) {
  115. $agent = $param_value;
  116. }
  117. break;
  118. case "referer":
  119. if(!empty($param_value)) {
  120. $referer = $param_value;
  121. }
  122. break;
  123. case "timeout":
  124. if(!preg_match('!\D!', $param_value)) {
  125. $timeout = (int) $param_value;
  126. } else {
  127. trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE);
  128. return;
  129. }
  130. break;
  131. default:
  132. trigger_error("[plugin] unrecognized attribute '".$param_key."'",E_USER_NOTICE);
  133. return;
  134. }
  135. }
  136. if(!empty($proxy_host) && !empty($proxy_port)) {
  137. $_is_proxy = true;
  138. $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
  139. } else {
  140. $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
  141. }
  142. if(!$fp) {
  143. trigger_error("[plugin] unable to fetch: $errstr ($errno)",E_USER_NOTICE);
  144. return;
  145. } else {
  146. if($_is_proxy) {
  147. fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
  148. } else {
  149. fputs($fp, "GET $uri HTTP/1.0\r\n");
  150. }
  151. if(!empty($host)) {
  152. fputs($fp, "Host: $host\r\n");
  153. }
  154. if(!empty($accept)) {
  155. fputs($fp, "Accept: $accept\r\n");
  156. }
  157. if(!empty($agent)) {
  158. fputs($fp, "User-Agent: $agent\r\n");
  159. }
  160. if(!empty($referer)) {
  161. fputs($fp, "Referer: $referer\r\n");
  162. }
  163. if(isset($extra_headers) && is_array($extra_headers)) {
  164. foreach($extra_headers as $curr_header) {
  165. fputs($fp, $curr_header."\r\n");
  166. }
  167. }
  168. if(!empty($user) && !empty($pass)) {
  169. fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
  170. }
  171. fputs($fp, "\r\n");
  172. while(!feof($fp)) {
  173. $content .= fgets($fp,4096);
  174. }
  175. fclose($fp);
  176. $csplit = preg_split("!\r\n\r\n!",$content,2);
  177. $content = $csplit[1];
  178. if(!empty($params['assign_headers'])) {
  179. $template->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0]));
  180. }
  181. }
  182. } else {
  183. trigger_error("[plugin fetch] unable to parse URL, check syntax",E_USER_NOTICE);
  184. return;
  185. }
  186. } else {
  187. // ftp fetch
  188. if($fp = @fopen($params['file'],'r')) {
  189. while(!feof($fp)) {
  190. $content .= fgets ($fp,4096);
  191. }
  192. fclose($fp);
  193. } else {
  194. trigger_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'',E_USER_NOTICE);
  195. return;
  196. }
  197. }
  198. }
  199. if (!empty($params['assign'])) {
  200. $template->assign($params['assign'],$content);
  201. } else {
  202. return $content;
  203. }
  204. }
  205. ?>