Skip to content
New issue

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

Another py3 version #1

Open
beardhatcode opened this issue Aug 26, 2020 · 1 comment
Open

Another py3 version #1

beardhatcode opened this issue Aug 26, 2020 · 1 comment

Comments

@beardhatcode
Copy link

beardhatcode commented Aug 26, 2020

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:

  • I got rid of the evil zip wrapper (it is no longer needed)
  • I added some tests
  • Some other pyton3 things
  • Added doctype to the HTML

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("")
@beardhatcode beardhatcode changed the title An other py3 version Another py3 version Aug 26, 2020
@CoolCat467
Copy link

@beardhatcode Most recent no longer has the evil zip stream wrapper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants