2023-03-17 21:06:01 +01:00
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import 'dart:convert';
|
|
|
|
|
2023-03-29 18:02:00 +02:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
|
2023-03-17 21:06:01 +01:00
|
|
|
const String wellKnownPath = "/.well-known/outbag/server";
|
|
|
|
const int defaultPort = 7223;
|
|
|
|
|
|
|
|
Future<Uri> fetchWellKnown(String host, int port) async {
|
|
|
|
Uri uri = Uri(path: wellKnownPath, host: host, port: port, scheme: "https");
|
|
|
|
final resp = await http.get(uri);
|
|
|
|
final json = jsonDecode(resp.body);
|
|
|
|
|
|
|
|
return Uri(host: host, path: json['path'], port: json['port']);
|
|
|
|
}
|
|
|
|
|
|
|
|
class OutbagServer {
|
|
|
|
final String host;
|
|
|
|
final int port;
|
|
|
|
final String path;
|
|
|
|
|
|
|
|
final String tag;
|
|
|
|
|
|
|
|
const OutbagServer(
|
2023-03-18 20:24:48 +01:00
|
|
|
{required this.host,
|
2023-03-17 21:06:01 +01:00
|
|
|
required this.port,
|
|
|
|
required this.path,
|
|
|
|
required this.tag});
|
|
|
|
|
|
|
|
String get base {
|
|
|
|
return Uri(
|
|
|
|
host: host,
|
|
|
|
port: port,
|
|
|
|
path: path,
|
|
|
|
scheme: 'https',
|
|
|
|
).toString();
|
|
|
|
}
|
|
|
|
|
2023-03-18 20:24:48 +01:00
|
|
|
factory OutbagServer.fromMap(Map<String, dynamic> data) {
|
|
|
|
return OutbagServer(
|
|
|
|
tag: data['tag'],
|
|
|
|
host: data['host'],
|
|
|
|
path: data['path'],
|
|
|
|
port: data['port']);
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> toMap() {
|
|
|
|
return {'host': host, 'port': port, 'path': path, 'tag': tag};
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> toDisk() async {
|
2023-03-29 18:02:00 +02:00
|
|
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
|
|
|
|
await prefs.setString('server-host', host);
|
|
|
|
await prefs.setInt('server-port', port);
|
|
|
|
await prefs.setString('server-path', path);
|
|
|
|
await prefs.setString('server-tag', tag);
|
2023-03-17 21:06:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Future<OutbagServer> fromDisk() async {
|
2023-03-29 18:02:00 +02:00
|
|
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
|
|
|
|
return OutbagServer(
|
2023-12-22 20:14:36 +01:00
|
|
|
path: prefs.getString('server-path')!,
|
|
|
|
port: prefs.getInt('server-port')!,
|
|
|
|
tag: prefs.getString('server-tag')!,
|
|
|
|
host: prefs.getString('server-host')!);
|
2023-03-29 18:02:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static Future<void> removeDisk() async {
|
|
|
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
2023-03-17 21:06:01 +01:00
|
|
|
|
2023-03-29 18:02:00 +02:00
|
|
|
await prefs.remove('server-host');
|
|
|
|
await prefs.remove('server-port');
|
|
|
|
await prefs.remove('server-path');
|
|
|
|
await prefs.remove('server-tag');
|
2023-03-17 21:06:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<OutbagServer> getOutbagServerUrl(String tag) async {
|
|
|
|
final rootUri = Uri.parse(tag.startsWith('https://') ? tag : 'https://$tag');
|
|
|
|
|
|
|
|
bool onRoot = rootUri.port == 443;
|
|
|
|
|
|
|
|
try {
|
|
|
|
final uri = await fetchWellKnown(rootUri.host, rootUri.port);
|
|
|
|
return OutbagServer(
|
2023-03-18 20:24:48 +01:00
|
|
|
host: rootUri.host,
|
|
|
|
port: uri.port,
|
|
|
|
path: uri.path,
|
|
|
|
tag: onRoot ? rootUri.host : '${rootUri.host}:${uri.port}');
|
2023-03-17 21:06:01 +01:00
|
|
|
} catch (_) {
|
|
|
|
if (onRoot) {
|
|
|
|
final uri = await fetchWellKnown(rootUri.host, defaultPort);
|
|
|
|
return OutbagServer(
|
2023-03-18 20:24:48 +01:00
|
|
|
host: rootUri.host,
|
|
|
|
port: uri.port,
|
|
|
|
path: uri.path,
|
|
|
|
tag: onRoot ? rootUri.host : '${rootUri.host}:${uri.port}');
|
2023-03-17 21:06:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
throw Error();
|
|
|
|
}
|