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