Home | History | Annotate | Download | only in perfetto-site.appspot.com
      1 # Copyright (C) 2018 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 from google.appengine.api import memcache
     16 from google.appengine.api import urlfetch
     17 
     18 import re
     19 import webapp2
     20 
     21 MEMCACHE_TTL_SEC= 60 * 60 * 24
     22 BASE = 'https://catapult-project.github.io/perfetto/%s'
     23 HEADERS = {'last-modified', 'content-type',
     24            'content-length', 'content-encoding', 'etag'}
     25 
     26 
     27 class MainHandler(webapp2.RequestHandler):
     28     def get(self):
     29         handler = GithubMirrorHandler()
     30         handler.initialize(self.request, self.response)
     31         return handler.get("index.html")
     32 
     33 
     34 class GithubMirrorHandler(webapp2.RequestHandler):
     35     def get(self, resource):
     36         if not re.match('^[a-zA-Z0-9-_./]*$', resource):
     37             self.response.set_status(403)
     38             return
     39 
     40         url = BASE % resource
     41         cache = memcache.get(url)
     42         if not cache or self.request.get('reload'):
     43             result = urlfetch.fetch(url)
     44             if result.status_code != 200:
     45                 memcache.delete(url)
     46                 self.response.set_status(result.status_code)
     47                 self.response.write(result.content)
     48                 return
     49             cache = {'content-type': 'text/html'}
     50             for k, v in result.headers.iteritems():
     51                 k = k.lower()
     52                 if k in HEADERS:
     53                     cache[k] = v
     54             cache['content'] = result.content
     55             memcache.set(url, cache, time=MEMCACHE_TTL_SEC)
     56 
     57         for k, v in cache.iteritems():
     58             if k != 'content':
     59                 self.response.headers[k] = v
     60         self.response.headers['cache-control'] = 'public,max-age=600'
     61         self.response.write(cache['content'])
     62 
     63 
     64 app = webapp2.WSGIApplication([
     65     ('/', MainHandler),
     66     ('/(.+)', GithubMirrorHandler),
     67 ], debug=True)
     68