MCPcopy Create free account
hub / github.com/Hieromon/AutoConnect / UpdateHTTPRequestHandler

Class UpdateHTTPRequestHandler

src/updateserver/python3/updateserver.py:32–118  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

30
31
32class UpdateHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
33 def __init__(self, catalog_dir, *args):
34 self.catalog_dir = catalog_dir
35 http.server.BaseHTTPRequestHandler.__init__(self, *args)
36
37 def do_GET(self):
38 request_path = urllib.parse.urlparse(self.path)
39 if request_path.path == '/_catalog':
40 err = ''
41 query = urllib.parse.urlparse(self.path).query
42 try:
43 op = urllib.parse.parse_qs(query)['op'][0]
44 if op == 'list':
45 try:
46 path = urllib.parse.parse_qs(query)['path'][0]
47 except KeyError:
48 path = '.'
49 full_path = os.path.join(self.catalog_dir, path)
50 if os.path.commonprefix((os.path.realpath(full_path), self.catalog_dir)) == self.catalog_dir:
51 self.__send_dir(full_path)
52 result = True
53 else:
54 err = 'Path traversal detected'
55 result = False
56 else:
57 err = '{0} unknown operation'.format(op)
58 result = False
59 except KeyError:
60 err = '{0} invaid catalog request'.format(self.path)
61 result = False
62 if not result:
63 logger.info(err)
64 self.send_response(http.HTTPStatus.FORBIDDEN, err)
65 self.end_headers()
66 else:
67 self.__send_file(self.path)
68
69 def __check_header(self):
70 ex_headers_templ = ['x-*-STA-MAC', 'x-*-AP-MAC', 'x-*-FREE-SPACE', 'x-*-SKETCH-SIZE', 'x-*-SKETCH-MD5', 'x-*-CHIP-SIZE', 'x-*-SDK-VERSION']
71 ex_headers = []
72 ua = re.match('(ESP8266|ESP32)-http-Update', self.headers.get('User-Agent'))
73 if ua:
74 arch = ua.group().split('-')[0]
75 ex_headers = list(map(lambda x: x.replace('*', arch), ex_headers_templ))
76 else:
77 logger.info('User-Agent {0} is not HTTPUpdate'.format(ua))
78 return False
79 for ex_header in ex_headers:
80 if ex_header not in self.headers:
81 logger.info('Missing header {0} to identify a legitimate request'.format(ex_header))
82 return False
83 return True
84
85 def __send_file(self, path):
86 if not self.__check_header():
87 self.send_response(http.HTTPStatus.FORBIDDEN, 'The request available only from ESP8266 or ESP32 http updater.')
88 self.end_headers()
89 return

Callers 1

handlerMethod · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected