Serve files without wrapper if requested using /raw/ prefix
This commit is contained in:
parent
6c0062dbc1
commit
febdea6c64
4 changed files with 33 additions and 13 deletions
|
@ -38,7 +38,7 @@ def openArchive(archive_path, path_within):
|
||||||
|
|
||||||
@PluginManager.registerTo("UiRequest")
|
@PluginManager.registerTo("UiRequest")
|
||||||
class UiRequestPlugin(object):
|
class UiRequestPlugin(object):
|
||||||
def actionSiteMedia(self, path, header_length=True):
|
def actionSiteMedia(self, path, **kwargs):
|
||||||
if ".zip/" in path or ".tar.gz/" in path:
|
if ".zip/" in path or ".tar.gz/" in path:
|
||||||
path_parts = self.parsePath(path)
|
path_parts = self.parsePath(path)
|
||||||
file_path = u"%s/%s/%s" % (config.data_dir, path_parts["address"], path_parts["inner_path"].decode("utf8"))
|
file_path = u"%s/%s/%s" % (config.data_dir, path_parts["address"], path_parts["inner_path"].decode("utf8"))
|
||||||
|
@ -63,7 +63,7 @@ class UiRequestPlugin(object):
|
||||||
self.log.debug("Error opening archive file: %s" % err)
|
self.log.debug("Error opening archive file: %s" % err)
|
||||||
return self.error404(path)
|
return self.error404(path)
|
||||||
|
|
||||||
return super(UiRequestPlugin, self).actionSiteMedia(path, header_length=header_length)
|
return super(UiRequestPlugin, self).actionSiteMedia(path, **kwargs)
|
||||||
|
|
||||||
def streamFile(self, file):
|
def streamFile(self, file):
|
||||||
while 1:
|
while 1:
|
||||||
|
|
|
@ -6,14 +6,15 @@ from Translate import translate
|
||||||
|
|
||||||
@PluginManager.registerTo("UiRequest")
|
@PluginManager.registerTo("UiRequest")
|
||||||
class UiRequestPlugin(object):
|
class UiRequestPlugin(object):
|
||||||
def actionSiteMedia(self, path, header_length=True):
|
def actionSiteMedia(self, path, **kwargs):
|
||||||
file_name = path.split("/")[-1]
|
file_name = path.split("/")[-1]
|
||||||
if not file_name: # Path ends with /
|
if not file_name: # Path ends with /
|
||||||
file_name = "index.html"
|
file_name = "index.html"
|
||||||
extension = file_name.split(".")[-1]
|
extension = file_name.split(".")[-1]
|
||||||
if translate.lang != "en" and extension in ["js", "html"]:
|
if translate.lang != "en" and extension in ["js", "html"]:
|
||||||
path_parts = self.parsePath(path)
|
path_parts = self.parsePath(path)
|
||||||
file_generator = super(UiRequestPlugin, self).actionSiteMedia(path, header_length=False)
|
kwargs["header_length"] = False
|
||||||
|
file_generator = super(UiRequestPlugin, self).actionSiteMedia(path, **kwargs)
|
||||||
if "next" in dir(file_generator): # File found and generator returned
|
if "next" in dir(file_generator): # File found and generator returned
|
||||||
site = self.server.sites.get(path_parts["address"])
|
site = self.server.sites.get(path_parts["address"])
|
||||||
return self.actionPatchFile(site, path_parts["inner_path"], file_generator)
|
return self.actionPatchFile(site, path_parts["inner_path"], file_generator)
|
||||||
|
@ -21,7 +22,7 @@ class UiRequestPlugin(object):
|
||||||
return file_generator
|
return file_generator
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return super(UiRequestPlugin, self).actionSiteMedia(path)
|
return super(UiRequestPlugin, self).actionSiteMedia(path, **kwargs)
|
||||||
|
|
||||||
def actionUiMedia(self, path):
|
def actionUiMedia(self, path):
|
||||||
file_generator = super(UiRequestPlugin, self).actionUiMedia(path)
|
file_generator = super(UiRequestPlugin, self).actionUiMedia(path)
|
||||||
|
|
|
@ -12,7 +12,7 @@ class UiRequestPlugin(object):
|
||||||
super(UiRequestPlugin, self).__init__(*args, **kwargs)
|
super(UiRequestPlugin, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
# Media request
|
# Media request
|
||||||
def actionSiteMedia(self, path, header_length=True):
|
def actionSiteMedia(self, path, **kwargs):
|
||||||
match = re.match("/media/(?P<address>[A-Za-z0-9-]+\.[A-Za-z0-9\.-]+)(?P<inner_path>/.*|$)", path)
|
match = re.match("/media/(?P<address>[A-Za-z0-9-]+\.[A-Za-z0-9\.-]+)(?P<inner_path>/.*|$)", path)
|
||||||
if match: # Its a valid domain, resolve first
|
if match: # Its a valid domain, resolve first
|
||||||
domain = match.group("address")
|
domain = match.group("address")
|
||||||
|
|
|
@ -99,6 +99,9 @@ class UiRequest(object):
|
||||||
return self.actionDebug()
|
return self.actionDebug()
|
||||||
elif path == "/Console" and config.debug:
|
elif path == "/Console" and config.debug:
|
||||||
return self.actionConsole()
|
return self.actionConsole()
|
||||||
|
# Wrapper-less static files
|
||||||
|
elif path.startswith("/raw/"):
|
||||||
|
return self.actionSiteMedia(path.replace("/raw", "/media", 1), header_noscript=True)
|
||||||
# Site media wrapper
|
# Site media wrapper
|
||||||
else:
|
else:
|
||||||
if self.get.get("wrapper_nonce"):
|
if self.get.get("wrapper_nonce"):
|
||||||
|
@ -164,6 +167,22 @@ class UiRequest(object):
|
||||||
self.user = UserManager.user_manager.create()
|
self.user = UserManager.user_manager.create()
|
||||||
return self.user
|
return self.user
|
||||||
|
|
||||||
|
def getRequestUrl(self):
|
||||||
|
if self.isProxyRequest():
|
||||||
|
if self.env["PATH_INFO"].startswith("http://zero"):
|
||||||
|
return self.env["PATH_INFO"]
|
||||||
|
else: # Add http://zero to direct domain access
|
||||||
|
return self.env["PATH_INFO"].replace("http://", "http://zero/", 1)
|
||||||
|
else:
|
||||||
|
return self.env["wsgi.url_scheme"] + "://" + self.env["HTTP_HOST"] + self.env["PATH_INFO"]
|
||||||
|
|
||||||
|
def getReferer(self):
|
||||||
|
referer = self.env.get("HTTP_REFERER")
|
||||||
|
if referer and self.isProxyRequest() and not referer.startswith("http://zero"):
|
||||||
|
return referer.replace("http://", "http://zero/", 1)
|
||||||
|
else:
|
||||||
|
return referer
|
||||||
|
|
||||||
# Send response headers
|
# Send response headers
|
||||||
def sendHeader(self, status=200, content_type="text/html", extra_headers=[]):
|
def sendHeader(self, status=200, content_type="text/html", extra_headers=[]):
|
||||||
headers = []
|
headers = []
|
||||||
|
@ -383,7 +402,7 @@ class UiRequest(object):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Serve a media for site
|
# Serve a media for site
|
||||||
def actionSiteMedia(self, path, header_length=True):
|
def actionSiteMedia(self, path, header_length=True, header_noscript=False):
|
||||||
if ".." in path: # File not in allowed path
|
if ".." in path: # File not in allowed path
|
||||||
return self.error403("Invalid file path")
|
return self.error403("Invalid file path")
|
||||||
|
|
||||||
|
@ -391,7 +410,7 @@ class UiRequest(object):
|
||||||
|
|
||||||
# Check wrapper nonce
|
# Check wrapper nonce
|
||||||
content_type = self.getContentType(path_parts["inner_path"])
|
content_type = self.getContentType(path_parts["inner_path"])
|
||||||
if "htm" in content_type: # Valid nonce must present to render html files
|
if "htm" in content_type and not header_noscript: # Valid nonce must present to render html files
|
||||||
wrapper_nonce = self.get.get("wrapper_nonce")
|
wrapper_nonce = self.get.get("wrapper_nonce")
|
||||||
if wrapper_nonce not in self.server.wrapper_nonces:
|
if wrapper_nonce not in self.server.wrapper_nonces:
|
||||||
return self.error403("Wrapper nonce error. Please reload the page.")
|
return self.error403("Wrapper nonce error. Please reload the page.")
|
||||||
|
@ -415,7 +434,7 @@ class UiRequest(object):
|
||||||
if not address or address == ".":
|
if not address or address == ".":
|
||||||
return self.error403(path_parts["inner_path"])
|
return self.error403(path_parts["inner_path"])
|
||||||
if os.path.isfile(file_path): # File exists
|
if os.path.isfile(file_path): # File exists
|
||||||
return self.actionFile(file_path, header_length=header_length)
|
return self.actionFile(file_path, header_length=header_length, header_noscript=header_noscript)
|
||||||
elif os.path.isdir(file_path): # If this is actually a folder, add "/" and redirect
|
elif os.path.isdir(file_path): # If this is actually a folder, add "/" and redirect
|
||||||
return self.actionRedirect("./{0}/".format(path_parts["inner_path"].split("/")[-1]))
|
return self.actionRedirect("./{0}/".format(path_parts["inner_path"].split("/")[-1]))
|
||||||
else: # File not exists, try to download
|
else: # File not exists, try to download
|
||||||
|
@ -429,7 +448,7 @@ class UiRequest(object):
|
||||||
|
|
||||||
result = site.needFile(path_parts["inner_path"], priority=15) # Wait until file downloads
|
result = site.needFile(path_parts["inner_path"], priority=15) # Wait until file downloads
|
||||||
if result:
|
if result:
|
||||||
return self.actionFile(file_path, header_length=header_length)
|
return self.actionFile(file_path, header_length=header_length, header_noscript=header_noscript)
|
||||||
else:
|
else:
|
||||||
self.log.debug("File not found: %s" % path_parts["inner_path"])
|
self.log.debug("File not found: %s" % path_parts["inner_path"])
|
||||||
# Site larger than allowed, re-add wrapper nonce to allow reload
|
# Site larger than allowed, re-add wrapper nonce to allow reload
|
||||||
|
@ -459,15 +478,13 @@ class UiRequest(object):
|
||||||
return self.error400()
|
return self.error400()
|
||||||
|
|
||||||
# Stream a file to client
|
# Stream a file to client
|
||||||
def actionFile(self, file_path, block_size=64 * 1024, send_header=True, header_length=True):
|
def actionFile(self, file_path, block_size=64 * 1024, send_header=True, header_length=True, header_noscript=False):
|
||||||
if ".." in file_path:
|
if ".." in file_path:
|
||||||
raise Exception("Invalid path")
|
raise Exception("Invalid path")
|
||||||
if os.path.isfile(file_path):
|
if os.path.isfile(file_path):
|
||||||
# Try to figure out content type by extension
|
# Try to figure out content type by extension
|
||||||
content_type = self.getContentType(file_path)
|
content_type = self.getContentType(file_path)
|
||||||
|
|
||||||
# TODO: Dont allow external access: extra_headers=
|
|
||||||
# [("Content-Security-Policy", "default-src 'unsafe-inline' data: http://localhost:43110 ws://localhost:43110")]
|
|
||||||
range = self.env.get("HTTP_RANGE")
|
range = self.env.get("HTTP_RANGE")
|
||||||
range_start = None
|
range_start = None
|
||||||
if send_header:
|
if send_header:
|
||||||
|
@ -476,6 +493,8 @@ class UiRequest(object):
|
||||||
extra_headers["Accept-Ranges"] = "bytes"
|
extra_headers["Accept-Ranges"] = "bytes"
|
||||||
if header_length:
|
if header_length:
|
||||||
extra_headers["Content-Length"] = str(file_size)
|
extra_headers["Content-Length"] = str(file_size)
|
||||||
|
if header_noscript:
|
||||||
|
extra_headers["Content-Security-Policy"] = "default-src 'none'; sandbox allow-top-navigation; img-src 'self'; style-src 'self' 'unsafe-inline';"
|
||||||
if range:
|
if range:
|
||||||
range_start = int(re.match(".*?([0-9]+)", range).group(1))
|
range_start = int(re.match(".*?([0-9]+)", range).group(1))
|
||||||
if re.match(".*?-([0-9]+)", range):
|
if re.match(".*?-([0-9]+)", range):
|
||||||
|
|
Loading…
Reference in a new issue