• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
15from google.appengine.api import memcache
16from google.appengine.api import urlfetch
17
18import re
19import webapp2
20
21MEMCACHE_TTL_SEC= 60 * 60 * 24
22BASE = 'https://catapult-project.github.io/perfetto/%s'
23HEADERS = {'last-modified', 'content-type',
24           'content-length', 'content-encoding', 'etag'}
25
26
27class 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
34class 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
64app = webapp2.WSGIApplication([
65    ('/', MainHandler),
66    ('/(.+)', GithubMirrorHandler),
67], debug=True)
68