Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2753)

Unified Diff: appengine/isolate/handlers_frontend.py

Issue 2693953006: Isolate: Download files as their filename instead of hash (Closed)
Patch Set: Isolate: Download files as their filename instead of hash Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | appengine/isolate/handlers_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/isolate/handlers_frontend.py
diff --git a/appengine/isolate/handlers_frontend.py b/appengine/isolate/handlers_frontend.py
index 531dc7ae2b14d52565f38712f278f9dee4c6f2a1..f573bbd928e131442986d7522e1945f8fac30377 100644
--- a/appengine/isolate/handlers_frontend.py
+++ b/appengine/isolate/handlers_frontend.py
@@ -8,7 +8,9 @@ import cgi
import datetime
import json
import logging
+import os
import re
+import urllib
import webapp2
@@ -58,6 +60,16 @@ _GVIZ_COLUMNS_ORDER = (
'contains_lookups',
)
+_ISOLATED_ROOT_MEMBERS = (
+ 'algo',
+ 'command',
+ 'files',
+ 'includes',
+ 'read_only',
+ 'relative_cwd',
+ 'version'
M-A Ruel 2017/02/14 23:46:14 include trailing comma, so when a new line is adde
jonesmi 2017/02/16 19:17:30 Done.
+)
+
### Restricted handlers
@@ -191,7 +203,9 @@ class BrowseHandler(auth.AuthenticatingHandler):
namespace = self.request.get('namespace', 'default-gzip')
# Support 'hash' for compatibility with old links. To remove eventually.
digest = self.request.get('digest', '') or self.request.get('hash', '')
+ save_as = self.request.get('as', '')
params = {
+ u'as': unicode(save_as),
u'digest': unicode(digest),
u'namespace': unicode(namespace),
}
@@ -258,33 +272,61 @@ class ContentHandler(auth.AuthenticatingHandler):
' python isolateserver.py download -I %s --namespace %s -f %s %s'
% (sizeInMib, host, namespace, digest, digest))
else:
- self.response.headers['Content-Disposition'] = str('filename=%s'
- % digest)
- if content.startswith('{'):
- # Try to format as JSON.
- try:
- content = json.dumps(
- json.loads(content), sort_keys=True, indent=2,
- separators=(',', ': '))
- content = cgi.escape(content)
- # If we don't wrap this in html, browsers will put content in a pre
- # tag which is also styled with monospace/pre-wrap. We can't use
- # anchor tags in <pre>, so we force it to be a <div>, which happily
- # accepts links.
- content = (
- '<div style="font-family:monospace;white-space:pre-wrap;">%s'
- '</div>' % content)
- # Linkify things that look like hashes
- content = re.sub(r'([0-9a-f]{40})',
- r'<a target="_blank" href="/browse?namespace=%s' % namespace +
- r'&digest=\1">\1</a>',
- content)
- self.response.headers['Content-Type'] = 'text/html; charset=utf-8'
- except ValueError:
- pass
+ self.response.headers['Content-Disposition'] = str(
+ 'filename=%s' % self.request.get('as') or digest)
+ if self._is_isolated_format(content):
+ content = self._format_isolated_content(content, namespace)
+ self.response.headers['Content-Type'] = 'text/html; charset=utf-8'
self.response.write(content)
+ @staticmethod
+ def _is_isolated_format(content):
+ """Checks if content string is a valid .isolated format."""
+ try:
+ data = json.loads(content)
+ except ValueError:
+ return False
+ if isinstance(data, dict):
+ actual = set(data)
+ if actual.issubset(_ISOLATED_ROOT_MEMBERS) and 'files' in actual:
M-A Ruel 2017/02/14 23:46:14 return actual.issubset(_ISOLATED_ROOT_MEMBERS) and
jonesmi 2017/02/16 19:17:30 Done.
+ return True
+ return False
+
+ @staticmethod
+ def _format_isolated_content(content, namespace):
mithro 2017/02/16 00:50:52 I feel like just giving the isolate json to a temp
+ """Formats .isolated content and returns a string representation of it."""
+ try:
+ # Ensure we're working with HTML-safe content. Do this before adding
+ # our own hyperlinks because cgi.escape would replace our anchor symbols.
+ content = cgi.escape(content)
+ data = json.loads(content)
+ except ValueError:
+ return content
+
+ # Linkify all files
+ if 'files' in data:
+ hyperlinked_files = {}
+ for filepath, metadata in data['files'].iteritems():
+ if 'h' in metadata: # Only linkify files that have a digest property
M-A Ruel 2017/02/14 23:46:14 if metadata.get('h'): is safer. no need for the co
jonesmi 2017/02/16 19:17:30 Done
+ save_as = os.path.basename(filepath)
+ anchor = (r'<a target=_blank" '
+ r'href=/browse?namespace=%s&digest=%s&as=%s>'
+ r'%s</a>') % (
+ namespace, metadata['h'], urllib.quote(save_as), filepath)
+ hyperlinked_files[anchor] = metadata
+ data['files'] = hyperlinked_files
+
+ content = json.dumps(data, sort_keys=True, indent=2, separators=(',', ': '))
+ # If we don't wrap this in html, browsers will put content in a pre
+ # tag which is also styled with monospace/pre-wrap. We can't use
+ # anchor tags in <pre>, so we force it to be a <div>, which happily
+ # accepts links.
+ content = (
+ '<div style="font-family:monospace;white-space:pre-wrap;">%s'
+ '</div>' % content)
+ return content
+
class StatsHandler(webapp2.RequestHandler):
"""Returns the statistics web page."""
« no previous file with comments | « no previous file | appengine/isolate/handlers_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698