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