|
4 | 4 | // functions for returning or comparing dates
|
5 | 5 |
|
6 | 6 |
|
7 |
| -// get remote file last modification date (returns unix timestamp) |
8 |
| -function remote_filemtime($url) { |
9 |
| - $fp = fopen($url, 'r'); |
10 |
| - if (!$fp) return 0; |
11 |
| - $metadata = stream_get_meta_data($fp); |
12 |
| - fclose($fp); |
13 |
| - |
14 |
| - $unixtime = 0; |
15 |
| - foreach ($metadata['wrapper_data'] as $response) { |
16 |
| - // case: redirection |
17 |
| - // WARNING: does not handle relative redirection |
18 |
| - if (substr(strtolower($response), 0, 10) == 'location: ') { |
19 |
| - return GetRemoteLastModified(substr($response, 10)); |
20 |
| - } |
21 |
| - // case: last-modified |
22 |
| - else if (substr(strtolower($response), 0, 15) == 'last-modified: ') { |
23 |
| - $unixtime = strtotime(substr($response, 15)); |
24 |
| - break; |
| 7 | +/* |
| 8 | + * Get remote file last modification date (returns unix timestamp) |
| 9 | + * Supports HTTPS, HTTP basic authentication, and location: redirects |
| 10 | + * FIXME: Basic auth should not be sent over unencrypted connections |
| 11 | + * unless an HTTP 401 Unauthorized is returned |
| 12 | + */ |
| 13 | +function remote_filemtime($url, $recurse = 0) { |
| 14 | + // We hate infinite loops! |
| 15 | + if (++$recurse > 5) return 0; |
| 16 | + |
| 17 | + // Caching the remote mtime is a Really Good Idea. |
| 18 | + static $remote_files = array(); |
| 19 | + if (isset($remote_files[$url])) return $remote_files[$url]; |
| 20 | + |
| 21 | + $uri = parse_url($url); |
| 22 | + $uri['proto'] = ( |
| 23 | + (isset($uri['proto']) && ($uri['proto'] == 'https')) ? |
| 24 | + 'ssl://' : |
| 25 | + '' |
| 26 | + ); |
| 27 | + $uri['port'] = isset($uri['port']) ? $uri['port'] : 80; |
| 28 | + $path = ( |
| 29 | + (isset($uri['path']) || isset($uri['query'])) ? |
| 30 | + (@$uri['path'] . @$uri['query']) : |
| 31 | + '/' |
| 32 | + ); |
| 33 | + $auth = ( |
| 34 | + (isset($uri['user']) || isset($uri['pass'])) ? |
| 35 | + ('Authentication: Basic ' . base64_encode(@$uri['user'] . ':' . @$uri['pass']) . "\r\n") : |
| 36 | + '' |
| 37 | + ); |
| 38 | + |
| 39 | + $handle = @fsockopen($uri['proto'] . $uri['host'], $uri['port']); |
| 40 | + if (!$handle) { |
| 41 | + $remote_files[$url] = 0; |
| 42 | + return 0; |
| 43 | + } |
| 44 | + |
| 45 | + fputs($handle, "HEAD {$path} HTTP/1.1\r\nHost: {$uri['host']}\r\n{$auth}Connection: close\r\n\r\n"); |
| 46 | + $headers = array(); |
| 47 | + while (!feof($handle)) { |
| 48 | + $line = trim(fgets($handle, 1024)); |
| 49 | + if (empty($line)) break; |
| 50 | + $headers[] = $line; |
| 51 | + } |
| 52 | + fclose($handle); |
| 53 | + |
| 54 | + $result = 0; |
| 55 | + array_shift($headers); |
| 56 | + foreach ($headers as $header) { |
| 57 | + list($key, $value) = explode(':', $header, 2); |
| 58 | + $value = trim($value); |
| 59 | + |
| 60 | + switch (strtolower(trim($key))) { |
| 61 | + case 'location': // Redirect |
| 62 | + $result = remote_filemtime(resolve_path($url, $value), $recurse); |
| 63 | + break; |
| 64 | + |
| 65 | + case 'last-modified': // Got it! |
| 66 | + $result = strtotime($value); |
| 67 | + break; |
25 | 68 | }
|
26 | 69 | }
|
27 | 70 |
|
28 |
| - return $unixtime; |
| 71 | + $remote_files[$url] = $result; |
| 72 | + return $result; |
| 73 | +} |
| 74 | + |
| 75 | +/* |
| 76 | + * Resolve relative paths |
| 77 | + * Utility function for remote_filemtime() |
| 78 | + */ |
| 79 | +function resolve_path($url, $rel_path) { |
| 80 | + $uri = parse_url($url); |
| 81 | + |
| 82 | + $uri['proto'] = (isset($uri['proto']) ? $uri['proto'] : 'http://'); |
| 83 | + $uri['port'] = (isset($uri['port']) ? (':' . $uri['port']) : ''); |
| 84 | + $auth = ( |
| 85 | + (isset($uri['user']) || isset($uri['pass'])) ? |
| 86 | + (urlencode(@$uri['user']) . ':' . urlencode(@$uri['pass']) . '@') : |
| 87 | + '' |
| 88 | + ); |
| 89 | + |
| 90 | + if (parse_url($rel_path) === false) { |
| 91 | + // Path is relative to this domain |
| 92 | + $rel_path = str_replace('\\', '/', $rel_path); |
| 93 | + |
| 94 | + if ($rel_path{0} == '/') |
| 95 | + return $uri['proto'] . '://' . $auth . $uri['host'] . $uri['port'] . $rel_path; |
| 96 | + |
| 97 | + return $uri['proto'] . '://' . $auth . $uri['host'] . $uri['port'] . $uri['path'] . '/' . $rel_path; |
| 98 | + } |
| 99 | + |
| 100 | + // Path is absolute |
| 101 | + return $rel_path; |
29 | 102 | }
|
30 | 103 |
|
31 | 104 | // takes iCalendar 2 day format and makes it into 3 characters
|
@@ -235,10 +308,10 @@ function openevent($event_date, $time, $uid, $arr, $lines = 0, $length = 0, $lin
|
235 | 308 | # for iCal pseudo tag <http> comptability
|
236 | 309 | if (ereg('<([[:alpha:]]+://)([^<>[:space:]]+)>',$event_text,$matches)) {
|
237 | 310 | $full_event_text = $matches[1] . $matches[2];
|
238 |
| - $event_text = $matches[2]; |
| 311 | + $event_text = $matches[2]; |
239 | 312 | } else {
|
240 | 313 | $full_event_text = $event_text;
|
241 |
| - $event_text = strip_tags($event_text, '<b><i><u><img>'); |
| 314 | + $event_text = strip_tags($event_text, '<b><i><u><img>'); |
242 | 315 | }
|
243 | 316 |
|
244 | 317 | if (!empty($link_class)) $link_class = ' class="'.$link_class.'"';
|
|
0 commit comments