blob: 47822d1548d19b2ad271e7906a28afab043f59df [file] [log] [blame]
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// HTTP API for [] and [symbolizer.symbolizer] functionality.
library symbolizer.server;
import 'dart:convert';
import 'dart:io';
import 'package:github/github.dart';
import 'package:github/hooks.dart';
import 'package:logging/logging.dart';
import 'package:pedantic/pedantic.dart';
import 'package:symbolizer/bot.dart';
import 'package:symbolizer/symbolizer.dart';
final _log = Logger('server');
typedef _RequestHandler = Future<Object> Function(Map<String, dynamic> request);
Future<void> serve(Object address, int port,
{required Symbolizer symbolizer, required Bot bot}) async {
final handlers = <String, _RequestHandler>{
'/symbolize': (issue) => symbolizer.symbolize(issue['body']),
'/command': (event) async {
final repoOrgMember = const {'MEMBER', 'OWNER'}
final commentEvent = IssueCommentEvent.fromJson(event);
final repo = RepositorySlug.full(event['repository']['full_name']);
await bot.executeCommand(repo, commentEvent.issue!, commentEvent.comment!,
authorized: repoOrgMember);
return {'status': 'ok'};
// Start the server.
final server = await HttpServer.bind(address, port);'Listening on ${server.address}:${server.port}');
// Intentionally not processing requests in parallel to avoid racing
// in symbol cache.
await for (HttpRequest request in server) {'Incoming request: ${request.method} ${request.requestedUri}');
final handler = handlers[request.requestedUri.path];
if (request.method != 'POST' || handler == null) {
..statusCode = 404
..write('Not found');
try {
final requestObj =
await utf8.decoder.bind(request).transform(json.decoder).first;
final responseJson =
jsonEncode(await handler(requestObj as Map<String, dynamic>));
..statusCode = HttpStatus.ok
..headers.add(HttpHeaders.contentTypeHeader, 'application/json')
} catch (e, st) {
..statusCode = HttpStatus.internalServerError
..headers.add(HttpHeaders.contentTypeHeader, 'application/json')
'status': 'error',
'message': e.toString(),
'stacktrace': st.toString(),