We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hi,
I started to create a py3 version of woof a couple of months ago, and now I noticed that you already pushed it here.
It's practically the same, but:
Just wanted to put this on your radar. I auropep8ed my code, so below a diff between our versions.
My code is at https://github.com/beardhatcode/python3-woof
If you are interested, I can make a PR for the tests and/or the removal of the evilZipWrapper (or you can just steal it).
1c1 < #!/usr/bin/env python3 --- > #!/usr/bin/env python 27a28 > # Python 3 support by Robbert Gurdeep Singh <[email protected]> 34d34 < import subprocess 37c37 < import urllib.request --- > import urllib 54,103d53 < class EvilZipStreamWrapper(TM): < def __init__(self, victim): < self.victim_fd = victim < self.position = 0 < self.tells = [] < self.in_file_data = 0 < < def tell(self): < self.tells.append(self.position) < return self.position < < def seek(self, offset, whence=0): < if offset != 0: < if offset == self.tells[0] + 14: < # the zipfile module tries to fix up the file header. < # write Data descriptor header instead, < # the next write from zipfile < # is CRC, compressed_size and file_size (as required) < self.write(b"PK\007\010") < elif offset == self.tells[1]: < # the zipfile module goes to the end of the file. The next < # data written definitely is infrastructure (in_file_data = 0) < self.tells = [] < self.in_file_data = 0 < else: < raise IOError("unexpected seek for EvilZipStreamWrapper") < < def write(self, data): < # only test for headers if we know that we're not writing < # (potentially compressed) data. < if self.in_file_data == 0: < if data[:4] == zipfile.stringFileHeader: < # fix the file header for extra Data descriptor < hdr = list(struct.unpack(zipfile.structFileHeader, data[:30])) < hdr[3] |= (1 << 3) < data = struct.pack(zipfile.structFileHeader, *hdr) + data[30:] < self.in_file_data = 1 < elif data[:4] == zipfile.stringCentralDir: < # fix the directory entry to match file header. < hdr = list(struct.unpack(zipfile.structCentralDir, data[:46])) < hdr[5] |= (1 << 3) < data = struct.pack(zipfile.structCentralDir, *hdr) + data[46:] < < self.position += len(data) < self.victim_fd.write(data) < < def __getattr__(self, name): < return getattr(self.victim_fd, name) < < 164d113 < ctype, pdict = cgi.parse_header(self.headers['Content-Type']) 170c119 < if "upfile" not in form: --- > if not "upfile" in form: 191,192c140,141 < destfile = os.open(destfilename, os.O_WRONLY | < os.O_CREAT | os.O_EXCL, 0o644) --- > destfile = os.open(destfilename, os.O_WRONLY | os.O_CREAT | > os.O_EXCL, 0o644) 204,205c153,154 < print("accepting uploaded file: %s -> %s" % < (upfilename, destfilename), file=sys.stderr) --- > print( > f"accepting uploaded file: {upfilename} -> {destfilename}", file=sys.stderr) 212c161,162 < txt = b"""\ --- > txt = """\ > <!DOCTYPE html> 225c175 < self.wfile.write(txt) --- > self.wfile.write(txt.encode("utf-8")) 236,247c186,201 < txt = b"""\ < <html> < <head><title>Woof Upload</title></head> < <body> < <h1>Woof Upload</title></h1> < <form name="upload" method="POST" enctype="multipart/form-data"> < <p><input type="file" name="upfile" /></p> < <p><input type="submit" value="Upload!" /></p> < </form> < </body> < </html> < """ --- > txt = """\ > <!DOCTYPE html> > <html lang="en"> > <head> > <meta charset="utf-8"/> > <title>Woof Upload</title> > </head> > <body> > <h1>Woof Upload</h1> > <form name="upload" method="POST" enctype="multipart/form-data"> > <p><input type="file" name="upfile" /></p> > <p><input type="submit" value="Upload!" /></p> > </form> > </body> > </html>""" > 252c206 < self.wfile.write(txt) --- > self.wfile.write(txt.encode("utf-8")) 271c225,226 < txt = """\ --- > txt = f"""\ > <!DOCTYPE html> 274,276c229,230 < <body>302 Found <a href="%s">here</a>.</body> < </html>\n""" % location < txt = txt.encode('ascii') --- > <body>302 Found <a href="{location}">here</a>.</body> > </html>\n""" 282c236 < self.wfile.write(txt) --- > self.wfile.write(txt.encode("utf-8")) 303c257 < print("can only serve files or directories. Aborting.", --- > print("can only serve files or directories. Aborting.", 309,310c263,265 < self.send_header("Content-Disposition", "attachment;filename=%s" % < urllib.parse.quote(os.path.basename(self.filename))) --- > safe_filename = urllib.parse.quote(os.path.basename(self.filename)) > self.send_header("Content-Disposition", > f"attachment;filename={safe_filename}") 318,320c273,274 < datafile = open(self.filename, "rb") < shutil.copyfileobj(datafile, self.wfile) < datafile.close() --- > with open(self.filename, "rb") as datafile: > shutil.copyfileobj(datafile, self.wfile) 323,335c277,288 < ezfile = EvilZipStreamWrapper(self.wfile) < zfile = zipfile.ZipFile( < ezfile, 'w', zipfile.ZIP_DEFLATED) < stripoff = os.path.dirname(self.filename) + os.sep < < for root, dirs, files in os.walk(self.filename): < for f in files: < filename = os.path.join(root, f) < if filename[:len(stripoff)] != stripoff: < raise RuntimeException( < "invalid filename assumptions, please report!") < zfile.write(filename, filename[len(stripoff):]) < zfile.close() --- > with zipfile.ZipFile(self.wfile, 'w', > zipfile.ZIP_DEFLATED) as zfile: > stripoff = os.path.dirname(self.filename) + os.sep > > for root, dirs, files in os.walk(self.filename): > for f in files: > filename = os.path.join(root, f) > if filename[:len(stripoff)] != stripoff: > raise Exception( > "invalid filename assumptions, please report!") > zfile.write( > filename, filename[len(stripoff):]) 337,341c290,293 < tfile = tarfile.open(mode=('w|' + compressed), < fileobj=self.wfile) < tfile.add(self.filename, < arcname=os.path.basename(self.filename)) < tfile.close() --- > with tarfile.open(mode=('w|' + compressed), > fileobj=self.wfile) as tfile: > tfile.add(self.filename, > arcname=os.path.basename(self.filename)) 343a296 > print(e.with_traceback()) 360,361c313,314 < print("cannot bind to IP address '%s' port %d" % < (ip_addr, port), file=sys.stderr) --- > print(f"cannot bind to IP address '{ip_addr}' port {port}", > file=sys.stderr) 368,369c321 < location = "http://%s:%s/%s" % (ip_addr, httpd.server_port, < urllib.parse.quote(os.path.basename(filename))) --- > location = f"http://{ip_addr}:{httpd.server_port}/{urllib.parse.quote(os.path.basename(filename))}" 380c332 < location = "http://%s:%s/" % (ip_addr, httpd.server_port) --- > location = f"http://{ip_addr}:{httpd.server_port}" 382c334 < print("Now serving on %s" % location) --- > print(f"Now serving on {location}") 390,394c342,348 < print(""" < Usage: %s [-i <ip_addr>] [-p <port>] [-c <count>] <file> < %s [-i <ip_addr>] [-p <port>] [-c <count>] [-z|-j|-Z|-u] <dir> < %s [-i <ip_addr>] [-p <port>] [-c <count>] -s < %s [-i <ip_addr>] [-p <port>] [-c <count>] -U --- > print(f""" > Usage: {name} [-i <ip_addr>] [-p <port>] [-c <count>] <file> > {name} [-i <ip_addr>] [-p <port>] [-c <count>] [-z|-j|-Z|-u] <dir> > {name} [-i <ip_addr>] [-p <port>] [-c <count>] -s > {name} [-i <ip_addr>] [-p <port>] [-c <count>] -U > > {name} <url> 396,397d349 < %s <url> < 401,403c353,355 < it is gzip compressed. You can specify -z for gzip compression, < -j for bzip2 compression, -Z for ZIP compression or -u for no compression. < You can configure your default compression method in the configuration --- > it is gzip compressed. You can specify -z for gzip compression, -j for > bzip2 compression, -Z for ZIP compression or -u for no compression (tar). > You can configure your default compression method in the configuration 406c358 < When -s is specified instead of a filename, %s distributes itself. --- > When -s is specified instead of a filename, {name} distributes itself. 409,410c361,362 < < defaults: count = %d, port = %d --- > > defaults: count = {defmaxdown}, port = {defport} 427c379 < """ % (name, name, name, name, name, name, defmaxdown, defport), file=sys.stderr) --- > """, file=sys.stderr) 431c383 < print(file=sys.stderr) --- > print("", file=sys.stderr) 442c394 < f = urllib.request.urlopen(url) --- > f = urllib.urlopen(url) 445c397 < disp = f_meta["Content-Disposition"] --- > disp = f_meta.getheader("Content-Disposition") 507c459 < print("downloading file: %s -> %s" % (fname, destfilename)) --- > print(f"downloading file: {fname} -> {destfilename}") 509c461 < shutil.copyfileobj(f, os.fdopen(destfile, "wb")) --- > shutil.copyfileobj(f, os.fdopen(destfile, "w")) 560,561c512,513 < "invalid download count: %r. " < "Please specify an integer >= 0." % val) --- > f"invalid download count: {val}. " > "Please specify an integer >= 0.") 571c523 < "invalid port number: %r. Please specify an integer" % val) --- > f"invalid port number: {val}. Please specify an integer") 592c544 < usage(defaultport, defaultmaxdown, "Unknown option: %r" % option) --- > usage(defaultport, defaultmaxdown, f"Unknown option: {option}") 602c554 < if woof_client(filenames[0]) != None: --- > if woof_client(filenames[0]) is not None: 612c564 < "%s: No such file or directory" % filenames[0]) --- > f"{filenames[0]}: No such file or directory") 616c568 < "%s: Neither file nor directory" % filenames[0]) --- > f"{filenames[0]}: Neither file nor directory") 633c585 < print() --- > print("")
The text was updated successfully, but these errors were encountered:
@beardhatcode Most recent no longer has the evil zip stream wrapper.
Sorry, something went wrong.
No branches or pull requests
Hi,
I started to create a py3 version of woof a couple of months ago, and now I noticed that you already pushed it here.
It's practically the same, but:
Just wanted to put this on your radar. I auropep8ed my code, so below a diff between our versions.
My code is at https://github.com/beardhatcode/python3-woof
If you are interested, I can make a PR for the tests and/or the removal of the evilZipWrapper (or you can just steal it).
The text was updated successfully, but these errors were encountered: