Implemented server check #13
2 changed files with 131 additions and 39 deletions
|
@ -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,
|
||||
|
|
|
@ -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<ServerList> {
|
|||
),
|
||||
new Server(
|
||||
"My VPS",
|
||||
"https://vps1.kescher.at",
|
||||
"http://kescher.at",
|
||||
),
|
||||
new Server(
|
||||
"Raspberry Pi",
|
||||
|
@ -66,18 +67,13 @@ class _ServerListState extends State<ServerList> {
|
|||
}
|
||||
|
||||
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<ServerList> {
|
|||
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<ServerList> {
|
|||
return list;
|
||||
}
|
||||
|
||||
static Future<ServerStatus> checkStatus(String uri) async {
|
||||
static Future<ServerStatus> _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<RRecord> 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<RRecord> 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<ServerStatus> _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: <String, String>{"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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue