r4359 dispatchImageRequest(): add missing semicolon
[racktables] / wwwroot / inc / solutions.php
CommitLineData
b325120a 1<?php
5c42f907
DO
2/*
3
4The purpose of this file is to contain functions, which generate a complete
5HTTP response body and are either "dead ends" or depend on just a small
6amount of other code (which should eventually be placed in a sort of
7"first order" library file).
8
9*/
10
11define ('RE_STATIC_URI', '#^([[:alpha:]]+)/(?:[[:alpha:]]+/)*[[:alnum:]\._-]+\.([[:alpha:]]+)$#');
e673ee24 12
4afb4c10 13function dispatchImageRequest()
d15b2330 14{
4afb4c10
DO
15 genericAssertion ('img', 'string');
16 global $pageno, $tabno;
17 switch ($_REQUEST['img'])
18 {
da958e52 19 case 'minirack': // rack security context
da958e52 20 $pageno = 'rack';
d15b2330 21 $tabno = 'default';
da958e52 22 fixContext();
46422e6f 23 assertPermission();
3ec33017 24 renderRackThumb (getBypassValue());
d15b2330 25 break;
da958e52 26 case 'progressbar': // no security context
0cc24e9a 27 assertUIntArg ('done', TRUE);
21d40daa 28 // 'progressbar's never change, make browser cache the result
d15b2330
DO
29 renderProgressBarImage ($_REQUEST['done']);
30 break;
0df8c52b 31 case 'preview': // file security context
37e59768 32 $pageno = 'file';
0df8c52b 33 $tabno = 'download';
37e59768 34 fixContext();
3ec33017
DO
35 assertPermission();
36 renderFilePreview (getBypassValue());
37e59768 37 break;
d15b2330 38 default:
11566bd6 39 renderErrorImage();
4afb4c10 40 }
90a3d6d8
DY
41}
42
11566bd6 43function renderErrorImage ()
e673ee24 44{
e673ee24 45 header("Content-type: image/png");
d5f8fa19
DO
46 // "ERROR", 76x17, red on white
47 echo base64_decode
48 (
49 'iVBORw0KGgoAAAANSUhEUgAAAEwAAAARCAYAAAB3h0oCAAAAAXNSR0IArs4c6QAAALBJREFUWMPt' .
50 'WFsOwCAIG4v3vzL7WEyWxQdVwM1A4l/F2iHVETPzESGOMyTAInURRP0suUhb2FIho/jWXO38w4KN' .
51 'LPDGEt2jlgPBZxFKc2o8UT7Lj6SkAmfw1nx+28MkVWQlcjT9EOwjLqnpaNImi+I1j/YSl5RY/gx+' .
52 'VCCF/MnkCz4JZQtvEUXx1nyW9jCUlPVLbTJ/3MO2dsnWRq2Nwl2wTarM51rhsVEnDhT/w7C4APaJ' .
53 'ZhkIGYaUAAAAAElFTkSuQmCC'
54 );
da958e52
DO
55}
56
9077fd0e
DO
57function renderAccessDeniedImage()
58{
59 header ('Content-type: image/png');
60 // 1x1, single black pixel
61 echo base64_decode
62 (
63 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAAxJREFUCNdj' .
64 'YGBgAAAABAABJzQnCgAAAABJRU5ErkJggg=='
65 );
66}
67
9c0b0016 68// Having a local caching array speeds things up. A little.
e673ee24
DO
69function colorFromHex ($image, $hex)
70{
9c0b0016
DO
71 static $colorcache = array ();
72 if (isset ($colorcache[$hex]))
73 return $colorcache[$hex];
e673ee24
DO
74 $r = hexdec ('0x' . substr ($hex, 0, 2));
75 $g = hexdec ('0x' . substr ($hex, 2, 2));
76 $b = hexdec ('0x' . substr ($hex, 4, 2));
9c0b0016
DO
77 $c = imagecolorallocate ($image, $r, $g, $b);
78 $colorcache[$hex] = $c;
79 return $c;
e673ee24
DO
80}
81
82function renderRackThumb ($rack_id = 0)
35ee7bd0
DO
83{
84 // Don't call DB extra times, hence we are most probably not the
6b06a019 85 // only script wishing to access the same data now.
61a1d996
DO
86 if (NULL !== ($thumbcache = loadThumbCache ($rack_id)))
87 {
88 header("Content-type: image/png");
35ee7bd0 89 echo $thumbcache;
61a1d996
DO
90 return;
91 }
92 ob_start();
93 if (FALSE !== generateMiniRack ($rack_id))
35ee7bd0 94 {
61a1d996
DO
95 $capture = ob_get_clean();
96 header("Content-type: image/png");
97 echo $capture;
68a0bd8a 98 usePreparedUpdateBlade ('Rack', array ('thumb_data' => base64_encode ($capture)), array ('id' => $rack_id));
61a1d996 99 return;
35ee7bd0 100 }
61a1d996
DO
101 // error text in the buffer
102 ob_end_flush();
35ee7bd0
DO
103}
104
61a1d996
DO
105// Output a binary string containing the PNG minirack. Indicate error with return code.
106function generateMiniRack ($rack_id)
e673ee24 107{
61a1d996
DO
108 if (NULL === ($rackData = spotEntity ('rack', $rack_id)))
109 return FALSE;
110 amplifyCell ($rackData);
e673ee24 111 markupObjectProblems ($rackData);
529eac25 112 global $rtwidth;
d5157018 113 $rtdepth = 9;
e673ee24
DO
114 $offset[0] = 3;
115 $offset[1] = 3 + $rtwidth[0];
116 $offset[2] = 3 + $rtwidth[0] + $rtwidth[1];
117 $totalheight = 3 + 3 + $rackData['height'] * 2;
118 $totalwidth = $offset[2] + $rtwidth[2] + 3;
aa0e4c55
DO
119 $img = @imagecreatetruecolor ($totalwidth, $totalheight)
120 or die("Cannot Initialize new GD image stream");
9c0b0016
DO
121 // cache our palette as well
122 $color = array();
123 foreach (array ('F', 'A', 'U', 'T', 'Th', 'Tw', 'Thw') as $statecode)
d1adb55a 124 $color[$statecode] = colorFromHex ($img, getConfigVar ('color_' . $statecode));
d5157018
DO
125 $color['black'] = colorFromHex ($img, '000000');
126 $color['gray'] = colorFromHex ($img, 'c0c0c0');
127 imagerectangle ($img, 0, 0, $totalwidth - 1, $totalheight - 1, $color['black']);
128 imagerectangle ($img, 1, 1, $totalwidth - 2, $totalheight - 2, $color['gray']);
129 imagerectangle ($img, 2, 2, $totalwidth - 3, $totalheight - 3, $color['black']);
130 for ($unit_no = 1; $unit_no <= $rackData['height']; $unit_no++)
e673ee24
DO
131 {
132 for ($locidx = 0; $locidx < 3; $locidx++)
133 {
134 $colorcode = $rackData[$unit_no][$locidx]['state'];
135 if (isset ($rackData[$unit_no][$locidx]['hl']))
136 $colorcode = $colorcode . $rackData[$unit_no][$locidx]['hl'];
137 imagerectangle
138 (
139 $img,
140 $offset[$locidx],
141 3 + ($rackData['height'] - $unit_no) * 2,
142 $offset[$locidx] + $rtwidth[$locidx] - 1,
143 3 + ($rackData['height'] - $unit_no) * 2 + 1,
d1adb55a 144 $color[$colorcode]
e673ee24
DO
145 );
146 }
147 }
e673ee24
DO
148 imagepng ($img);
149 imagedestroy ($img);
61a1d996 150 return TRUE;
e673ee24
DO
151}
152
d15b2330
DO
153function renderProgressBarImage ($done)
154{
d1adb55a 155 $img = @imagecreatetruecolor (100, 10);
fec0c8da
DO
156 switch (isset ($_REQUEST['theme']) ? $_REQUEST['theme'] : 'rackspace')
157 {
158 case 'sparenetwork':
159 $color['T'] = colorFromHex ($img, '808080');
160 $color['F'] = colorFromHex ($img, 'c0c0c0');
161 break;
162 case 'rackspace': // teal
163 default:
164 $color['T'] = colorFromHex ($img, getConfigVar ('color_T'));
165 $color['F'] = colorFromHex ($img, getConfigVar ('color_F'));
166 }
d1adb55a
DO
167 imagefilledrectangle ($img, 0, 0, $done, 10, $color['T']);
168 imagefilledrectangle ($img, $done, 0, 100, 10, $color['F']);
074106cf
DO
169 for ($x = 20; $x <= 80; $x += 20)
170 {
171 $cc = $x > $done ? $color['T'] : $color['F'];
172 imagesetpixel ($img, $x, 0, $cc);
173 imagesetpixel ($img, $x, 1, $cc);
174 imagesetpixel ($img, $x, 4, $cc);
175 imagesetpixel ($img, $x, 5, $cc);
176 imagesetpixel ($img, $x, 8, $cc);
177 imagesetpixel ($img, $x, 9, $cc);
178 }
d15b2330
DO
179 header("Content-type: image/png");
180 imagepng ($img);
181 imagedestroy ($img);
d15b2330
DO
182}
183
4afb4c10 184function renderFilePreview ($file_id)
37e59768 185{
4afb4c10 186 if ($image = getFileCache ($file_id)) //Cache Hit
37e59768 187 {
4afb4c10
DO
188 header("Content-type: image/jpeg");
189 echo $image;
190 return;
37e59768 191 }
4afb4c10
DO
192 //Cache Miss
193 $file = getFile ($file_id);
194 $image = imagecreatefromstring ($file['contents']);
195 unset ($file);
196 $width = imagesx ($image);
197 $height = imagesy ($image);
198 if ($width > getConfigVar ('PREVIEW_IMAGE_MAXPXS') or $height > getConfigVar ('PREVIEW_IMAGE_MAXPXS'))
199 {
200 $ratio = getConfigVar ('PREVIEW_IMAGE_MAXPXS') / max ($width, $height);
201 $newwidth = $width * $ratio;
202 $newheight = $height * $ratio;
203 $resampled = imagecreatetruecolor ($newwidth, $newheight);
204 imagecopyresampled ($resampled, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
205 imagedestroy ($image);
206 $image = $resampled;
207 unset ($resampled);
208 }
209 header ('Content-type: image/jpeg');
210 ob_start();
211 imagejpeg ($image);
212 imagedestroy ($image);
213 commitAddFileCache ($file_id, ob_get_flush());
37e59768 214}
f537da2f 215
5c42f907
DO
216function printStatic404()
217{
218 header ('404 Not Found');
219?><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
220<html><head>
221<title>404 Not Found</title>
222</head><body>
223<h1>Not Found</h1>
224<p>The requested file was not found in this instance.</p>
225<hr>
226<address>RackTables static content proxy</address>
227</body></html><?php
228 exit;
229}
230
231function proxyStaticURI ($URI)
232{
233 $content_type = array
234 (
235 'css' => 'text/css',
236 'js' => 'text/javascript',
237 'html' => 'text/html',
238 'png' => 'image/png',
239 'gif' => 'image/gif',
240 'jpg' => 'image/jpeg',
241 'jpeg' => 'image/jpeg',
242 'ico' => 'image/x-icon',
243 );
244 $matches = array();
245 if
246 (
247 ! preg_match (RE_STATIC_URI, $URI, $matches)
248 or ! in_array ($matches[1], array ('pix', 'css', 'js'))
249 or ! array_key_exists (strtolower ($matches[2]), $content_type)
250 )
251 printStatic404();
252 global $racktables_staticdir;
253 if (FALSE === $fh = fopen ("${racktables_staticdir}/${URI}", 'r'))
254 printStatic404();
255 if (FALSE !== $stat = fstat ($fh))
256 if (checkCachedResponse (max ($stat['mtime'], $stat['ctime']), 0))
257 exit;
258 header ('Content-type: ' . $content_type[$matches[2]]);
259 fpassthru ($fh);
260 fclose ($fh);
261}
262
e673ee24 263?>