Home | History | Annotate | Download | only in endpoints
      1 # Copyright (c) 2015 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import json
      6 import logging
      7 import os
      8 import re
      9 import webapp2
     10 import uuid
     11 
     12 from . import trace_info
     13 from . import cloud_config
     14 
     15 import cloudstorage as gcs
     16 
     17 from google.appengine.api import datastore_errors
     18 
     19 default_retry_params = gcs.RetryParams(initial_delay=0.2,
     20                                        max_delay=5.0,
     21                                        backoff_factor=2,
     22                                        max_retry_period=15)
     23 gcs.set_default_retry_params(default_retry_params)
     24 
     25 
     26 class UploadPage(webapp2.RequestHandler):
     27 
     28   def get(self):
     29     self.response.out.write("""
     30           <html><body>
     31             <head><title>Performance Insights - Trace Uploader</title></head>
     32             <form action="/upload" enctype="multipart/form-data" method="post">
     33               <div><input type="file" name="trace"/></div>
     34               <div><input type="submit" value="Upload"></div>
     35             </form><hr>
     36           </body></html>""")
     37 
     38   def post(self):
     39     trace_uuid = str(uuid.uuid4())
     40 
     41     gcs_path = '/%s/%s.gz' % (
     42         cloud_config.Get().trace_upload_bucket, trace_uuid)
     43     gcs_file = gcs.open(gcs_path,
     44                         'w',
     45                         content_type='application/octet-stream',
     46                         options={},
     47                         retry_params=default_retry_params)
     48     gcs_file.write(self.request.get('trace'))
     49     gcs_file.close()
     50 
     51     trace_object = trace_info.TraceInfo(id=trace_uuid)
     52     trace_object.remote_addr = os.environ["REMOTE_ADDR"]
     53 
     54     for arg in self.request.arguments():
     55       arg_key = arg.replace('-', '_').lower()
     56       if arg_key in trace_object._properties:
     57         try:
     58           setattr(trace_object, arg_key, self.request.get(arg))
     59         except datastore_errors.BadValueError:
     60           pass
     61 
     62     scenario_config = self.request.get('config')
     63     if scenario_config:
     64       config_json = json.loads(scenario_config)
     65       if 'scenario_name' in config_json:
     66         trace_object.scenario_name = config_json['scenario_name']
     67 
     68     tags_string = self.request.get('tags')
     69     if tags_string:
     70       # Tags are comma separated and should only include alphanumeric + '-'.
     71       if re.match('^[a-zA-Z0-9-,]+$', tags_string):
     72         trace_object.tags = tags_string.split(',')
     73       else:
     74         logging.warning('The provided tags string includes one or more invalid'
     75                         ' characters and will be ignored')
     76 
     77     trace_object.ver = self.request.get('product-version')
     78     trace_object.put()
     79 
     80     self.response.write(trace_uuid)
     81 
     82 app = webapp2.WSGIApplication([('/upload', UploadPage)])
     83