• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import json
6import logging
7import os
8import re
9import webapp2
10import uuid
11
12from . import trace_info
13from . import cloud_config
14
15import cloudstorage as gcs
16
17from google.appengine.api import datastore_errors
18
19default_retry_params = gcs.RetryParams(initial_delay=0.2,
20                                       max_delay=5.0,
21                                       backoff_factor=2,
22                                       max_retry_period=15)
23gcs.set_default_retry_params(default_retry_params)
24
25
26class 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
82app = webapp2.WSGIApplication([('/upload', UploadPage)])
83