|
2 | 2 | # -*- coding: utf-8 -*- |
3 | 3 | # |
4 | 4 | # The HTTP request handling interface for raspend. |
5 | | -# 'raspend' stands for RaspberryPi EndPoint. |
| 5 | +# 'raspend' stands for RaspberryPi Backend. |
6 | 6 | # |
7 | 7 | # License: MIT |
8 | 8 | # |
|
11 | 11 | from functools import partial |
12 | 12 | from http.server import BaseHTTPRequestHandler |
13 | 13 | import json |
| 14 | +import urllib |
14 | 15 |
|
15 | 16 | from .utils import stoppablehttpserver |
16 | 17 |
|
@@ -181,28 +182,81 @@ def onGetCmds(self): |
181 | 182 | self.dataLock.release() |
182 | 183 | return strJsonResponse |
183 | 184 |
|
| 185 | + def onGetCmd(self, queryParams): |
| 186 | + """ Call a command via HTTP GET. The response will be the command's return value as a JSON string. |
| 187 | + """ |
| 188 | + strJsonResponse = "" |
| 189 | + |
| 190 | + cmdName = queryParams["name"][0] |
| 191 | + cmdArgs = dict() |
| 192 | + |
| 193 | + cmd = self.commandMap.get(cmdName) |
| 194 | + |
| 195 | + if cmd == None: |
| 196 | + self.send_error(404, ("Command '{0}' not found!".format(cmdName))) |
| 197 | + return |
| 198 | + |
| 199 | + del (queryParams["name"]) |
| 200 | + |
| 201 | + for k,v in queryParams.items(): |
| 202 | + cmdArgs[k] = v[0] |
| 203 | + |
| 204 | + result = "" |
| 205 | + |
| 206 | + try: |
| 207 | + result = cmd.execute(cmdArgs) |
| 208 | + except Exception as e: |
| 209 | + self.send_error(500, "An unexpected error occured during execution of '{0}'! Exception: {1}".format(cmdName, e)) |
| 210 | + return |
| 211 | + |
| 212 | + strJsonResponse = json.dumps(result, ensure_ascii=False) |
| 213 | + |
| 214 | + try: |
| 215 | + self.send_response(200) |
| 216 | + self.send_header('Content-type', 'application/json; charset=utf-8') |
| 217 | + self.send_header('Access-Control-Allow-Origin', '*') |
| 218 | + self.end_headers() |
| 219 | + self.wfile.write(bytes(strJsonResponse, 'utf-8')) |
| 220 | + except OSError: |
| 221 | + self.send_error(500) |
| 222 | + except BlockingIOError: |
| 223 | + self.send_error(500) |
| 224 | + except Exception as e: |
| 225 | + self.send_error(500, "An unexpected error occured during execution of '{0}'! Exception: {1}".format(cmdName, e)) |
| 226 | + return |
| 227 | + |
184 | 228 | def do_GET(self): |
185 | 229 | """ Handle HTTP GET request |
186 | 230 |
|
187 | 231 | '/data' : returns the whole 'dataDict' as JSON string |
188 | 232 | '/data/key' : returns sub-element of 'dataDict' as JSON string |
189 | 233 | '/cmds' : returns the list of available commands |
190 | 234 | """ |
| 235 | + urlComponents = urllib.parse.urlparse(self.path) |
| 236 | + queryParams = urllib.parse.parse_qs(urlComponents.query) |
| 237 | + |
191 | 238 | strJsonResponse = "" |
192 | | - |
193 | | - if self.path.lower() == "/cmds": |
| 239 | + |
| 240 | + if urlComponents.path.lower() == "/cmds": |
194 | 241 | if self.commandMap == None or len(self.commandMap) == 0: |
195 | | - self.send_error(501, "No commands available.") |
| 242 | + self.send_error(501, "No commands available") |
| 243 | + return |
196 | 244 | else: |
197 | 245 | strJsonResponse = self.onGetCmds() |
198 | | - elif self.path == "/data" and self.dataDict != None: |
| 246 | + elif urlComponents.path.lower() == "/cmd": |
| 247 | + if self.commandMap == None or len(self.commandMap) == 0: |
| 248 | + self.send_error(501, "No commands available") |
| 249 | + return |
| 250 | + else: |
| 251 | + return self.onGetCmd(queryParams) |
| 252 | + elif urlComponents.path.lower() == "/data" and self.dataDict != None: |
199 | 253 | strJsonResponse = self.onGetRootDataPath() |
200 | | - elif self.path.startswith("/data/") and self.dataDict != None: |
| 254 | + elif urlComponents.path.startswith("/data/") and self.dataDict != None: |
201 | 255 | strJsonResponse = self.onGetDetailedDataPath() |
202 | 256 | else: |
203 | 257 | self.send_error(404) |
204 | 258 | return |
205 | | - |
| 259 | + |
206 | 260 | try: |
207 | 261 | self.send_response(200) |
208 | 262 | self.send_header('Content-type', 'application/json; charset=utf-8') |
|
0 commit comments