Line data Source code
1 : import 'dart:convert';
2 : import 'dart:io';
3 :
4 : import 'package:agattp/agattp.dart';
5 : import 'package:agattp/src/agattp_method.dart';
6 :
7 : import 'package:agattp/src/agattp_request.dart'
8 : if (dart.library.io) 'package:agattp/src/native/agattp_request.dart'
9 : if (dart.library.js) 'package:agattp/src/web/agattp_request.dart';
10 :
11 : /// This class holds a group of configs for requests, applied to all requests
12 : /// made through it. Contains a collection of helpful methods and constructors
13 : /// to easily integrate HTTP requests into most Anlix code bases
14 : class Agattp {
15 : /// The config applied to every request
16 : final AgattpConfig config;
17 :
18 2 : Agattp({this.config = const AgattpConfig()});
19 :
20 : /// Use default config with Bearer authentication
21 2 : factory Agattp.authBearer(String? token) => Agattp(
22 2 : config: AgattpConfig(auth: AgattpAuthBearer(token)),
23 : );
24 :
25 : /// Use default config with Basic Auth authentication
26 1 : factory Agattp.authBasic({
27 : required String username,
28 : required String password,
29 : }) =>
30 1 : Agattp(
31 1 : config: AgattpConfig(
32 1 : auth: AgattpAuthBasic(username: username, password: password),
33 : ),
34 : );
35 :
36 : /// Use default config with Digest authentication
37 1 : factory Agattp.authDigest({
38 : required String username,
39 : required String password,
40 : }) =>
41 1 : Agattp(
42 1 : config: AgattpConfig(
43 1 : auth: AgattpAuthDigest(username: username, password: password),
44 : ),
45 : );
46 :
47 : /// Retrieve the headers for this request - will return a copy of extraHeaders
48 : /// with the authentication headers inserted
49 1 : Future<Map<String, String>> _headers({
50 : required AgattpMethod method,
51 : required Uri uri,
52 : required Map<String, String> extraHeaders,
53 : }) async {
54 2 : if (config.auth == null) {
55 : return extraHeaders;
56 : }
57 0 : return Map<String, String>.from(extraHeaders)..addAll(
58 0 : await config.auth!.getAuthHeaders(method, uri),
59 : );
60 : }
61 :
62 : /// Retrieve the headers for this request - will return a copy of extraHeaders
63 : /// with the authentication headers inserted, as well as the JSON content-type
64 : /// header
65 2 : Future<Map<String, String>> _jsonHeaders({
66 : required Uri uri,
67 : required AgattpMethod method,
68 : required Map<String, String> extraHeaders,
69 : required bool hasBody,
70 : }) async {
71 4 : if (config.auth == null && !hasBody) {
72 : return extraHeaders;
73 : }
74 1 : final Map<String, String> headers = Map<String, String>.from(extraHeaders);
75 2 : if (config.auth != null) {
76 4 : headers.addAll(await config.auth!.getAuthHeaders(method, uri));
77 : }
78 : if (hasBody) {
79 1 : headers[HttpHeaders.contentTypeHeader] =
80 4 : 'application/json; charset=${config.encoding.name}';
81 : }
82 : return headers;
83 : }
84 :
85 1 : Future<AgattpResponse> _sendRequest(
86 : AgattpMethod method,
87 : Uri uri, {
88 : Map<String, String> headers = const <String, String>{},
89 : String? body,
90 : Duration? timeout,
91 : }) async {
92 3 : return AgattpRequest<void, AgattpResponse>(config).send(
93 : method: method,
94 : uri: uri,
95 1 : headers: await _headers(
96 : uri: uri,
97 : method: method,
98 : extraHeaders: headers,
99 : ),
100 : body: body,
101 : timeout: timeout,
102 : );
103 : }
104 :
105 2 : Future<AgattpJsonResponse<T>> _sendJsonRequest<T>(
106 : AgattpMethod method,
107 : Uri uri, {
108 : Map<String, String> extraHeaders = const <String, String>{},
109 : String? body,
110 : Duration? timeout,
111 : }) async {
112 6 : return AgattpRequest<T, AgattpJsonResponse<T>>(config).send(
113 : method: method,
114 : uri: uri,
115 2 : headers: await _jsonHeaders(
116 : uri: uri,
117 : method: method,
118 : extraHeaders: extraHeaders,
119 : hasBody: body != null,
120 : ),
121 : body: body,
122 : timeout: timeout,
123 : );
124 : }
125 :
126 : /// A simple GET HTTP request
127 1 : Future<AgattpResponse> get(
128 : Uri uri, {
129 : Map<String, String> headers = const <String, String>{},
130 : Duration? timeout,
131 : }) {
132 1 : return _sendRequest(
133 : AgattpMethod.get,
134 : uri,
135 : headers: headers,
136 : timeout: timeout,
137 : );
138 : }
139 :
140 : /// A simple GET HTTP request that converts the response body to a JSON of
141 : /// type T - usually a Map<String, dynamic>
142 2 : Future<AgattpJsonResponse<T>> getJson<T>(
143 : Uri uri, {
144 : Map<String, String> extraHeaders = const <String, String>{},
145 : Duration? timeout,
146 : }) async {
147 2 : return _sendJsonRequest(
148 : AgattpMethod.get,
149 : uri,
150 : extraHeaders: extraHeaders,
151 : timeout: timeout,
152 : );
153 : }
154 :
155 : /// A simple HEAD HTTP request
156 1 : Future<AgattpResponse> head(
157 : Uri uri, {
158 : Map<String, String> headers = const <String, String>{},
159 : Duration? timeout,
160 : }) async {
161 1 : return _sendRequest(
162 : AgattpMethod.head,
163 : uri,
164 : headers: headers,
165 : timeout: timeout,
166 : );
167 : }
168 :
169 : /// A simple HEAD HTTP request that converts the response body to a JSON of
170 : /// type T - usually a Map<String, dynamic>
171 1 : Future<AgattpJsonResponse<T>> headJson<T>(
172 : Uri uri, {
173 : Map<String, String> extraHeaders = const <String, String>{},
174 : Duration? timeout,
175 : }) async {
176 1 : return _sendJsonRequest(
177 : AgattpMethod.head,
178 : uri,
179 : extraHeaders: extraHeaders,
180 : timeout: timeout,
181 : );
182 : }
183 :
184 : /// A simple POST HTTP request
185 1 : Future<AgattpResponse> post(
186 : Uri uri, {
187 : Map<String, String> headers = const <String, String>{},
188 : String? body,
189 : Duration? timeout,
190 : }) async {
191 1 : return _sendRequest(
192 : AgattpMethod.post,
193 : uri,
194 : headers: headers,
195 : timeout: timeout,
196 : body: body,
197 : );
198 : }
199 :
200 : /// A simple POST HTTP request that converts the response body to a JSON of
201 : /// type T - usually a Map<String, dynamic>
202 1 : Future<AgattpJsonResponse<T>> postJson<T>(
203 : Uri uri, {
204 : dynamic body,
205 : Map<String, String> extraHeaders = const <String, String>{},
206 : Duration? timeout,
207 : }) async {
208 1 : return _sendJsonRequest(
209 : AgattpMethod.post,
210 : uri,
211 : extraHeaders: extraHeaders,
212 1 : body: body != null ? jsonEncode(body) : null,
213 : timeout: timeout,
214 : );
215 : }
216 :
217 : /// A simple PUT HTTP request
218 1 : Future<AgattpResponse> put(
219 : Uri uri, {
220 : Map<String, String> headers = const <String, String>{},
221 : String? body,
222 : Duration? timeout,
223 : }) async {
224 1 : return _sendRequest(
225 : AgattpMethod.put,
226 : uri,
227 : headers: headers,
228 : timeout: timeout,
229 : body: body,
230 : );
231 : }
232 :
233 : /// A simple PUT HTTP request that converts the response body to a JSON of
234 : /// type T - usually a Map<String, dynamic>
235 1 : Future<AgattpJsonResponse<T>> putJson<T>(
236 : Uri uri, {
237 : dynamic body,
238 : Map<String, String> extraHeaders = const <String, String>{},
239 : Duration? timeout,
240 : }) async {
241 1 : return _sendJsonRequest(
242 : AgattpMethod.put,
243 : uri,
244 : extraHeaders: extraHeaders,
245 1 : body: body != null ? jsonEncode(body) : null,
246 : timeout: timeout,
247 : );
248 : }
249 :
250 : /// A simple PATCH HTTP request
251 1 : Future<AgattpResponse> patch(
252 : Uri uri, {
253 : Map<String, String> headers = const <String, String>{},
254 : String? body,
255 : Duration? timeout,
256 : }) async {
257 1 : return _sendRequest(
258 : AgattpMethod.patch,
259 : uri,
260 : headers: headers,
261 : timeout: timeout,
262 : body: body,
263 : );
264 : }
265 :
266 : /// A simple PATCH HTTP request that converts the response body to a JSON of
267 : /// type T - usually a Map<String, dynamic>
268 1 : Future<AgattpJsonResponse<T>> patchJson<T>(
269 : Uri uri, {
270 : dynamic body,
271 : Map<String, String> extraHeaders = const <String, String>{},
272 : Duration? timeout,
273 : }) async {
274 1 : return _sendJsonRequest(
275 : AgattpMethod.patch,
276 : uri,
277 : extraHeaders: extraHeaders,
278 1 : body: body != null ? jsonEncode(body) : null,
279 : timeout: timeout,
280 : );
281 : }
282 :
283 : /// A simple DELETE HTTP request
284 1 : Future<AgattpResponse> delete(
285 : Uri uri, {
286 : Map<String, String> headers = const <String, String>{},
287 : String? body,
288 : Duration? timeout,
289 : }) async {
290 1 : return _sendRequest(
291 : AgattpMethod.delete,
292 : uri,
293 : headers: headers,
294 : timeout: timeout,
295 : body: body,
296 : );
297 : }
298 :
299 : /// A simple DELETE HTTP request that converts the response body to a JSON of
300 : /// type T - usually a Map<String, dynamic>
301 1 : Future<AgattpJsonResponse<T>> deleteJson<T>(
302 : Uri uri, {
303 : dynamic body,
304 : Map<String, String> extraHeaders = const <String, String>{},
305 : Duration? timeout,
306 : }) async {
307 1 : return _sendJsonRequest(
308 : AgattpMethod.delete,
309 : uri,
310 : extraHeaders: extraHeaders,
311 1 : body: body != null ? jsonEncode(body) : null,
312 : timeout: timeout,
313 : );
314 : }
315 : }
|