r4358 render_image.php: rename to solutions.php and add comment
[racktables] / wwwroot / index.php
1 <?php
2 ob_start();
3 # Neither "throw/catch" for custom exceptions nor printException() will
4 # work without first loading exceptions.php.
5 require_once 'inc/exceptions.php';
6 try {
7 // Code block below is a module request dispatcher. Turning it into a
8 // function will break things because of the way require() works.
9 switch (TRUE)
10 {
11 case ! array_key_exists ('module', $_REQUEST):
12 case 'interface' == $_REQUEST['module']:
13 require_once 'inc/interface.php';
14 // init.php has to be included after interface.php, otherwise the bits
15 // set by local.php get lost
16 require_once 'inc/init.php';
17 prepareNavigation();
18 // Security context is built on the requested page/tab/bypass data,
19 // do not override.
20 fixContext();
21 redirectIfNecessary();
22 assertPermission();
23 header ('Content-Type: text/html; charset=UTF-8');
24 // Only store the tab name after clearance is got. Any failure is unhandleable.
25 if (isset ($_REQUEST['tab']) and ! isset ($_SESSION['RTLT'][$pageno]['dont_remember']))
26 $_SESSION['RTLT'][$pageno] = array ('tabname' => $tabno, 'time' => time());
27 // call the main handler - page or tab handler.
28 if (isset ($tabhandler[$pageno][$tabno]))
29 call_user_func ($tabhandler[$pageno][$tabno], getBypassValue());
30 elseif (isset ($page[$pageno]['handler']))
31 $page[$pageno]['handler'] ($tabno);
32 else
33 throw new RackTablesError ("Failed to find handler for page '${pageno}', tab '${tabno}'", RackTablesError::INTERNAL);
34 // Embed the current text in OB into interface layout (the latter also
35 // empties color message buffer).
36 $contents = ob_get_contents();
37 ob_clean();
38 renderInterfaceHTML ($pageno, $tabno, $contents);
39 break;
40 case 'chrome' == $_REQUEST['module']:
41 require_once 'inc/init.php';
42 require_once 'inc/solutions.php';
43 genericAssertion ('uri', 'string');
44 proxyStaticURI ($_REQUEST['uri']);
45 break;
46 case 'download' == $_REQUEST['module']:
47 require_once 'inc/init.php';
48 $pageno = 'file';
49 $tabno = 'download';
50 fixContext();
51 assertPermission();
52 $file = getFile (getBypassValue());
53 header("Content-Type: {$file['type']}");
54 header("Content-Length: {$file['size']}");
55 if (! array_key_exists ('asattach', $_REQUEST) or $_REQUEST['asattach'] != 'no')
56 header("Content-Disposition: attachment; filename={$file['name']}");
57 echo $file['contents'];
58 break;
59 case 'image' == $_REQUEST['module']:
60 # The difference between "image" and "download" ways to serve the same
61 # picture file is that the former is used in <IMG SRC=...> construct,
62 # and the latter is accessed as a standalone URL and can reply with any
63 # Content-type. Hence "image" module indicates failures with internally
64 # built images, and "download" can return a full-fledged "permission
65 # denied" or "exception" HTML page instead of the file requested.
66 require_once 'inc/init.php'; // for authentication check
67 // 'progressbar's never change, attempt an IMS shortcut before loading init.php
68 if (@$_REQUEST['img'] == 'progressbar')
69 if (checkCachedResponse (0, CACHE_DURATION))
70 exit;
71 require_once 'inc/solutions.php';
72 try
73 {
74 dispatchImageRequest();
75 }
76 catch (RTPermissionDenied $e)
77 {
78 ob_clean();
79 renderAccessDeniedImage();
80 }
81 catch (Exception $e)
82 {
83 ob_clean();
84 renderErrorImage();
85 }
86 break;
87 case 'ajax' == $_REQUEST['module']:
88 require_once 'inc/ajax-interface.php';
89 require_once 'inc/init.php';
90 try
91 {
92 dispatchAJAXRequest();
93 }
94 catch (InvalidRequestArgException $e)
95 {
96 ob_clean();
97 echo "NAK\nMalformed request";
98 }
99 catch (Exception $e)
100 {
101 ob_clean();
102 echo "NAK\nRuntime exception: ". $e->getMessage();
103 }
104 break;
105 case 'redirect' == $_REQUEST['module']:
106 // Include init after ophandlers/snmp, not before, so local.php can redefine things.
107 require_once 'inc/ophandlers.php';
108 // snmp.php is an exception, it is treated by a special hack
109 if (isset ($_REQUEST['op']) and $_REQUEST['op'] == 'querySNMPData')
110 require_once 'inc/snmp.php';
111 require_once 'inc/init.php';
112 try
113 {
114 genericAssertion ('op', 'string');
115 $op = $_REQUEST['op'];
116 prepareNavigation();
117 $location = buildWideRedirectURL();
118 // FIXME: find a better way to handle this error
119 if ($op == 'addFile' && !isset($_FILES['file']['error']))
120 throw new RackTablesError ('File upload error, check upload_max_filesize in php.ini', RackTablesError::MISCONFIGURED);
121 fixContext();
122 if
123 (
124 !isset ($ophandler[$pageno][$tabno][$op]) or
125 !function_exists ($ophandler[$pageno][$tabno][$op])
126 )
127 throw new RackTablesError ("Invalid navigation data for '${pageno}-${tabno}-${op}'", RackTablesError::INTERNAL);
128 // We have a chance to handle an error before starting HTTP header.
129 if (!isset ($delayauth[$pageno][$tabno][$op]))
130 assertPermission();
131 # Call below does the job of bypass argument assertion, if such is required,
132 # so the ophandler function doesn't have to re-assert this portion of its
133 # arguments. And it would be even better to pass returned value to ophandler,
134 # so it is not necessary to remember the name of bypass in it.
135 getBypassValue();
136 if (strlen ($redirect_to = call_user_func ($ophandler[$pageno][$tabno][$op])))
137 $location = $redirect_to;
138 }
139 // known "soft" failures require a short error message
140 catch (InvalidRequestArgException $e)
141 {
142 ob_clean();
143 showError ($e->getMessage());
144 }
145 catch (RTDatabaseError $e)
146 {
147 ob_clean();
148 showError ('Database error: ' . $e->getMessage());
149 }
150 catch (RTPermissionDenied $e)
151 {
152 ob_clean();
153 showError ('Operation not permitted');
154 }
155 header ('Location: ' . $location);
156 // any other error requires no special handling and will be caught outside
157 break;
158 case 'popup' == $_REQUEST['module']:
159 require_once 'inc/popup.php';
160 require_once 'inc/init.php';
161 renderPopupHTML();
162 break;
163 case 'upgrade' == $_REQUEST['module']:
164 require_once 'inc/config.php'; // for CODE_VERSION
165 require_once 'inc/dictionary.php';
166 require_once 'inc/upgrade.php';
167 // Enforce default value for now, releases prior to 0.17.0 didn't support 'httpd' auth source.
168 $user_auth_src = 'database';
169 if (FALSE === @include_once 'inc/secret.php')
170 die ('<center>There is no working RackTables instance here, <a href="?module=installer">install</a>?</center>');
171 try
172 {
173 $dbxlink = new PDO ($pdo_dsn, $db_username, $db_password);
174 }
175 catch (PDOException $e)
176 {
177 die ("Database connection failed:\n\n" . $e->getMessage());
178 }
179 renderUpgraderHTML();
180 break;
181 case 'installer' == $_REQUEST['module']:
182 require_once 'inc/dictionary.php';
183 require_once 'inc/install.php';
184 renderInstallerHTML();
185 break;
186 default:
187 throw new InvalidRequestArgException ('module', $_REQUEST['module']);
188 }
189 ob_end_flush();
190 }
191 catch (Exception $e)
192 {
193 ob_end_clean();
194 # prevent message appearing in foreign tab
195 if (isset ($_SESSION['log']))
196 unset ($_SESSION['log']);
197 printException ($e);
198 }
199 ?>