1e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport BaseHTTPServer 2e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport SimpleHTTPServer 3e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport os 4e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport sys 5e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport urllib, urlparse 6e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport posixpath 7e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport StringIO 8e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport re 9e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport shutil 10e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport threading 11e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport time 12e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarimport socket 137ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbarimport itertools 14e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 155472249ee4281673c63db466c8670f269803469aDaniel Dunbarimport Reporter 168dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbarimport ConfigParser 17e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 1817fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar### 1917fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar# Various patterns matched or replaced by server. 2017fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar 2117fded63f9dba691d517f5c6952344d87d6338bfDaniel DunbarkReportFileRE = re.compile('(.*/)?report-(.*)\\.html') 22e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 23e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel DunbarkBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->') 24e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 257ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar# <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" --> 267ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 277ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel DunbarkReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->') 287ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel DunbarkReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"') 297ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 304d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel DunbarkReportReplacements = [] 31cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar 324d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar# Add custom javascript. 334d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel DunbarkReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\ 344d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar<script language="javascript" type="text/javascript"> 354d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbarfunction load(url) { 364d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar if (window.XMLHttpRequest) { 374d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar req = new XMLHttpRequest(); 384d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar } else if (window.ActiveXObject) { 394d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar req = new ActiveXObject("Microsoft.XMLHTTP"); 404d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar } 414d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar if (req != undefined) { 424d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar req.open("GET", url, true); 434d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar req.send(""); 444d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar } 454d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar} 464d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar</script>""")) 474d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar 484d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar# Insert additional columns. 494d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel DunbarkReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'), 504d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar '<td></td><td></td>')) 514d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar 524d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar# Insert report bug and open file links. 534d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel DunbarkReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'), 544d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' + 554d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>'))) 564d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar 5717fded63f9dba691d517f5c6952344d87d6338bfDaniel DunbarkReportReplacements.append((re.compile('<!-- REPORTHEADER -->'), 5817fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar '<h3><a href="/">Summary</a> > Report %(report)s</h3>')) 5917fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar 6017fded63f9dba691d517f5c6952344d87d6338bfDaniel DunbarkReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'), 6117fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>')) 6217fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar 637ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar# Insert report crashes link. 647ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 65b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar# Disabled for the time being until we decide exactly when this should 66b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar# be enabled. Also the radar reporter needs to be fixed to report 67b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar# multiple files. 68b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar 69b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'), 70b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar# '<br>These files will automatically be attached to ' + 71b5f9a4ea171931a2092aa466046251629c75e65bDaniel Dunbar# 'reports filed here: <a href="report_crashes">Report Crashes</a>.')) 727ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 734d20cf759d96ac194ae27aa81cb127cd0619d0ddDaniel Dunbar### 74b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar# Other simple parameters 75b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar 76b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel DunbarkResources = posixpath.join(posixpath.dirname(__file__), 'Resources') 778dcd940c0f00530e0e8ca55be1193382e80227caDaniel DunbarkConfigPath = os.path.expanduser('~/.scanview.cfg') 78b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar 79e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar### 80e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 81e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar__version__ = "0.1" 82e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 83e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar__all__ = ["create_server"] 84e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 85e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarclass ReporterThread(threading.Thread): 86e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def __init__(self, report, reporter, parameters, server): 87e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar threading.Thread.__init__(self) 88e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.report = report 89e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.server = server 90e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.reporter = reporter 91e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.parameters = parameters 9247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar self.success = False 93e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.status = None 94e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 95e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def run(self): 96e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar result = None 97e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 98e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.server.options.debug: 99e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],) 10047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar self.status = self.reporter.fileReport(self.report, self.parameters) 10147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar self.success = True 102e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar time.sleep(3) 103e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.server.options.debug: 104e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],) 1055472249ee4281673c63db466c8670f269803469aDaniel Dunbar except Reporter.ReportFailure,e: 10647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar self.status = e.value 107e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except Exception,e: 108e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar s = StringIO.StringIO() 109e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar import traceback 11047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar print >>s,'<b>Unhandled Exception</b><br><pre>' 111e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar traceback.print_exc(e,file=s) 112e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>s,'</pre>' 113e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.status = s.getvalue() 114e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 115e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarclass ScanViewServer(BaseHTTPServer.HTTPServer): 116e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def __init__(self, address, handler, root, reporters, options): 117e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar BaseHTTPServer.HTTPServer.__init__(self, address, handler) 118e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.root = root 119e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.reporters = reporters 120e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.options = options 121e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.halted = False 1228dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.config = None 1238dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.load_config() 124e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 1258dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar def load_config(self): 1268dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.config = ConfigParser.RawConfigParser() 1278dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar 1288dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar # Add defaults 1298dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.config.add_section('ScanView') 1307ad535db066b6f5e31776f8a74b8f1e98b14cc7eDaniel Dunbar for r in self.reporters: 1318dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.config.add_section(r.getName()) 13219c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek for p in r.getParameters(): 133480bc342cd48896828dcf7443411e59d67aeb2aaTed Kremenek if p.saveConfigValue(): 13419c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek self.config.set(r.getName(), p.getName(), '') 1358dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar 1368dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar # Ignore parse errors 1378dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar try: 1388dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.config.read([kConfigPath]) 1398dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar except: 1408dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar pass 1418dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar 1428dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar # Save on exit 1438dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar import atexit 1448dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar atexit.register(lambda: self.save_config()) 1458dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar 1468dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar def save_config(self): 1478dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar # Ignore errors (only called on exit). 1488dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar try: 1498dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar f = open(kConfigPath,'w') 1508dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar self.config.write(f) 1518dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar f.close() 1528dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar except: 1538dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar pass 1548dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar 155e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def halt(self): 156e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.halted = True 157e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.options.debug: 158e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],) 159e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 160e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def serve_forever(self): 161e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar while not self.halted: 162e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.options.debug > 1: 163e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],) 164e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 165e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.handle_request() 166e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except OSError,e: 167e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print 'OSError',e.errno 168e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 169cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar def finish_request(self, request, client_address): 170cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar if self.options.autoReload: 171cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar import ScanView 172cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler 173cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar BaseHTTPServer.HTTPServer.finish_request(self, request, client_address) 174cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar 175e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def handle_error(self, request, client_address): 176e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Ignore socket errors 177e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar info = sys.exc_info() 178e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if info and isinstance(info[1], socket.error): 179e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.options.debug > 1: 180e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],) 181e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return 182cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar BaseHTTPServer.HTTPServer.handle_error(self, request, client_address) 183e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 184e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar# Borrowed from Quixote, with simplifications. 185e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbardef parse_query(qs, fields=None): 186e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if fields is None: 187e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar fields = {} 188e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar for chunk in filter(None, qs.split('&')): 189e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if '=' not in chunk: 190e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar name = chunk 191e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar value = '' 192e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar else: 193e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar name, value = chunk.split('=', 1) 194e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar name = urllib.unquote(name.replace('+', ' ')) 195e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar value = urllib.unquote(value.replace('+', ' ')) 1967ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar item = fields.get(name) 1977ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if item is None: 1987ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar fields[name] = [value] 1997ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar else: 2007ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar item.append(value) 201e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return fields 202e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 203e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarclass ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): 204e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar server_version = "ScanViewServer/" + __version__ 205cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar dynamic_mtime = time.time() 206e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 207e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def do_HEAD(self): 208e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 209e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self) 210e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except Exception,e: 211e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.handle_exception(e) 212e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 213e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def do_GET(self): 214e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 215e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) 216e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except Exception,e: 217e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.handle_exception(e) 218e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 219e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def do_POST(self): 220e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar """Serve a POST request.""" 221e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 222e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar length = self.headers.getheader('content-length') or "0" 223e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 224e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar length = int(length) 225e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except: 226e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar length = 0 227e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar content = self.rfile.read(length) 228e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar fields = parse_query(content) 229e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar f = self.send_head(fields) 230e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if f: 231e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.copyfile(f, self.wfile) 232e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar f.close() 233e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except Exception,e: 234e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.handle_exception(e) 235e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 236e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def log_message(self, format, *args): 237e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.server.options.debug: 238e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" % 239e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar (sys.argv[0], 240e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.address_string(), 241e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.log_date_time_string(), 242e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar format%args)) 243e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 244e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def load_report(self, report): 245e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar path = os.path.join(self.server.root, 'report-%s.html'%report) 246e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar data = open(path).read() 247e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar keys = {} 248e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar for item in kBugKeyValueRE.finditer(data): 249e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar k,v = item.groups() 250e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar keys[k] = v 251e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return keys 252e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 2537ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar def load_crashes(self): 2547ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar path = posixpath.join(self.server.root, 'index.html') 2557ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar data = open(path).read() 2567ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar problems = [] 2577ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar for item in kReportCrashEntryRE.finditer(data): 2587ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar fieldData = item.group(1) 2597ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar fields = dict([i.groups() for i in 2607ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar kReportCrashEntryKeyValueRE.finditer(fieldData)]) 2617ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar problems.append(fields) 2627ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return problems 2637ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 264e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def handle_exception(self, exc): 265e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar import traceback 266e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar s = StringIO.StringIO() 267e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>s, "INTERNAL ERROR\n" 268e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar traceback.print_exc(exc, s) 269e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar f = self.send_string(s.getvalue(), 'text/plain') 270e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if f: 271e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.copyfile(f, self.wfile) 272e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar f.close() 2737ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 2747ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar def get_scalar_field(self, name): 2757ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if name in self.fields: 2767ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return self.fields[name][0] 2777ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar else: 2787ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return None 2797ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 2807ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar def submit_bug(self, c): 2817ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar title = self.get_scalar_field('title') 2827ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar description = self.get_scalar_field('description') 2837ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar report = self.get_scalar_field('report') 2847ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar reporterIndex = self.get_scalar_field('reporter') 2857ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar files = [] 2867ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar for fileID in self.fields.get('files',[]): 2877ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar try: 2887ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar i = int(fileID) 2897ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar except: 2907ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar i = None 2917ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if i is None or i<0 or i>=len(c.files): 2927ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return (False, 'Invalid file ID') 2937ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar files.append(c.files[i]) 2947ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 29547cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar if not title: 29647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar return (False, "Missing title.") 29747cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar if not description: 29847cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar return (False, "Missing description.") 29947cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar try: 3008dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar reporterIndex = int(reporterIndex) 30147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar except: 30247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar return (False, "Invalid report method.") 303e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 304e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Get the reporter and parameters. 3058dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar reporter = self.server.reporters[reporterIndex] 306e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar parameters = {} 30719c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek for o in reporter.getParameters(): 30819c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek name = '%s_%s'%(reporter.getName(),o.getName()) 30947cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar if name not in self.fields: 31047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar return (False, 31147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar 'Missing field "%s" for %s report method.'%(name, 31247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar reporter.getName())) 31319c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek parameters[o.getName()] = self.get_scalar_field(name) 314e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 3158dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar # Update config defaults. 3167ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if report != 'None': 3177ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar self.server.config.set('ScanView', 'reporter', reporterIndex) 31819c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek for o in reporter.getParameters(): 319480bc342cd48896828dcf7443411e59d67aeb2aaTed Kremenek if o.saveConfigValue(): 32019c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek name = o.getName() 32119c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek self.server.config.set(reporter.getName(), name, parameters[name]) 3228dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar 323e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Create the report. 3247ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar bug = Reporter.BugReport(title, description, files) 325e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 326e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Kick off a reporting thread. 32747cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar t = ReporterThread(bug, reporter, parameters, self.server) 328e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar t.start() 329e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 330e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Wait for thread to die... 331e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar while t.isAlive(): 332e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar time.sleep(.25) 333e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar submitStatus = t.status 334e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 33547cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar return (t.success, t.status) 33647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar 33747cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar def send_report_submit(self): 3387ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar report = self.get_scalar_field('report') 3397ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c = self.get_report_context(report) 3407ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if c.reportSource is None: 3417ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar reportingFor = "Report Crashes > " 3427ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar fileBug = """\ 3437ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar<a href="/report_crashes">File Bug</a> > """%locals() 3447ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar else: 3457ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource, 3467ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar report) 3477ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar fileBug = '<a href="/report/%s">File Bug</a> > ' % report 3487ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar title = self.get_scalar_field('title') 3497ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar description = self.get_scalar_field('description') 35047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar 3517ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar res,message = self.submit_bug(c) 35247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar 35347cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar if res: 35447cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar statusClass = 'SubmitOk' 35547cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar statusName = 'Succeeded' 35647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar else: 35747cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar statusClass = 'SubmitFail' 35847cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar statusName = 'Failed' 35947cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar 36047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar result = """ 36147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<head> 362c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel Dunbar <title>Bug Submission</title> 36347cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar <link rel="stylesheet" type="text/css" href="/scanview.css" /> 36447cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</head> 36547cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<body> 366c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel Dunbar<h3> 367c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel Dunbar<a href="/">Summary</a> > 3687ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%(reportingFor)s 3697ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%(fileBug)s 370c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel DunbarSubmit</h3> 37147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<form name="form" action=""> 37247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<table class="form"> 37347cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<tr><td> 37447cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<table class="form_group"> 37547cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<tr> 37647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar <td class="form_clabel">Title:</td> 37747cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar <td class="form_value"> 37847cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar <input type="text" name="title" size="50" value="%(title)s" disabled> 37947cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar </td> 38047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</tr> 38147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<tr> 38247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar <td class="form_label">Description:</td> 38347cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar <td class="form_value"> 38447cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<textarea rows="10" cols="80" name="description" disabled> 38547cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar%(description)s 38647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</textarea> 38747cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar </td> 38847cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</table> 38947cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</td></tr> 39047cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</table> 39147cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</form> 39247cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<h1 class="%(statusClass)s">Submission %(statusName)s</h1> 39347cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar%(message)s 39447cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<p> 395e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar<hr> 39647cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar<a href="/">Return to Summary</a> 397e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar</body> 39847cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar</html>"""%locals() 39947cceff13c109963735f3462f1226a8ae74a864bDaniel Dunbar return self.send_string(result) 400e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 40128870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar def send_open_report(self, report): 40228870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar try: 40328870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar keys = self.load_report(report) 40428870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar except IOError: 40528870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar return self.send_error(400, 'Invalid report.') 40628870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar 40728870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar file = keys.get('FILE') 40828870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar if not file or not posixpath.exists(file): 40928870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar return self.send_error(400, 'File does not exist: "%s"' % file) 41028870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar 41128870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar import startfile 41228870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar if self.server.options.debug: 41328870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0], 41428870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar file) 41528870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar 41628870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar status = startfile.open(file) 41728870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar if status: 41828870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar res = 'Opened: "%s"' % file 41928870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar else: 42028870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar res = 'Open failed: "%s"' % file 42128870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar 42228870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar return self.send_string(res, 'text/plain') 42328870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar 4247ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar def get_report_context(self, report): 4257ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar class Context: 4267ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar pass 4277ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if report is None or report == 'None': 4287ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar data = self.load_crashes() 4297ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar # Don't allow empty reports. 4307ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if not data: 4317ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar raise ValueError, 'No crashes detected!' 4327ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c = Context() 4337ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.title = 'clang static analyzer failures' 4347ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 4357ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar stderrSummary = "" 4367ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar for item in data: 4377ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if 'stderr' in item: 4387ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar path = posixpath.join(self.server.root, item['stderr']) 4397ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if os.path.exists(path): 4407ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar lns = itertools.islice(open(path), 0, 10) 4417ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar stderrSummary += '%s\n--\n%s' % (item.get('src', 4427ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar '<unknown>'), 4437ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar ''.join(lns)) 4447ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 4457ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.description = """\ 4467ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel DunbarThe clang static analyzer failed on these inputs: 4477ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%s 448e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 4497ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel DunbarSTDERR Summary 4507ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar-------------- 4517ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%s 4527ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar""" % ('\n'.join([item.get('src','<unknown>') for item in data]), 4537ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar stderrSummary) 4547ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.reportSource = None 4557ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.navMarkup = "Report Crashes > " 4567ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files = [] 4577ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar for item in data: 4587ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files.append(item.get('src','')) 4597ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files.append(posixpath.join(self.server.root, 4607ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar item.get('file',''))) 4617ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files.append(posixpath.join(self.server.root, 4627ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar item.get('clangfile',''))) 4637ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files.append(posixpath.join(self.server.root, 4647ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar item.get('stderr',''))) 4657ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files.append(posixpath.join(self.server.root, 4667ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar item.get('info',''))) 4677ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar # Just in case something failed, ignore files which don't 4687ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar # exist. 4697ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files = [f for f in c.files 4707ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if os.path.exists(f) and os.path.isfile(f)] 4717ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar else: 4727ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar # Check that this is a valid report. 4737ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar path = posixpath.join(self.server.root, 'report-%s.html' % report) 4747ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if not posixpath.exists(path): 4757ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar raise ValueError, 'Invalid report ID' 4767ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar keys = self.load_report(report) 4777ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c = Context() 4787ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.title = keys.get('DESC','clang error (unrecognized') 4797ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.description = """\ 4807ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel DunbarBug reported by the clang static analyzer. 48125b51d06991ee3b60a24ba5d303973794401d527Daniel Dunbar 48225b51d06991ee3b60a24ba5d303973794401d527Daniel DunbarDescription: %s 48325b51d06991ee3b60a24ba5d303973794401d527Daniel DunbarFile: %s 48425b51d06991ee3b60a24ba5d303973794401d527Daniel DunbarLine: %s 4857ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>')) 4867ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.reportSource = 'report-%s.html' % report 4877ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource, 4887ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar report) 4897ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 4907ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c.files = [path] 4917ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return c 4927ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 4937ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar def send_report(self, report, configOverrides=None): 4947ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar def getConfigOption(section, field): 4957ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if (configOverrides is not None and 4967ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar section in configOverrides and 4977ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar field in configOverrides[section]): 4987ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return configOverrides[section][field] 4997ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return self.server.config.get(section, field) 5007ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 5017ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar # report is None is used for crashes 5027ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar try: 5037ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar c = self.get_report_context(report) 5047ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar except ValueError, e: 5057ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return self.send_error(400, e.message) 5067ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 5077ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar title = c.title 5087ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar description= c.description 5097ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar reportingFor = c.navMarkup 5107ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if c.reportSource is None: 5117ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar extraIFrame = "" 5127ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar else: 5137ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar extraIFrame = """\ 5147ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar<iframe src="/%s" width="100%%" height="40%%" 5157ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar scrolling="auto" frameborder="1"> 5167ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar <a href="/%s">View Bug Report</a> 5177ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar</iframe>""" % (c.reportSource, c.reportSource) 518e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 519e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reporterSelections = [] 520e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reporterOptions = [] 5217ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 5228dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar try: 5237ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar active = int(getConfigOption('ScanView','reporter')) 5248dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar except: 5258dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar active = 0 526e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar for i,r in enumerate(self.server.reporters): 5278dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar selected = (i == active) 5288dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar if selected: 5298dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar selectedStr = ' selected' 5308dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar else: 5318dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar selectedStr = '' 5328dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName())) 53319c8820134605ee6cc72a18624e56041952e9ae4Ted Kremenek options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()]) 5348dcd940c0f00530e0e8ca55be1193382e80227caDaniel Dunbar display = ('none','')[selected] 53578266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar reporterOptions.append("""\ 53678266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<tr id="%sReporterOptions" style="display:%s"> 53778266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_label">%s Options</td> 53878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_value"> 53978266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <table class="form_inner_group"> 54078266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar%s 54178266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar </table> 54278266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar </td> 54378266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</tr> 54478266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar"""%(r.getName(),display,r.getName(),options)) 545e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reporterSelections = '\n'.join(reporterSelections) 546e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reporterOptionsDivs = '\n'.join(reporterOptions) 547e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters])) 548e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 5497ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if c.files: 5507ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar fieldSize = min(5, len(c.files)) 5517ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar attachFileOptions = '\n'.join(["""\ 5527ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)]) 5537ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar attachFileRow = """\ 5547ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar<tr> 5557ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar <td class="form_label">Attach:</td> 5567ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar <td class="form_value"> 5577ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar<select style="width:100%%" name="files" multiple size=%d> 5587ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%s 5597ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar</select> 5607ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar </td> 5617ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar</tr> 5627ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar""" % (min(5, len(c.files)), attachFileOptions) 5637ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar else: 5647ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar attachFileRow = "" 5657ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 566e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar result = """<html> 567e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar<head> 568c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel Dunbar <title>File Bug</title> 56978266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <link rel="stylesheet" type="text/css" href="/scanview.css" /> 570e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar</head> 571e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar<script language="javascript" type="text/javascript"> 572e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarvar reporters = %(reportersArray)s; 573e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbarfunction updateReporterOptions() { 574e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar index = document.getElementById('reporter').selectedIndex; 575e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar for (var i=0; i < reporters.length; ++i) { 576e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar o = document.getElementById(reporters[i] + "ReporterOptions"); 577e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if (i == index) { 57878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar o.style.display = ""; 579e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar } else { 580e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar o.style.display = "none"; 581e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar } 582e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar } 583e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar} 584e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar</script> 5857345e4782e1218255cad13e7bab5f8104463500dDaniel Dunbar<body onLoad="updateReporterOptions()"> 586c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel Dunbar<h3> 587c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel Dunbar<a href="/">Summary</a> > 5887ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%(reportingFor)s 589c2dd3459fede8e963e2e84a02d3083c4bc53c469Daniel DunbarFile Bug</h3> 590e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar<form name="form" action="/report_submit" method="post"> 59178266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<input type="hidden" name="report" value="%(report)s"> 59278266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar 59378266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<table class="form"> 59478266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<tr><td> 59578266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<table class="form_group"> 59678266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<tr> 59778266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_clabel">Title:</td> 59878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_value"> 5997ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar <input type="text" name="title" size="50" value="%(title)s"> 60078266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar </td> 60178266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</tr> 60278266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<tr> 60378266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_label">Description:</td> 60478266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_value"> 605e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar<textarea rows="10" cols="80" name="description"> 6067ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%(description)s 60778266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</textarea> 60878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar </td> 6097ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar</tr> 6107ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 6117ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%(attachFileRow)s 6127ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 61378266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</table> 61478266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<br> 61578266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<table class="form_group"> 61678266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<tr> 61778266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_clabel">Method:</td> 61878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <td class="form_value"> 61978266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <select id="reporter" name="reporter" onChange="updateReporterOptions()"> 62078266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar %(reporterSelections)s 62178266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar </select> 62278266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar </td> 62378266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</tr> 624e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar%(reporterOptionsDivs)s 62578266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</table> 62678266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<br> 62778266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</td></tr> 62878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar<tr><td class="form_submit"> 62978266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar <input align="right" type="submit" name="Submit" value="Submit"> 63078266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</td></tr> 63178266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar</table> 632e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar</form> 63325b51d06991ee3b60a24ba5d303973794401d527Daniel Dunbar 6347ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar%(extraIFrame)s 63525b51d06991ee3b60a24ba5d303973794401d527Daniel Dunbar 636e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar</body> 637e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar</html>"""%locals() 6387ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 639e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_string(result) 640e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 641e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def send_head(self, fields=None): 642f6a415fe4735debe6398aae241b873e332ada0dbDaniel Dunbar if (self.server.options.onlyServeLocal and 643f6a415fe4735debe6398aae241b873e332ada0dbDaniel Dunbar self.client_address[0] != '127.0.0.1'): 64457cbb0de091a05a6510f0a7278ee8da57a4d27fcTed Kremenek return self.send_error(401, 'Unauthorized host.') 645f6a415fe4735debe6398aae241b873e332ada0dbDaniel Dunbar 646e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if fields is None: 647e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar fields = {} 648e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.fields = fields 649e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 650e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar o = urlparse.urlparse(self.path) 651e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.fields = parse_query(o.query, fields) 652e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar path = posixpath.normpath(urllib.unquote(o.path)) 653e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 654e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Split the components and strip the root prefix. 655e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar components = path.split('/')[1:] 656e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 657e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Special case some top-level entries. 658e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if components: 659e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar name = components[0] 66078266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar if len(components)==2: 66178266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar if name=='report': 662e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_report(components[1]) 66328870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar elif name=='open': 66428870e141a2467c838d0554570904bcf53481b1cDaniel Dunbar return self.send_open_report(components[1]) 66578266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar elif len(components)==1: 66678266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar if name=='quit': 66778266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar self.server.halt() 66878266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar return self.send_string('Goodbye.', 'text/plain') 66978266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar elif name=='report_submit': 670e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_report_submit() 6717ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar elif name=='report_crashes': 6727ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar overrides = { 'ScanView' : {}, 6737ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 'Radar' : {}, 6747ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar 'Email' : {} } 6757ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar for i,r in enumerate(self.server.reporters): 6767ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar if r.getName() == 'Radar': 6777ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar overrides['ScanView']['reporter'] = i 6787ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar break 6797ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar overrides['Radar']['Component'] = 'llvm - checker' 6807ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar overrides['Radar']['Component Version'] = 'X' 6817ebe0ed4443428b47f04f97c86c78c1ba775cedbDaniel Dunbar return self.send_report(None, overrides) 68278266296fd201f0766b7e79319151bb4f9231e28Daniel Dunbar elif name=='favicon.ico': 683b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar return self.send_path(posixpath.join(kResources,'bugcatcher.ico')) 684e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 685e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Match directory entries. 686e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if components[-1] == '': 687e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar components[-1] = 'index.html' 688b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar 689b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar suffix = '/'.join(components) 690b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar 691b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar # The summary may reference source files on disk using rooted 692b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar # paths. Make sure these resolve correctly for now. 693b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar # FIXME: This isn't a very good idea... we should probably 694b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar # mark rooted paths somehow. 695b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar if os.path.exists(posixpath.join('/', suffix)): 696b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar path = posixpath.join('/', suffix) 697b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar else: 698b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar path = posixpath.join(self.server.root, suffix) 699b131c8ac7cc429416a2d6aaa0baccb2336883accDaniel Dunbar 700e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if self.server.options.debug > 1: 701e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0], 702e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar path) 703e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_path(path) 704e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 705e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def send_404(self): 706e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_error(404, "File not found") 707e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return None 708e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 709e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def send_path(self, path): 710e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar ctype = self.guess_type(path) 711e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if ctype.startswith('text/'): 712e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Patch file instead 713e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_patched_file(path, ctype) 714e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar else: 715e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar mode = 'rb' 716e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar try: 717e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar f = open(path, mode) 718e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar except IOError: 719e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_404() 720e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_file(f, ctype) 721e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 722e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def send_file(self, f, ctype): 723e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar # Patch files to add links, but skip binary files. 724e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_response(200) 725e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_header("Content-type", ctype) 726e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar fs = os.fstat(f.fileno()) 727e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_header("Content-Length", str(fs[6])) 728e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) 729e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.end_headers() 730e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return f 731e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 732e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def send_string(self, s, ctype='text/html', headers=True, mtime=None): 733e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar if headers: 734e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_response(200) 735e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_header("Content-type", ctype) 736e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.send_header("Content-Length", str(len(s))) 737cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar if mtime is None: 738cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar mtime = self.dynamic_mtime 739cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar self.send_header("Last-Modified", self.date_time_string(mtime)) 740e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar self.end_headers() 741e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return StringIO.StringIO(s) 742e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 743e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar def send_patched_file(self, path, ctype): 74417fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar # Allow a very limited set of variables. This is pretty gross. 74517fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar variables = {} 74617fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar variables['report'] = '' 74717fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar m = kReportFileRE.match(path) 74817fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar if m: 74917fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar variables['report'] = m.group(2) 75017fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar 7517345e4782e1218255cad13e7bab5f8104463500dDaniel Dunbar try: 7527345e4782e1218255cad13e7bab5f8104463500dDaniel Dunbar f = open(path,'r') 7537345e4782e1218255cad13e7bab5f8104463500dDaniel Dunbar except IOError: 7547345e4782e1218255cad13e7bab5f8104463500dDaniel Dunbar return self.send_404() 755e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar fs = os.fstat(f.fileno()) 756e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar data = f.read() 757cb028b0180b38c7d0404acb936d276ff050061c6Daniel Dunbar for a,b in kReportReplacements: 75817fded63f9dba691d517f5c6952344d87d6338bfDaniel Dunbar data = a.sub(b % variables, data) 759e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar return self.send_string(data, ctype, mtime=fs.st_mtime) 760e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 761e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 7627ad535db066b6f5e31776f8a74b8f1e98b14cc7eDaniel Dunbardef create_server(address, options, root): 763e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar import Reporter 764e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 765e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reporters = Reporter.getReporters() 766e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar 7677ad535db066b6f5e31776f8a74b8f1e98b14cc7eDaniel Dunbar return ScanViewServer(address, ScanViewRequestHandler, 768e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar root, 769e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar reporters, 770e33d3682b6f4ba798b9d8d6f395ac8003827c03bDaniel Dunbar options) 771