from http import HTTP import time import os import subprocess import shutil SIGN = '--' CRLR = '\r\n' MAX_CHUNK = 1024 * 512 progress = 0.0 PATH = '/mnt/data/fw' TARGET = 'rootfs.ubi' def skipHeader(inp, size): while True: line = inp.readline() size -= len(line) if line == CRLR: break return size def readFile(inp, out, size, separator): global progress datasize = size - len(separator) toread = datasize progress = 0.0 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) progress = float(datasize - toread) / datasize progress = 1.0 out.flush() return len(separator) def suckAll(inp): try: while True: inp.read(MAX_CHUNK) except: pass def process(request, environ): global progress # progress request if environ['REQUEST_URI'].startswith('/BS350/default/upload/upload/progress'): raise HTTP(202, str(progress)) # prepare path if not os.access(PATH, os.F_OK): try: os.mkdir(PATH) except: progress = 0.0 environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) raise HTTP(202, '{"success":false, "msg":"Firmware update error: error creating path"}') if not os.access(PATH, 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 size = skipHeader(socket, size) with open(os.path.join(PATH, TARGET), '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) shutil.rmtree(PATH) raise HTTP(202, '{"success":false, "msg":"%s"}' % errStr) progress = 0.0 raise HTTP(202, '{"success":true, "msg":"File uploaded"}')