Example #1
0
 def list_directory(
     self, path
 ):  # Patches the list_directory method so that files an be served but directories not listed.
     if config.getboolean('DEFAULT', 'servefiles') and config.getboolean(
             'DEFAULT', 'listdirs'):
         SimpleHTTPRequestHandler.list_directory(
             self, path
         )  # If listing is allowed, then do what the original method does
     else:
         self.send_error(403)  #No permission to list directory
         return None  # Effectively, all directory listing is blocked
Example #2
0
 def list_directory(self, path):
     if self.file_only:
         self.send_error(404, "No such file")
     else:
         return SimpleHTTPRequestHandler.list_directory(self, path)
Example #3
0
 def list_directory(self, path):
     if self.file_only:
         self.send_error(404, "No such file")
     else:
         return SimpleHTTPRequestHandler.list_directory(self, path)
Example #4
0
 def send_head(self):
     path = self.path.split("?",1)[0].split("#",1)[0]
     #strip path after second slash:
     while path.rfind("/", 1)>0:
         path = path[:path.rfind("/", 1)]
     script = self.script_paths.get(path)
     log("send_head() script(%s)=%s", path, script)
     if script:
         log("request for %s handled using %s", path, script)
         content = script(self)
         return content
     path = self.translate_path(self.path)
     if not path or not os.path.exists(path):
         self.send_error(404, "Path not found")
         return None
     if os.path.isdir(path):
         if not path.endswith('/'):
             # redirect browser - doing basically what apache does
             self.send_response(301)
             self.send_header("Location", path + "/")
             self.end_headers()
             return None
         for index in "index.html", "index.htm":
             index = os.path.join(path, index)
             if os.path.exists(index):
                 path = index
                 break
         else:
             if not self.directory_listing:
                 self.send_error(403, "Directory listing forbidden")
                 return None
             return SimpleHTTPRequestHandler.list_directory(self, path).read()
     ext = os.path.splitext(path)[1]
     f = None
     try:
         # Always read in binary mode. Opening files in text mode may cause
         # newline translations, making the actual size of the content
         # transmitted *less* than the content-length!
         f = open(path, 'rb')
         fs = os.fstat(f.fileno())
         content_length = fs[6]
         content_type = EXTENSION_TO_MIMETYPE.get(ext)
         if not content_type:
             if not mimetypes.inited:
                 mimetypes.init()
             ctype = mimetypes.guess_type(path, False)
             if ctype and ctype[0]:
                 content_type = ctype[0]
         log("guess_type(%s)=%s", path, content_type)
         if content_type:
             self.extra_headers["Content-type"] = content_type
         accept = self.headers.get('accept-encoding', '').split(",")
         accept = tuple(x.split(";")[0].strip() for x in accept)
         content = None
         log("accept-encoding=%s", csv(accept))
         for enc in HTTP_ACCEPT_ENCODING:
             #find a matching pre-compressed file:
             if enc not in accept:
                 continue
             compressed_path = "%s.%s" % (path, enc)     #ie: "/path/to/index.html.br"
             if not os.path.exists(compressed_path):
                 continue
             if not os.path.isfile(compressed_path):
                 log.warn("Warning: '%s' is not a file!", compressed_path)
                 continue
             if not os.access(compressed_path, os.R_OK):
                 log.warn("Warning: '%s' is not readable", compressed_path)
                 continue
             st = os.stat(compressed_path)
             if st.st_size==0:
                 log.warn("Warning: '%s' is empty", compressed_path)
                 continue
             log("sending pre-compressed file '%s'", compressed_path)
             #read pre-gzipped file:
             f.close()
             f = None
             f = open(compressed_path, 'rb')
             content = f.read()
             assert content, "no data in %s" % compressed_path
             self.extra_headers["Content-Encoding"] = enc
             break
         if not content:
             content = f.read()
             assert len(content)==content_length, \
                 "expected %s to contain %i bytes but read %i bytes" % (path, content_length, len(content))
             if content_length>128 and \
             ("gzip" in accept) and \
             ("gzip" in HTTP_ACCEPT_ENCODING) \
             and (ext not in (".png", )):
                 #gzip it on the fly:
                 import zlib
                 assert len(content)==content_length, \
                     "expected %s to contain %i bytes but read %i bytes" % (path, content_length, len(content))
                 gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)
                 compressed_content = gzip_compress.compress(content) + gzip_compress.flush()
                 if len(compressed_content)<content_length:
                     log("gzip compressed '%s': %i down to %i bytes", path, content_length, len(compressed_content))
                     self.extra_headers["Content-Encoding"] = "gzip"
                     content = compressed_content
         f.close()
         f = None
         #send back response headers:
         self.send_response(200)
         self.extra_headers.update({
             "Content-Length"    : len(content),
             "Last-Modified"     : self.date_time_string(fs.st_mtime),
             })
         self.end_headers()
     except IOError as e:
         self.close_connection = True
         log("send_head()", exc_info=True)
         log.error("Error sending '%s':", path)
         emsg = str(e)
         if emsg.endswith(": '%s'" % path):
             log.error(" %s", emsg.rsplit(":", 1)[0])
         else:
             log.error(" %s", e)
         try:
             self.send_error(404, "File not found")
         except OSError:
             log("failed to send 404 error - maybe some of the headers were already sent?", exc_info=True)
         return None
     finally:
         if f:
             try:
                 f.close()
             except OSError:
                 log("failed to close", exc_info=True)
     return content