Nikolas Rimikis
1 year ago
6 changed files with 179 additions and 339 deletions
@ -0,0 +1 @@
|
||||
export 'src/http_client.dart'; |
@ -0,0 +1,144 @@
|
||||
import 'dart:convert'; |
||||
import 'dart:typed_data'; |
||||
|
||||
import 'package:cookie_jar/cookie_jar.dart'; |
||||
import 'package:universal_io/io.dart'; |
||||
|
||||
export 'package:cookie_jar/cookie_jar.dart'; |
||||
|
||||
extension DynamiteHttpClientResponseBody on HttpClientResponse { |
||||
Future<Uint8List> get bodyBytes async { |
||||
final chunks = await toList(); |
||||
if (chunks.isEmpty) { |
||||
return Uint8List(0); |
||||
} |
||||
return Uint8List.fromList(chunks.reduce((final value, final element) => [...value, ...element])); |
||||
} |
||||
|
||||
Future<String> get body async => utf8.decode(await bodyBytes); |
||||
} |
||||
|
||||
class DynamiteResponse<T, U> { |
||||
DynamiteResponse( |
||||
this.data, |
||||
this.headers, |
||||
); |
||||
|
||||
final T data; |
||||
|
||||
final U headers; |
||||
|
||||
@override |
||||
String toString() => 'DynamiteResponse(data: $data, headers: $headers)'; |
||||
} |
||||
|
||||
class RawResponse { |
||||
RawResponse( |
||||
this.statusCode, |
||||
this.headers, |
||||
this.body, |
||||
); |
||||
|
||||
final int statusCode; |
||||
|
||||
final Map<String, String> headers; |
||||
|
||||
final Uint8List body; |
||||
|
||||
@override |
||||
String toString() => 'RawResponse(statusCode: $statusCode, headers: $headers, body: ${utf8.decode(body)})'; |
||||
} |
||||
|
||||
class DynamiteApiException extends RawResponse implements Exception { |
||||
DynamiteApiException( |
||||
super.statusCode, |
||||
super.headers, |
||||
super.body, |
||||
); |
||||
|
||||
@override |
||||
String toString() => |
||||
'DynamiteApiException(statusCode: ${super.statusCode}, headers: ${super.headers}, body: ${utf8.decode(super.body)})'; |
||||
} |
||||
|
||||
abstract class DynamiteAuthentication { |
||||
String get id; |
||||
Map<String, String> get headers; |
||||
} |
||||
|
||||
class DynamiteHttpBasicAuthentication extends DynamiteAuthentication { |
||||
DynamiteHttpBasicAuthentication({ |
||||
required this.username, |
||||
required this.password, |
||||
}); |
||||
|
||||
final String username; |
||||
|
||||
final String password; |
||||
|
||||
@override |
||||
String get id => 'basic_auth'; |
||||
@override |
||||
Map<String, String> get headers => { |
||||
'Authorization': 'Basic ${base64.encode(utf8.encode('$username:$password'))}', |
||||
}; |
||||
} |
||||
|
||||
class DynamiteClient { |
||||
DynamiteClient( |
||||
this.baseURL, { |
||||
final Map<String, String>? baseHeaders, |
||||
final String? userAgent, |
||||
final HttpClient? httpClient, |
||||
this.cookieJar, |
||||
this.authentications = const [], |
||||
}) { |
||||
this.baseHeaders = { |
||||
...?baseHeaders, |
||||
}; |
||||
this.httpClient = (httpClient ?? HttpClient())..userAgent = userAgent; |
||||
} |
||||
|
||||
final String baseURL; |
||||
|
||||
late final Map<String, String> baseHeaders; |
||||
|
||||
late final HttpClient httpClient; |
||||
|
||||
final CookieJar? cookieJar; |
||||
|
||||
final List<DynamiteAuthentication> authentications; |
||||
|
||||
Future<RawResponse> doRequest( |
||||
final String method, |
||||
final String path, |
||||
final Map<String, String> headers, |
||||
final Uint8List? body, |
||||
) async { |
||||
final uri = Uri.parse('$baseURL$path'); |
||||
final request = await httpClient.openUrl(method, uri); |
||||
for (final header in {...baseHeaders, ...headers}.entries) { |
||||
request.headers.add(header.key, header.value); |
||||
} |
||||
if (body != null) { |
||||
request.add(body.toList()); |
||||
} |
||||
if (cookieJar != null) { |
||||
request.cookies.addAll(await cookieJar!.loadForRequest(uri)); |
||||
} |
||||
|
||||
final response = await request.close(); |
||||
if (cookieJar != null) { |
||||
await cookieJar!.saveFromResponse(uri, response.cookies); |
||||
} |
||||
final responseHeaders = <String, String>{}; |
||||
response.headers.forEach((final name, final values) { |
||||
responseHeaders[name] = values.last; |
||||
}); |
||||
return RawResponse( |
||||
response.statusCode, |
||||
responseHeaders, |
||||
await response.bodyBytes, |
||||
); |
||||
} |
||||
} |
Loading…
Reference in new issue