from http import HTTP import time import os import subprocess import shutil import re SIGN = '--' CRLR = '\r\n' MAX_CHUNK = 1024 * 512 SEVEN_ZIP_BIN = '/home/tool/bin/7za' PATH = '/home/tool/config/service/FwPack/' ZIPPATH = '/tmp/FwPack' def skipHeader(inp, size): while True: line = inp.readline() size -= len(line) if line == CRLR: break return size def readFile(inp, out, size, separator): datasize = size - len(separator) toread = datasize while toread > 0: time.sleep(0.3) if toread >= MAX_CHUNK: bytes = inp.read(MAX_CHUNK) toread -= MAX_CHUNK else: bytes = inp.read(toread) toread = 0 out.write(bytes) out.flush() return len(separator) def extractFiles(filename): tmp = re.search('NxFw.+', filename) # rm possible path (IE) from filename if tmp is not None: filename = tmp.group() else: raise HTTP(202, '{"success":false, "msg":"Filename have to start with NxFw"}') fullpath = PATH + filename.split('.')[0] if not os.access(fullpath, os.F_OK): os.mkdir(fullpath) p = subprocess.Popen([SEVEN_ZIP_BIN, "x", os.path.join(ZIPPATH,'fw.zip'), "-o{0}".format(fullpath), "-y"], preexec_fn=lambda: os.nice(15), close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.communicate() if p.returncode != 0: raise Exception("Cannot extract formware") #if subprocess.call(['unzip', os.path.join(ZIPPATH,'fw.zip'), '-d', fullpath]) != 0: os.remove(os.path.join(ZIPPATH,'fw.zip')) def suckAll(inp): try: while True: inp.read(MAX_CHUNK) except: pass def process(request, environ): # prepare path if not os.access(ZIPPATH, os.F_OK): try: os.mkdir(ZIPPATH) except: environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) raise HTTP(202, '{"success":false, "msg":"Firmware update error: error creating path"}') #try: # subprocess.call(['mount', '-t', 'tmpfs', '-o', 'size=100M', 'tmpfs', ZIPPATH]) #except: # environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) # raise HTTP(202, '{"success":false, "msg":"Firmware update error: error mounting ramdisk"}') if not os.access(ZIPPATH, os.W_OK): suckAll(environ['wsgi.input']) raise HTTP(202, '{"success":false, "msg":"Firmware update error: cannot write to target path"}') try: socket = environ['wsgi.input'] size = int(environ['CONTENT_LENGTH']) ct = environ['HTTP_CONTENT_TYPE'] boundary = ct[ct.index('boundary=') + 9:] separator = CRLR + SIGN + boundary + SIGN + CRLR filename = environ['QUERY_STRING'] size = skipHeader(socket, size) with open(os.path.join(ZIPPATH,'fw.zip'), 'wb') as out: size = readFile(socket, out, size, separator) socket.read(size) except Exception as e: suckAll(environ['wsgi.input']) errStr = "Firmware update error: %s " % str(e) if os.access(ZIPPATH, os.F_OK): shutil.rmtree(ZIPPATH) raise HTTP(202, '{"success":false, "msg":"%s"}' % errStr) try: extractFiles(filename) except Exception as e: errStr = "Firmware update error: %s " % str(e) folder = PATH + filename.split('.')[0] shutil.rmtree(folder) raise HTTP(202, '{"success":false, "msg":"%s"}' % errStr) raise HTTP(202, '{"success":true, "msg":"File uploaded"}')