From 3299e24f9bcb9c02ea10cac3553377a235c86d00 Mon Sep 17 00:00:00 2001 From: Jeremy Kescher Date: Tue, 28 Jan 2020 14:49:32 +0100 Subject: [PATCH] server check now fully works, woohoo --- lib/server.dart | 5 +- lib/serverlist.dart | 165 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 131 insertions(+), 39 deletions(-) diff --git a/lib/server.dart b/lib/server.dart index 48060cc..ee7f2a2 100644 --- a/lib/server.dart +++ b/lib/server.dart @@ -1,9 +1,10 @@ -enum ServerStatus { unknown, timeout, responding, dnserror } +enum ServerStatus { unknown, ok, notok, timeout, dnserror, toomanyredirects } class Server { - String uri; String displayName; + String uri; ServerStatus status = ServerStatus.unknown; + double ping; Server( this.displayName, diff --git a/lib/serverlist.dart b/lib/serverlist.dart index 2338262..d7b1a9f 100644 --- a/lib/serverlist.dart +++ b/lib/serverlist.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:basic_utils/basic_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; +import 'package:http/src/response.dart'; import 'package:server_pinger/server.dart'; import 'server.dart'; @@ -40,7 +41,7 @@ class _ServerListState extends State { ), new Server( "My VPS", - "https://vps1.kescher.at", + "http://kescher.at", ), new Server( "Raspberry Pi", @@ -66,18 +67,13 @@ class _ServerListState extends State { } void _updateServerStatus(Server s) { - checkStatus(s.uri).then((value) { - if (value != s.status) - setState(() { - s.status = value; - }); + _checkStatus(s.uri).then((value) { + setState(() { + s.status = value; + }); }); } - void _updateUI() { - setState(() {}); - } - @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done @@ -180,7 +176,8 @@ class _ServerListState extends State { children: [ info, Container( - decoration: BoxDecoration(border: Border(top: BorderSide(color: Colors.grey))), + decoration: BoxDecoration( + border: Border(top: BorderSide(color: Colors.grey))), ), Text('Ping: 1111'), ], @@ -233,41 +230,135 @@ class _ServerListState extends State { return list; } - static Future checkStatus(String uri) async { + static Future _checkStatus(String uri, + {int iterations = 0}) async { Uri parsedUri; + try { parsedUri = Uri.parse(uri); } catch (FormatException) { - print("The URI was invalid, returning DNS_ERROR"); return ServerStatus.dnserror; } - if (parsedUri.isScheme("http") || parsedUri.isScheme("http")) {} - try { - InternetAddress ia = InternetAddress(parsedUri.host); - //parsedUri.scheme - } catch (ArgumentError) { - List record = - await DnsUtils.lookupRecord(parsedUri.host, RRecordType.ANY); - } - return ServerStatus.responding; + if (parsedUri.isScheme("http") || parsedUri.isScheme("https")) { + InternetAddress ia; + try { + ia = InternetAddress(parsedUri.host); + return await _checkResponse(parsedUri, iterations); + } catch (ArgumentError) /* Host is a DNS name */ { + try { + var v4recs = await DnsUtils.lookupRecord(parsedUri.host, RRecordType.A); + var v6recs = + await DnsUtils.lookupRecord(parsedUri.host, RRecordType.AAAA); + var v4 = await _getDNS(v4recs, RRecordType.A); + var v6 = await _getDNS(v6recs, RRecordType.AAAA); + if (v4 != "" && v6 != "") { + return ServerStatus.dnserror; + } + } catch (SocketException) { + return ServerStatus.dnserror; + } + + return await _checkResponse(parsedUri, iterations); + } + } else // non-HTTP scheme + return ServerStatus.unknown; } Icon _generateIcon(Server server) { - if (server.status == ServerStatus.unknown) - return new Icon( - Icons.check_box_outline_blank, - color: Colors.yellow, - ); - else if (server.status == ServerStatus.responding) - return new Icon( - Icons.check_box, - color: Colors.green, - ); - else - return new Icon( - Icons.indeterminate_check_box, - color: Colors.red, - ); + switch (server.status) { + case ServerStatus.unknown: + return new Icon( + Icons.sync, + color: Colors.blueGrey.shade400, + ); + break; + case ServerStatus.ok: + return new Icon( + Icons.check_box, + color: Colors.green.shade400, + ); + break; + case ServerStatus.notok: + return new Icon( + Icons.indeterminate_check_box, + color: Colors.red, + ); + break; + case ServerStatus.timeout: + return new Icon( + Icons.timer_off, + color: Colors.yellowAccent.shade700, + ); + break; + case ServerStatus.dnserror: + return new Icon( + Icons.dns, + color: Colors.red.shade400, + ); + break; + case ServerStatus.toomanyredirects: + return new Icon( + Icons.subdirectory_arrow_right, + color: Colors.red.shade400, + ); + break; + } + } + + static _getDNS(List records, RRecordType type) { + String _return; + if (records == null) return ServerStatus.dnserror; + + records.forEach((record) { + if (record != null) { + return; + } + + if (record == null) { + // ignore: unrelated_type_equality_checks + if (record.rType == type) { + _return = record.data; + } + } + }); + if (_return == null) _return = ""; + return _return; + } + + static Future _checkResponse(Uri uri, int iterations) async { + var scheme = uri.scheme; + var port = uri.port; + var host = uri.host; + var location = uri.path; + + for (int i = 0; i < 5; i++) { + Response response = await HttpUtils.getForFullResponse( + scheme + "://" + host, + headers: {"Location": location}) + .timeout(new Duration(seconds: 3)); + if (response.statusCode > 199 && response.statusCode < 300) { + return ServerStatus.ok; + } else if (response.statusCode == HttpStatus.movedPermanently || + response.statusCode == HttpStatus.found || + response.statusCode == HttpStatus.temporaryRedirect || + response.statusCode == HttpStatus.permanentRedirect) { + if (iterations < 5) return ServerStatus.toomanyredirects; + var responseLocation = response.headers["Location"]; + if (responseLocation.startsWith("http://") || + responseLocation.startsWith("https://")) { + return await _checkStatus(responseLocation, + iterations: iterations + 1); + } + location = responseLocation; + return await _checkStatus( + scheme + "://" + host + ":" + port.toString() + location, + iterations: iterations + 1); + } else { + return ServerStatus.notok; + } + } + // Too many redirects + return ServerStatus.unknown; } } -- 2.47.0