1 | <?php |
||||
2 | // This file is part of BOINC. |
||||
3 | // http://boinc.berkeley.edu |
||||
4 | // Copyright (C) 2008 University of California |
||||
5 | // |
||||
6 | // BOINC is free software; you can redistribute it and/or modify it |
||||
7 | // under the terms of the GNU Lesser General Public License |
||||
8 | // as published by the Free Software Foundation, |
||||
9 | // either version 3 of the License, or (at your option) any later version. |
||||
10 | // |
||||
11 | // BOINC is distributed in the hope that it will be useful, |
||||
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||||
14 | // See the GNU Lesser General Public License for more details. |
||||
15 | // |
||||
16 | // You should have received a copy of the GNU Lesser General Public License |
||||
17 | // along with BOINC. If not, see <http://www.gnu.org/licenses/>. |
||||
18 | |||||
19 | // mechanism for caching commonly-accessed pages |
||||
20 | |||||
21 | require_once("../project/cache_parameters.inc"); |
||||
22 | |||||
23 | // If we can't see request headers, don't do caching |
||||
24 | // |
||||
25 | $no_cache = false; |
||||
26 | if (!function_exists("apache_request_headers")) { |
||||
27 | $no_cache = true; |
||||
28 | } |
||||
29 | |||||
30 | function make_cache_dirs() { |
||||
31 | if (!@filemtime("../cache")) { |
||||
32 | mkdir("../cache", 0770); |
||||
33 | chmod("../cache", 0770); |
||||
34 | } |
||||
35 | for ($i=0;$i<256;$i++) { |
||||
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||||
36 | $j=sprintf("%02x",$i); |
||||
37 | if (!@filemtime("../cache/$j")) { |
||||
38 | mkdir("../cache/$j", 0770); |
||||
39 | chmod("../cache/$j", 0770); |
||||
40 | } |
||||
41 | } |
||||
42 | } |
||||
43 | |||||
44 | function get_path($params, $phpfile=null) { |
||||
45 | if (!@filemtime("../cache/00")) make_cache_dirs(); |
||||
46 | if ($phpfile) { |
||||
47 | $z = $phpfile; |
||||
48 | } else { |
||||
49 | $y = pathinfo($_SERVER["PHP_SELF"]); |
||||
50 | $z = $y["basename"]; |
||||
51 | } |
||||
52 | |||||
53 | // add a layer of subdirectories for reducing file lookup time |
||||
54 | $sz = substr(md5($z."_".urlencode($params)),1,2); |
||||
55 | $path = "../cache/".$sz."/".$z; |
||||
56 | if ($params) { |
||||
57 | $path = $path."_".urlencode($params); |
||||
58 | } |
||||
59 | return $path; |
||||
60 | } |
||||
61 | |||||
62 | function disk_usage($dir) { |
||||
63 | $usage=0; |
||||
64 | if ($handle=@opendir($dir)) { |
||||
65 | while ($file=readdir($handle)) { |
||||
66 | if (($file != ".") && ($file != "..")) { |
||||
67 | if (@is_dir($dir."/".$file)) { |
||||
68 | $usage+=disk_usage($dir."/".$file); |
||||
69 | } else { |
||||
70 | $usage+=@filesize($dir."/".$file); |
||||
71 | } |
||||
72 | } |
||||
73 | } |
||||
74 | @closedir($handle); |
||||
0 ignored issues
–
show
Are you sure the usage of
closedir($handle) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
It seems like you do not handle an error condition for
closedir() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||
75 | } |
||||
76 | return $usage; |
||||
77 | } |
||||
78 | |||||
79 | function clean_cache($max_age, $dir) { |
||||
80 | $start_dir = getcwd(); |
||||
81 | if (!chdir($dir)) { |
||||
82 | return; |
||||
83 | } |
||||
84 | if ($handle=@opendir(".")) { |
||||
85 | while ($file=readdir($handle)) { |
||||
86 | if ($file == ".") continue; |
||||
87 | if ($file == "..") continue; |
||||
88 | |||||
89 | // don't let hackers trick us into deleting other files! |
||||
90 | if (strstr($file, "..")) { |
||||
91 | continue; |
||||
92 | } |
||||
93 | if (@is_dir($file)) { |
||||
94 | clean_cache($max_age, $file); |
||||
95 | } else { |
||||
96 | if ((time()-@filemtime($file))>$max_age) { |
||||
97 | //echo "unlinking ".getcwd()."/$file\n"; |
||||
98 | @unlink($file); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||
99 | } |
||||
100 | } |
||||
101 | } |
||||
102 | @closedir($handle); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
closedir() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Are you sure the usage of
closedir($handle) is correct as it seems to always return null .
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
103 | } |
||||
104 | chdir($start_dir); |
||||
105 | } |
||||
106 | |||||
107 | |||||
108 | // check cache size every once in a while, purge if too big |
||||
109 | // |
||||
110 | function cache_check_diskspace(){ |
||||
111 | if ((rand() % CACHE_SIZE_CHECK_FREQ)) return; |
||||
112 | if (disk_usage("../cache") < MAX_CACHE_USAGE) return; |
||||
113 | $x = max(TEAM_PAGE_TTL, USER_PAGE_TTL, USER_HOST_TTL, |
||||
114 | USER_PROFILE_TTL, TOP_PAGES_TTL, INDEX_PAGE_TTL |
||||
115 | ); |
||||
116 | clean_cache($x, "../cache"); |
||||
117 | } |
||||
118 | |||||
119 | function cache_need_to_regenerate($path, $max_age){ |
||||
120 | $regenerate = false; |
||||
121 | $request = apache_request_headers(); |
||||
122 | |||||
123 | clearstatcache(); |
||||
124 | $lastmodified = @filemtime($path); |
||||
125 | if ($lastmodified) { |
||||
0 ignored issues
–
show
The expression
$lastmodified of type false|integer is loosely compared to true ; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
Loading history...
|
|||||
126 | // See if cached copy is too old. |
||||
127 | // If so regenerate, |
||||
128 | // and touch the cached copy so other processes |
||||
129 | // don't regenerate at the same time |
||||
130 | // |
||||
131 | if ($lastmodified<time()-$max_age) { |
||||
132 | $regenerate = true; |
||||
133 | @touch($path); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
touch() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||
134 | } |
||||
135 | } else { |
||||
136 | $regenerate = true; |
||||
137 | } |
||||
138 | return $regenerate; |
||||
139 | } |
||||
140 | |||||
141 | // Returns cached data or false if nothing was found |
||||
142 | function get_cached_data($max_age, $params=""){ |
||||
143 | global $no_cache; |
||||
144 | |||||
145 | if ($no_cache) return; |
||||
146 | |||||
147 | $path = get_path($params); |
||||
148 | if ($max_age) { |
||||
149 | if (defined('MEMCACHE_SERVERS')) { |
||||
150 | $cache = BoincMemcache::get()->get($path); |
||||
151 | if ($cache['content']) { |
||||
152 | return $cache['content']; |
||||
153 | } else { |
||||
154 | return $cache; |
||||
155 | } |
||||
156 | } else { |
||||
157 | cache_check_diskspace(); |
||||
158 | $regenerate=cache_need_to_regenerate($path, $max_age); |
||||
159 | if (!$regenerate) { |
||||
160 | return file_get_contents($path); |
||||
161 | } |
||||
162 | } |
||||
163 | } |
||||
164 | return false; //No data was cached, just return |
||||
165 | } |
||||
166 | |||||
167 | // DEPRECATED |
||||
168 | function start_cache($max_age, $params=""){ |
||||
169 | global $no_cache, $caching, $memcache; |
||||
170 | |||||
171 | if ($no_cache) return; |
||||
172 | $caching = true; |
||||
173 | |||||
174 | if ($max_age) { |
||||
175 | $path = get_path($params); |
||||
176 | $cache = null; |
||||
177 | if (defined('MEMCACHE_SERVERS')) { |
||||
178 | $cache = BoincMemcache::get()->get($path); |
||||
179 | if ($cache) { |
||||
180 | $regenerate = false; |
||||
181 | $lastmodified = abs($cache->timestamp); |
||||
182 | } else { |
||||
183 | $regenerate = true; |
||||
184 | } |
||||
185 | } else { |
||||
186 | $lastmodified = @filemtime($path); |
||||
187 | cache_check_diskspace(); //Check free disk space once in a while |
||||
188 | $regenerate = cache_need_to_regenerate($path, $max_age); |
||||
189 | } |
||||
190 | //Is the stored version too old, do we need to regenerate it? |
||||
191 | if ($regenerate){ |
||||
192 | // If cached version is too old (or non-existent) |
||||
193 | // generate the page and write to cache |
||||
194 | // |
||||
195 | ob_start(); |
||||
196 | ob_implicit_flush(0); |
||||
197 | Header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); |
||||
0 ignored issues
–
show
|
|||||
198 | Header("Expires: " . gmdate("D, d M Y H:i:s",time()+$max_age) . " GMT"); |
||||
0 ignored issues
–
show
|
|||||
199 | Header("Cache-Control: public, max-age=" . $max_age); |
||||
0 ignored issues
–
show
|
|||||
200 | |||||
201 | // allow the calling page to see cache period |
||||
202 | // |
||||
203 | global $cached_max_age; |
||||
204 | $cached_max_age = $max_age; |
||||
205 | } else { |
||||
206 | // Otherwise serve the cached version and exit |
||||
207 | // |
||||
208 | if (strstr($params, "format=xml")) { |
||||
209 | header('Content-type: text/xml'); |
||||
210 | } |
||||
211 | Header("Last-Modified: " . gmdate("D, d M Y H:i:s",$lastmodified) . " GMT"); |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
212 | Header("Expires: " . gmdate("D, d M Y H:i:s",$lastmodified+$max_age) . " GMT"); |
||||
0 ignored issues
–
show
|
|||||
213 | Header("Cache-Control: public, max-age=" . $max_age ); |
||||
0 ignored issues
–
show
|
|||||
214 | if ($cache && $cache->content) { |
||||
215 | echo $cache->content; |
||||
216 | exit; |
||||
217 | } |
||||
218 | if (!@readfile($path)) { |
||||
219 | //echo "can't read $path; lastmod $lastmodified\n"; |
||||
220 | @unlink($path); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||
221 | //Proceed to regenerate content |
||||
222 | } else { |
||||
223 | exit; |
||||
0 ignored issues
–
show
|
|||||
224 | } |
||||
225 | } |
||||
226 | } |
||||
227 | } |
||||
228 | |||||
229 | // write output buffer both to client and to cache |
||||
230 | // DEPRECATED |
||||
231 | function end_cache($max_age,$params=""){ |
||||
232 | global $no_cache; |
||||
233 | if ($no_cache) return; |
||||
234 | |||||
235 | // for the benefit of hackers |
||||
236 | if (strstr($params, "..")) { |
||||
237 | return; |
||||
238 | } |
||||
239 | if ($max_age) { |
||||
240 | $path = get_path($params); |
||||
241 | |||||
242 | if (defined('MEMCACHE_SERVERS')) { |
||||
243 | $cache = array('content' => ob_get_contents(), 'timestamp' => time()); |
||||
244 | ob_end_flush(); |
||||
245 | $cache = BoincMemcache::get()->set($path, $cache, $max_age); |
||||
246 | } else { |
||||
247 | $fhandle = fopen($path, "w"); |
||||
248 | $page = ob_get_contents(); |
||||
249 | ob_end_flush(); |
||||
250 | fwrite($fhandle, $page); |
||||
251 | fclose($fhandle); |
||||
252 | } |
||||
253 | } |
||||
254 | } |
||||
255 | |||||
256 | function set_cached_data($max_age, $data, $params=""){ |
||||
257 | // for the benefit of hackers |
||||
258 | if (strstr($params, "..")) { |
||||
259 | return "bad params"; |
||||
260 | } |
||||
261 | $path = get_path($params); |
||||
262 | if (defined('MEMCACHE_SERVERS')) { |
||||
263 | $cache = array('content' => $data, 'timestamp' => time()); |
||||
264 | BoincMemcache::get()->set($path, $cache, $max_age); |
||||
265 | } else { |
||||
266 | $fhandle = @fopen($path, "w"); |
||||
267 | if (!$fhandle) { |
||||
0 ignored issues
–
show
|
|||||
268 | return "can't open $path"; |
||||
269 | } |
||||
270 | fwrite($fhandle, $data); |
||||
271 | fclose($fhandle); |
||||
272 | } |
||||
273 | return ""; |
||||
274 | } |
||||
275 | |||||
276 | function clear_cache_entry($phpfile, $params) { |
||||
277 | if (strstr($phpfile, "..")) { |
||||
278 | return; |
||||
279 | } |
||||
280 | if (strstr($params, "..")) { |
||||
281 | return; |
||||
282 | } |
||||
283 | $path = get_path($params, $phpfile); |
||||
284 | @unlink($path); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||
285 | } |
||||
286 | |||||
287 | // Memcached class |
||||
288 | class BoincMemcache { |
||||
289 | static $instance; |
||||
290 | |||||
291 | static function get() { |
||||
292 | self::$instance = new Memcached; |
||||
293 | if (defined('MEMCACHE_PREFIX')) { |
||||
294 | self::$instance->setOption(Memcached::OPT_PREFIX_KEY, MEMCACHE_PREFIX); |
||||
295 | } |
||||
296 | $servers = explode('|', MEMCACHE_SERVERS); |
||||
297 | foreach($servers as &$server) { |
||||
298 | list($ip, $port) = explode(':', $server); |
||||
299 | if (!$port) { $port = 11211; } |
||||
300 | $server = array($ip, $port); |
||||
301 | } |
||||
302 | self::$instance->addServers($servers); |
||||
303 | return self::$instance; |
||||
304 | } |
||||
305 | } |
||||
306 | |||||
307 | ?> |
||||
308 |