def setDBM(self, dbm): self.dbm = dbm #setup encryption password import anydbm dbm = anydbm.open(dbm, 'r') try: from resources.lib import encryption self.encrypt = encryption.encryption(dbm['salt'], dbm['password']) except: self.encrypt = None # login password? try: self.username = dbm['username'] self.password = dbm['password'] except: self.username = None self.password = None try: if dbm['hide'] == 'true': self.hide = True if dbm['keyvalue'] == 'true': self.keyvalue = True except: pass try: self.cryptoSalt = dbm['crypto_salt'] self.cryptoPassword = dbm['crypto_password'] except: pass dbm.close()
def main(): try: opts, args = getopt.getopt(sys.argv[1:], "s:p:d:x:z:va", [ "help", "directory=", "salt=", "password="******"search=", "replace=" ]) except getopt.GetoptError as err: # print help information and exit: print str(err) # will print something like "option -a not recognized" usage() sys.exit(2) directory = None salt = None password = None search = None replace = None verbose = False decryptOnly = False wasEncrypted = False for o, a in opts: if o in ('-v'): verbose = True elif o in ('-a'): decryptOnly = True elif o in ("-p", "--password"): password = a elif o in ("-s", "--salt"): salt = a elif o in ("-h", "--help"): print "usage: " sys.exit() elif o in ("-d", "--directory"): directory = a elif o in ("-x", "--search"): search = a elif o in ("-z", "--replace"): replace = a else: assert False, "unhandled option" if (directory is None): print "No directory (-d) provided." print "-d directory [-s salt -p salt password -x search -z replace -a]" return if (salt is None or password is None): print "Crypto salt (-s) or password (-p) not provided." return encrypt = None if (salt is not None and password is not None): encrypt = encryption.encryption(salt, password) for root, dirs, files in os.walk(directory): for filename in files: if filename.endswith(".strm"): print "reading " + str(filename) + "\n" file = open(str(root) + '/' + str(filename), "r") url = file.read() file.close() if verbose: print "url = " + str(url) + "\n" m = re.search("kv\=([^\&]+)", url) kv = None if m: kv = m.group(1) kv = encrypt.decryptString(kv) wasEncrypted = True else: kv = url m = re.search("^([^\?]+)\?", url) baseurl = None if m: baseurl = m.group(1) if verbose: print "base url = " + str(baseurl) + "\n" if verbose: print "kv = " + str(kv) + "\n" if (search is not None and replace is not None): kv = kv.replace(search, replace) if verbose: print "kv (with replacements) = " + str(kv) + "\n" file = open(str(root) + '/' + str(filename), "w") if not decryptOnly: kv = str(baseurl) + '?kv=' + str(encrypt.encryptString(kv)) file.write(str(kv) + "\n") file.close()
from resources.lib import encryption #from subprocess import call import sys import re import os saltFile = str(sys.argv[1]) password = str(sys.argv[2]) source = str(sys.argv[3]) target = str(sys.argv[4]) encrypt = encryption.encryption(saltFile, password) #encrypt.encryptString(file) #print encrypt.decryptString(file) def encrypt_dir(source, target): current, dirs, files = os.walk(source).next() for file in files: encFile = encrypt.encryptString(file) encrypt.encryptFile( str(source) + '/' + str(file), str(target) + '/' + str(encFile)) print str(source) + '/' + str(file) + ' -> ' + str(target) + '/' + str( encFile) for dir in dirs: encDIR = encrypt.encryptString(dir) os.mkdir(str(target) + '/' + str(encDIR))
from resources.lib import encryption #from subprocess import call import sys import re import os saltFile = str(sys.argv[1]) password = str(sys.argv[2]) stringToEncrypt = str(sys.argv[3]) encrypt = encryption.encryption(saltFile,password) #encrypt.encryptString(file) print encrypt.encryptString(stringToEncrypt) #encrypt.decryptStream #encrypt.encryptFile(file) #encrypt.decryptFile(file+'.enc')
def do_GET(self): # debug - print headers in log headers = str(self.headers) print(headers) start = '' end = '' startOffset = 0 for r in re.finditer('Range\:\s+bytes\=(\d+)\-', headers, re.DOTALL): start = int(r.group(1)) break for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)', headers, re.DOTALL): end = int(r.group(1)) break # passed a kill signal? if self.path == '/kill': self.server.ready = False return # redirect url to output elif self.path == '/play': if (self.server.crypto and start != '' and start > 16 and end == ''): #start = start - (16 - (end % 16)) xbmc.log("START = " + str(start)) startOffset = 16 - ((int(self.server.length) - start) % 16) + 8 # if (self.server.crypto and start == 23474184 ): #start = start - (16 - (end % 16)) # start = 23474184 - 8 url = self.server.playbackURL xbmc.log('GET ' + url + "\n" + self.server.service.getHeadersEncoded() + "\n") if start == '': req = urllib2.Request(url, None, self.server.service.getHeadersList()) else: req = urllib2.Request( url, None, self.server.service.getHeadersList( additionalHeader='Range', additionalValue='bytes=' + str(start - startOffset) + '-' + str(end))) try: response = urllib2.urlopen(req) except urllib2.URLError, e: if e.code == 403 or e.code == 401: xbmc.log("ERROR\n" + self.server.service.getHeadersEncoded()) self.server.service.refreshToken() req = urllib2.Request(url, None, self.server.service.getHeadersList()) try: response = urllib2.urlopen(req) except: xbmc.log("STILL ERROR\n" + self.server.service.getHeadersEncoded()) return else: return if start == '': self.send_response(200) self.send_header('Content-Length', response.info().getheader('Content-Length')) else: self.send_response(206) self.send_header( 'Content-Length', str( int(response.info().getheader('Content-Length')) - startOffset)) #self.send_header('Content-Range','bytes ' + str(start) + '-' +str(end)) if end == '': self.send_header( 'Content-Range', 'bytes ' + str(start) + '-' + str(int(self.server.length) - 1) + '/' + str(int(self.server.length))) else: self.send_header( 'Content-Range', 'bytes ' + str(start) + '-' + str(end) + '/' + str(int(self.server.length))) #self.send_header('Content-Range',response.info().getheader('Content-Range')) xbmc.log('Content-Range!!!' + str(start) + '-' + str(int(self.server.length) - 1) + '/' + str(int(self.server.length)) + "\n") xbmc.log(str(response.info()) + "\n") self.send_header('Content-Type', response.info().getheader('Content-Type')) # self.send_header('Content-Length',response.info().getheader('Content-Length')) self.send_header('Cache-Control', response.info().getheader('Cache-Control')) self.send_header('Date', response.info().getheader('Date')) self.send_header('Content-type', 'video/mp4') self.send_header('Accept-Ranges', 'bytes') self.end_headers() ## may want to add more granular control over chunk fetches #self.wfile.write(response.read()) if (self.server.crypto): self.server.settings.setCryptoParameters() from resources.lib import encryption decrypt = encryption.encryption( self.server.settings.cryptoSalt, self.server.settings.cryptoPassword) CHUNK = 16 * 1024 decrypt.decryptStreamChunkOld(response, self.wfile, startOffset=startOffset) else: CHUNK = 16 * 1024 while True: chunk = response.read(CHUNK) if not chunk: break self.wfile.write(chunk) response.close()
# self.send_header('Accept-Ranges','bytes') #self.send_header('ETag',response.info().getheader('ETag')) #self.send_header('Server',response.info().getheader('Server')) self.end_headers() ## may want to add more granular control over chunk fetches #self.wfile.write(response.read()) if (self.server.crypto): self.server.settings.setCryptoParameters() from resources.lib import encryption decrypt = encryption.encryption( self.server.settings.cryptoSalt, self.server.settings.cryptoPassword) CHUNK = 16 * 1024 decrypt.decryptStreamChunkOld(response, self.wfile, CHUNK) else: CHUNK = 16 * 1024 while True: chunk = response.read(CHUNK) if not chunk: break self.wfile.write(chunk) #response_data = response.read() response.close()
def do_GET(self): # debug - print headers in log headers = str(self.headers) print(headers) start = '' end = '' startOffset = 0 for r in re.finditer('Range\:\s+bytes\=(\d+)\-' , headers, re.DOTALL): start = int(r.group(1)) break for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)' , headers, re.DOTALL): end = int(r.group(1)) break # passed a kill signal? if self.path == '/kill': self.server.ready = False return # redirect url to output elif self.path == '/play': if (self.server.crypto and start != '' and start > 16 and end == ''): #start = start - (16 - (end % 16)) xbmc.log("START = " + str(start)) startOffset = 16-(( int(self.server.length) - start) % 16)+8 # if (self.server.crypto and start == 23474184 ): #start = start - (16 - (end % 16)) # start = 23474184 - 8 url = self.server.playbackURL xbmc.log('GET ' + url + "\n" + self.server.service.getHeadersEncoded() + "\n") if start == '': req = urllib2.Request(url, None, self.server.service.getHeadersList()) else: req = urllib2.Request(url, None, self.server.service.getHeadersList(additionalHeader='Range', additionalValue='bytes='+str(start- startOffset)+'-' + str(end))) try: response = urllib2.urlopen(req) except urllib2.URLError, e: if e.code == 403 or e.code == 401: xbmc.log("ERROR\n" + self.server.service.getHeadersEncoded()) self.server.service.refreshToken() req = urllib2.Request(url, None, self.server.service.getHeadersList()) try: response = urllib2.urlopen(req) except: xbmc.log("STILL ERROR\n" + self.server.service.getHeadersEncoded()) return else: return if start == '': self.send_response(200) self.send_header('Content-Length',response.info().getheader('Content-Length')) else: self.send_response(206) self.send_header('Content-Length', str(int(response.info().getheader('Content-Length'))-startOffset)) #self.send_header('Content-Range','bytes ' + str(start) + '-' +str(end)) if end == '': self.send_header('Content-Range','bytes ' + str(start) + '-' +str(int(self.server.length)-1) + '/' +str(int(self.server.length))) else: self.send_header('Content-Range','bytes ' + str(start) + '-' + str(end) + '/' +str(int(self.server.length))) #self.send_header('Content-Range',response.info().getheader('Content-Range')) xbmc.log('Content-Range!!!' + str(start) + '-' + str(int(self.server.length)-1) + '/' +str(int(self.server.length)) + "\n") xbmc.log(str(response.info()) + "\n") self.send_header('Content-Type',response.info().getheader('Content-Type')) # self.send_header('Content-Length',response.info().getheader('Content-Length')) self.send_header('Cache-Control',response.info().getheader('Cache-Control')) self.send_header('Date',response.info().getheader('Date')) self.send_header('Content-type','video/mp4') self.send_header('Accept-Ranges','bytes') self.end_headers() ## may want to add more granular control over chunk fetches #self.wfile.write(response.read()) if (self.server.crypto): self.server.settings.setCryptoParameters() from resources.lib import encryption decrypt = encryption.encryption(self.server.settings.cryptoSalt,self.server.settings.cryptoPassword) CHUNK = 16 * 1024 decrypt.decryptStreamChunkOld(response,self.wfile, startOffset=startOffset) else: CHUNK = 16 * 1024 while True: chunk = response.read(CHUNK) if not chunk: break self.wfile.write(chunk) response.close()
self.send_header('Content-type','video/mp4') # self.send_header('Accept-Ranges','bytes') #self.send_header('ETag',response.info().getheader('ETag')) #self.send_header('Server',response.info().getheader('Server')) self.end_headers() ## may want to add more granular control over chunk fetches #self.wfile.write(response.read()) if (self.server.crypto): self.server.settings.setCryptoParameters() from resources.lib import encryption decrypt = encryption.encryption(self.server.settings.cryptoSalt,self.server.settings.cryptoPassword) CHUNK = 16 * 1024 decrypt.decryptStreamChunkOld(response,self.wfile, CHUNK) else: CHUNK = 16 * 1024 while True: chunk = response.read(CHUNK) if not chunk: break self.wfile.write(chunk) #response_data = response.read() response.close()
def do_GET(self): decryptkeyvalue = self.path if re.search(r'kv\=', str(self.path)): from resources.lib import encryption results = re.search(r'kv\=(.*)$', str(self.path)) if results: keyvalue = str(results.group(1)) decryptkeyvalue = '/' + self.server.encrypt.decryptString( keyvalue).strip() print decryptkeyvalue + "." # debug - print headers in log headers = str(self.headers) print(headers) start = '' end = '' startOffset = 0 for r in re.finditer('Range\:\s+bytes\=(\d+)\-', headers, re.DOTALL): start = int(r.group(1)) break for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)', headers, re.DOTALL): end = int(r.group(1)) break # passed a kill signal? if decryptkeyvalue == '/kill': self.send_response(200) self.end_headers() if self.server.username is not None: self.wfile.write( '<html><form action="/kill" method="post">Username: <input type="text" name="username"><br />Password: <input type="password" name="password"><br /><input type="submit" value="Stop Server"></form></html>' ) else: self.wfile.write( '<html><form action="/kill" method="post"><input type="submit" value="Stop Server"></form></html>' ) #self.server.ready = False return elif decryptkeyvalue == '/settings': self.send_response(200) self.end_headers() self.setings = {} file = open('./resources/settings.xml', "r") print "LOAD SETTINGS\n\n\n" for line in file: result = re.search( r'\<setting id\=\"([^\"]+)\" type\=\"([^\"]+)\" values\=\"([^\"]+)\" default\=\"([^\"]+)\" label\=\"([^\"]+)\" \/\>', str(line)) if result is None: result = re.search( r'\<setting id\=\"([^\"]+)\" type\=\"([^\"]+)\"( )label\=\"([^\"]+)\" default\=\"([^\"]+)\" \/\>', str(line)) id = '' type = '' values = '' defaults = '' label = '' if result: id = str(result.group(1)) type = str(result.group(2)) values = str(result.group(3)) defaults = str(result.group(4)) label = str(result.group(5)) print "ID = " + id + "\n" elif decryptkeyvalue == '/list' or decryptkeyvalue == '/': self.send_response(200) self.end_headers() if self.server.username is not None: self.wfile.write( '<html><form action="/list" method="post">Username: <input type="text" name="username"><br />Password: <input type="password" name="password"><br /><input type="submit" value="Login"></form></html>' ) else: self.wfile.write( '<html><form action="/list" method="post"><input type="submit" value="Login"></form></html>' ) #self.server.ready = False return #self.send_response(200) #self.end_headers() #xbmcplugin.assignOutputBuffer(self.wfile) mediaEngine = default.contentengine() mediaEngine.run(self, DBM=self.server.dbm, addon=self.server.addon) #self.wfile.write(outputBuffer) return # redirect url to output elif re.search(r'/play', str(decryptkeyvalue)): # self.send_response(200) # self.end_headers() count = 0 isEncrypted = False results = re.search(r'/play\?count\=(\d+)\&encrypted\=true$', str(decryptkeyvalue)) #encrypted stream if results: count = int(results.group(1)) isEncrypted = True #not encrypted stream else: results = re.search(r'/play\?count\=(\d+)$', str(decryptkeyvalue)) if results: count = int(results.group(1)) #self.send_response(200) #self.end_headers() #xbmcplugin.assignOutputBuffer(self.wfile) #cookies = self.headers['Cookie'] cookie = xbmcplugin.playbackBuffer.playback[count]['cookie'] url = xbmcplugin.playbackBuffer.playback[count]['url'] auth = xbmcplugin.playbackBuffer.playback[count]['auth'] auth = auth.replace("+", ' ') length = 0 try: length = xbmcplugin.playbackBuffer.playback[count]['length'] except: length = 0 start = '' endOffset = 0 startOffset = 0 newEnd = end specialEnd = 0 if isEncrypted: from resources.lib import encryption decrypt = encryption.encryption(self.server.cryptoSalt, self.server.cryptoPassword) # # 1) start > 16 bytes, back up to nearest whole chunk of 16 if (start != '' and start > 16 and end == ''): #start = start - (16 - (end % 16)) # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD startOffset = 16 - ((int(length) - start) % 16) + 8 newEnd = int(xbmcplugin.playbackBuffer.playback[count] ['length']) - 1 print "[1] START=" + str(start) + ', END=' + str( end ) + ', length=' + str(length) + ' , startOffset=' + str( startOffset) + ' , endOffset=' + str( endOffset) + ', newEnd=' + str(newEnd) + "\n" #tested - good** # 2) start > 16 bytes, back up to nearest whole chunk of 16, end < end of file elif (start != '' and start > 16 and end == int(xbmcplugin.playbackBuffer.playback[count] ['decryptedlength']) - 1): finalChunkDifference = int( xbmcplugin.playbackBuffer.playback[count]['length'] ) - int(xbmcplugin.playbackBuffer.playback[count] ['decryptedlength']) #start = start - (16 - (end % 16)) # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD #startOffset = -(( int(end) - start - finalChunkDifference) % 16) startOffset += finalChunkDifference - 8 newEnd = int(xbmcplugin.playbackBuffer.playback[count] ['length']) - 1 startOffset += 16 - ((end - start + 1) % 16) print "[2] START=" + str(start) + ', END=' + str( end ) + ', length=' + str(length) + ' , startOffset=' + str( startOffset) + ' , endOffset=' + str( endOffset) + ', newEnd=' + str(newEnd) + "\n" #tested - good** # fetch all, return all elif (start == 0 and end == int(xbmcplugin.playbackBuffer.playback[count] ['decryptedlength']) - 1): finalChunkDifference = int( xbmcplugin.playbackBuffer.playback[count]['length'] ) - int(xbmcplugin.playbackBuffer.playback[count] ['decryptedlength']) - 8 #start = start - (16 - (end % 16)) # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD startOffset = 0 newEnd = int(xbmcplugin.playbackBuffer.playback[count] ['length']) - 1 print "[5] START=" + str(start) + ', END=' + str( end ) + ', length=' + str(length) + ' , startOffset=' + str( startOffset) + ' , endOffset=' + str( endOffset) + ', newEnd=' + str(newEnd) + "\n" #?issue *problems elif (start != '' and start > 16 and end != ''): #start = start - (16 - (end % 16)) # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD #startOffset = 16-(( int(end+1) - start) % 16)+8 startOffset = 0 #8 endOffset = 16 - ((end - start + 1 + 8) % 16) newEnd = end + endOffset + 8 #specialEnd = endOffset print "[3] START=" + str(start) + ', END=' + str( end ) + ', length=' + str(length) + ' , startOffset=' + str( startOffset) + ' , endOffset=' + str( endOffset) + ', newEnd=' + str(newEnd) + "\n" #tested - good** # special case - end < 16 (such as first 2 bytes (apple) elif (end < 16): #start = start - (16 - (end % 16)) # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD endOffset = 16 - int(end) newEnd = 15 + 8 print "[4] START=" + str(start) + ', END=' + str( end ) + ', length=' + str(length) + ' , startOffset=' + str( startOffset) + ' , endOffset=' + str( endOffset) + ', newEnd=' + str(newEnd) + "\n" if start == '': # req = urllib2.Request(url, None, { 'Cookie' : 'DRIVE_STREAM='+ cookie, 'Authorization' : auth}) req = urllib2.Request(url, None, { 'Cookie': 'DRIVE_STREAM=' + cookie, 'Authorization': auth }) else: req = urllib2.Request( url, None, { 'Cookie': 'DRIVE_STREAM=' + cookie, 'Authorization': auth, 'Range': 'bytes=' + str(int(start - startOffset)) + '-' + str(newEnd) }) #req = urllib2.Request(url, None, { 'Cookie' : 'DRIVE_STREAM='+ cookie, 'Authorization' : auth, 'Range': 'bytes='+str(int(start- startOffset))+'-' + str(int(xbmcplugin.playbackBuffer.playback[count]['decryptedlength'])-1)}) try: response = urllib2.urlopen(req) except urllib2.URLError, e: if e.code == 403 or e.code == 401: print "STILL ERROR" + str(e.code) + "\n" return else: return # first fetch (no start specified, or 0) if start == '': xbmcplugin.playbackBuffer.playback[count][ 'length'] = response.info().getheader('Content-Length') #for encrypted streams # need to fetch the last 16 bytes to calculate unpadded size if isEncrypted: response.close() req = urllib2.Request( url, None, { 'Cookie': 'DRIVE_STREAM=' + cookie, 'Authorization': auth, 'Range': 'bytes=' + str( int(xbmcplugin.playbackBuffer.playback[count] ['length']) - 16 - 8) + '-' }) try: response = urllib2.urlopen(req) except urllib2.URLError, e: if e.code == 403 or e.code == 401: print "STILL ERROR" + str(e.code) + "\n" return else: return CHUNK = 16 * 1024 #originalSize = decrypt.decryptCalculateSizing(response) #print "size " + response.info().getheader('Content-Length') + ' vs ' + str(originalSize) + "\n" #return finalChunkDifference = decrypt.decryptCalculatePadding( response, chunksize=CHUNK) #xbmcplugin.playbackBuffer.playback[count]['length'] = int(xbmcplugin.playbackBuffer.playback[count]['length']) - finalChunkDifference xbmcplugin.playbackBuffer.playback[count][ 'decryptedlength'] = int( xbmcplugin.playbackBuffer.playback[count] ['length']) - finalChunkDifference - 8 print "FINAL CHUNK SIZE DIFFERENCE " + str( finalChunkDifference) + "\n" print "length " + str(xbmcplugin.playbackBuffer. playback[count]['length']) + "\n" print "decryptedlength " + str( xbmcplugin.playbackBuffer.playback[count] ['decryptedlength']) + "\n" req = urllib2.Request(url, None, { 'Cookie': 'DRIVE_STREAM=' + cookie, 'Authorization': auth }) try: response = urllib2.urlopen(req) except urllib2.URLError, e: if e.code == 403 or e.code == 401: print "STILL ERROR" + str(e.code) + "\n" return else: return
def do_GET(self): # debug - print headers in log headers = str(self.headers) print(headers) start = '' end = '' startOffset = 0 for r in re.finditer('Range\:\s+bytes\=(\d+)\-', headers, re.DOTALL): start = int(r.group(1) ) break for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)', headers, re.DOTALL): end = int(r.group(1) ) break # passed a kill signal? if self.path == '/kill': self.server.ready = False return # redirect url to output elif self.path == '/play': if (self.server.crypto and start != '' and start > 16 and end == ''): #start = start - (16 - (end % 16) ) xbmc.log("START = " + str(start) ) startOffset = 16 - ( (int(self.server.length) - start) % 16) + 8 # if (self.server.crypto and start == 23474184): #start = start - (16 - (end % 16) ) # start = 23474184 - 8 url = self.server.playbackURL xbmc.log('GET ' + url + "\n" + self.server.service.getHeadersEncoded() + "\n") if start == '': req = urllib.request.Request(url, None, self.server.service.getHeadersList() ) else: req = urllib.request.Request(url, None, self.server.service.getHeadersList(additionalHeader='Range', additionalValue='bytes=' + str(start- startOffset) + '-' + str(end) ) ) try: response = urllib.request.urlopen(req) except urllib.error.URLError as e: if e.code == 403 or e.code == 401: xbmc.log("ERROR\n" + self.server.service.getHeadersEncoded() ) self.server.service.refreshToken() req = urllib.request.Request(url, None, self.server.service.getHeadersList() ) try: response = urllib.request.urlopen(req) except: xbmc.log("STILL ERROR\n" + self.server.service.getHeadersEncoded() ) return else: return if start == '': self.send_response(200) self.send_header('Content-Length', response.info().get('Content-Length') ) else: self.send_response(206) self.send_header('Content-Length', str(int(response.info().get('Content-Length') ) - startOffset) ) #self.send_header('Content-Range', 'bytes ' + str(start) + '-' + str(end) ) if end == '': self.send_header('Content-Range', 'bytes ' + str(start) + '-' + str(int(self.server.length) - 1) + '/' + str(int(self.server.length) ) ) else: self.send_header('Content-Range', 'bytes ' + str(start) + '-' + str(end) + '/' + str(int(self.server.length) ) ) #self.send_header('Content-Range', response.info().get('Content-Range') ) xbmc.log('Content-Range!!!' + str(start) + '-' + str(int(self.server.length) - 1) + '/' + str(int(self.server.length) ) + "\n") xbmc.log(str(response.info() ) + "\n") self.send_header('Content-Type', response.info().get('Content-Type') ) # self.send_header('Content-Length', response.info().get('Content-Length') ) self.send_header('Cache-Control', response.info().get('Cache-Control') ) self.send_header('Date', response.info().get('Date') ) self.send_header('Content-type', 'video/mp4') self.send_header('Accept-Ranges', 'bytes') self.end_headers() ## may want to add more granular control over chunk fetches #self.wfile.write(response.read() ) if (self.server.crypto): from resources.lib import encryption decrypt = encryption.encryption(self.server.addon.getSetting("crypto_salt"), self.server.addon.getSetting("crypto_password") ) CHUNK = 16 * 1024 decrypt.decryptStreamChunkOld(response, self.wfile, startOffset=startOffset) response.close() # redirect url to output elif self.path == '/enroll': self.send_response(200) self.end_headers() self.wfile.write(b''' <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .container { position: absolute; top: 50%; left: 50%; -moz-transform: translateX(-50%) translateY(-50%); -webkit-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); background-color: 080808; border: 1px solid black; height: 200px; width: 300px; background-color: #0F0F0F; box-shadow: 5px 10px; } .inner { position: absolute; top: 50%; left: 50%; -moz-transform: translateX(-50%) translateY(-50%); -webkit-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); } .input { width: 200px; height: 26px; border: 0.6px solid black; background-color: #2E2E2E; } .button { width: 200px; height: 26px; border: 0.6px solid black; background-color: #1D1D1D; margin-top: 21px; } body { background-color: #080808; } </style> </head> <body> <div class="container"> <form action="/enroll?default=false" method="post"> <div class="inner"> <input div class="input" style="color:white" type="text" name="client_id" placeholder="Client ID"> <br/> <br/> <input div class="input" style="color:white" type="text" name="client_secret" placeholder="Client Secret"> <br/> <input div class="button" style="color:white" type="submit" value="Submit"> </div> </div> </form> </body> </html>''') return