| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:convert' show |
| 6 JSON, |
| 7 UTF8; |
| 8 |
| 9 import 'dart:isolate' show |
| 10 RawReceivePort; |
| 11 |
| 12 import 'dart:io'; |
| 13 |
| 14 import 'package:fasta/src/errors.dart' show |
| 15 defaultServerAddress; |
| 16 |
| 17 badRequest(HttpRequest request, int status, String message) { |
| 18 request.response.statusCode = status; |
| 19 request.response.write(''' |
| 20 <!DOCTYPE html> |
| 21 <html lang="en"> |
| 22 <head> |
| 23 <meta charset="utf-8"> |
| 24 <title>$message</title> |
| 25 </head> |
| 26 <body> |
| 27 <h1>$message</h1> |
| 28 </body> |
| 29 </html> |
| 30 '''); |
| 31 request.response.close().catchError((e, s) { |
| 32 print("Request error: $e."); |
| 33 }); |
| 34 print("${request.uri}: $message"); |
| 35 } |
| 36 |
| 37 collectLog(DateTime time, HttpRequest request) async { |
| 38 String json = await request.transform(UTF8.decoder).join(); |
| 39 var data; |
| 40 try { |
| 41 data = JSON.decode(json); |
| 42 } on FormatException catch (e) { |
| 43 print(e); |
| 44 return badRequest(request, HttpStatus.BAD_REQUEST, |
| 45 "Malformed JSON data: ${e.message}."); |
| 46 } |
| 47 if (data is! Map) { |
| 48 return badRequest(request, HttpStatus.BAD_REQUEST, |
| 49 "Malformed JSON data: not a map."); |
| 50 } |
| 51 if (data["type"] != "crash") { |
| 52 return badRequest(request, HttpStatus.BAD_REQUEST, |
| 53 "Malformed JSON data: type should be 'crash'."); |
| 54 } |
| 55 request.response.close(); |
| 56 String year = "${time.year}".padLeft(4, "0"); |
| 57 String month = "${time.month}".padLeft(2, "0"); |
| 58 String day = "${time.day}".padLeft(2, "0"); |
| 59 String us = "${time.microsecondsSinceEpoch}".padLeft(19, '0'); |
| 60 Uri uri = Uri.base.resolve( |
| 61 "crash_logs/${data['client']}/$year-$month-$day/$us.log"); |
| 62 File file = new File.fromUri(uri); |
| 63 await file.parent.create(recursive: true); |
| 64 await file.writeAsString(json); |
| 65 print("Wrote ${uri.toFilePath()}"); |
| 66 |
| 67 String type = data["type"]; |
| 68 String text = data["uri"]; |
| 69 uri = text == null ? null : Uri.parse(text); |
| 70 int charOffset = data["offset"]; |
| 71 var error = data["error"]; |
| 72 text = data["trace"]; |
| 73 StackTrace trace = text == null ? null : new StackTrace.fromString(text); |
| 74 String client = data["client"]; |
| 75 print(""" |
| 76 date: ${time} |
| 77 type: $type |
| 78 client: $client |
| 79 uri: $uri |
| 80 offset: $charOffset |
| 81 error: |
| 82 $error |
| 83 trace: |
| 84 $trace |
| 85 """); |
| 86 } |
| 87 |
| 88 main(List<String> arguments) async { |
| 89 RawReceivePort keepAlive = new RawReceivePort(); |
| 90 Uri uri; |
| 91 if (arguments.length == 1) { |
| 92 uri = Uri.base.resolve(arguments.single); |
| 93 } else if (arguments.length == 0) { |
| 94 uri = Uri.parse(defaultServerAddress); |
| 95 } else { |
| 96 throw "Unexpected arguments: ${arguments.join(' ')}."; |
| 97 } |
| 98 int port = uri.hasPort ? uri.port : 0; |
| 99 var host = uri.host.isEmpty ? InternetAddress.LOOPBACK_IP_V4 : uri.host; |
| 100 HttpServer server = await HttpServer.bind(host, port); |
| 101 print("Listening on http://${server.address.host}:${server.port}/"); |
| 102 await for (HttpRequest request in server) { |
| 103 if (request.method != "POST") { |
| 104 badRequest(request, HttpStatus.METHOD_NOT_ALLOWED, "Not allowed."); |
| 105 continue; |
| 106 } |
| 107 if (request.uri.path != "/") { |
| 108 badRequest(request, HttpStatus.NOT_FOUND, "Not found."); |
| 109 continue; |
| 110 } |
| 111 collectLog(new DateTime.now(), request); |
| 112 } |
| 113 keepAlive.close(); |
| 114 } |
| OLD | NEW |