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 {
|
class Server {
|
||||||
String uri;
|
|
||||||
String displayName;
|
String displayName;
|
||||||
|
String uri;
|
||||||
ServerStatus status = ServerStatus.unknown;
|
ServerStatus status = ServerStatus.unknown;
|
||||||
|
double ping;
|
||||||
|
|
||||||
Server(
|
Server(
|
||||||
this.displayName,
|
this.displayName,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'dart:io';
|
||||||
import 'package:basic_utils/basic_utils.dart';
|
import 'package:basic_utils/basic_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||||
|
import 'package:http/src/response.dart';
|
||||||
import 'package:server_pinger/server.dart';
|
import 'package:server_pinger/server.dart';
|
||||||
|
|
||||||
import 'server.dart';
|
import 'server.dart';
|
||||||
|
@ -40,7 +41,7 @@ class _ServerListState extends State<ServerList> {
|
||||||
),
|
),
|
||||||
new Server(
|
new Server(
|
||||||
"My VPS",
|
"My VPS",
|
||||||
"https://vps1.kescher.at",
|
"http://kescher.at",
|
||||||
),
|
),
|
||||||
new Server(
|
new Server(
|
||||||
"Raspberry Pi",
|
"Raspberry Pi",
|
||||||
|
@ -66,18 +67,13 @@ class _ServerListState extends State<ServerList> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateServerStatus(Server s) {
|
void _updateServerStatus(Server s) {
|
||||||
checkStatus(s.uri).then((value) {
|
_checkStatus(s.uri).then((value) {
|
||||||
if (value != s.status)
|
setState(() {
|
||||||
setState(() {
|
s.status = value;
|
||||||
s.status = value;
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateUI() {
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// This method is rerun every time setState is called, for instance as done
|
// This method is rerun every time setState is called, for instance as done
|
||||||
|
@ -180,7 +176,8 @@ class _ServerListState extends State<ServerList> {
|
||||||
children: [
|
children: [
|
||||||
info,
|
info,
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(border: Border(top: BorderSide(color: Colors.grey))),
|
decoration: BoxDecoration(
|
||||||
|
border: Border(top: BorderSide(color: Colors.grey))),
|
||||||
),
|
),
|
||||||
Text('Ping: 1111'),
|
Text('Ping: 1111'),
|
||||||
],
|
],
|
||||||
|
@ -233,41 +230,135 @@ class _ServerListState extends State<ServerList> {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<ServerStatus> checkStatus(String uri) async {
|
static Future<ServerStatus> _checkStatus(String uri,
|
||||||
|
{int iterations = 0}) async {
|
||||||
Uri parsedUri;
|
Uri parsedUri;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parsedUri = Uri.parse(uri);
|
parsedUri = Uri.parse(uri);
|
||||||
} catch (FormatException) {
|
} catch (FormatException) {
|
||||||
print("The URI was invalid, returning DNS_ERROR");
|
|
||||||
return ServerStatus.dnserror;
|
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) {
|
Icon _generateIcon(Server server) {
|
||||||
if (server.status == ServerStatus.unknown)
|
switch (server.status) {
|
||||||
return new Icon(
|
case ServerStatus.unknown:
|
||||||
Icons.check_box_outline_blank,
|
return new Icon(
|
||||||
color: Colors.yellow,
|
Icons.sync,
|
||||||
);
|
color: Colors.blueGrey.shade400,
|
||||||
else if (server.status == ServerStatus.responding)
|
);
|
||||||
return new Icon(
|
break;
|
||||||
Icons.check_box,
|
case ServerStatus.ok:
|
||||||
color: Colors.green,
|
return new Icon(
|
||||||
);
|
Icons.check_box,
|
||||||
else
|
color: Colors.green.shade400,
|
||||||
return new Icon(
|
);
|
||||||
Icons.indeterminate_check_box,
|
break;
|
||||||
color: Colors.red,
|
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