request method

Future<Map<String, Object?>> request(
  1. RequestType type,
  2. String action, {
  3. dynamic data = '',
  4. String contentType = 'application/json',
  5. Map<String, Object?>? query,
})

Used for all SDN json requests using the c2s API.

Throws: FormatException, SDNException

You must first set this.node and for some endpoints also this.accessToken before you can use this! For example to send a message to a SDN room with the id '!fjd823j:example.com' you call:

final resp = await request(
  RequestType.PUT,
  '/r0/rooms/!fjd823j:example.com/send/m.room.message/$txnId',
  data: {
    'msgtype': 'm.text',
    'body': 'hello'
  }
 );

Implementation

Future<Map<String, Object?>> request(
  RequestType type,
  String action, {
  dynamic data = '',
  String contentType = 'application/json',
  Map<String, Object?>? query,
}) async {
  if (node == null) {
    throw ('No node specified.');
  }
  dynamic json;
  (data is! String) ? json = jsonEncode(data) : json = data;
  if (data is List<int> || action.startsWith('/media/v3/upload')) json = data;

  final url =
      node!.resolveUri(Uri(path: '_api$action', queryParameters: query));

  final headers = <String, String>{};
  if (type == RequestType.PUT || type == RequestType.POST) {
    headers['Content-Type'] = contentType;
  }
  if (accessToken != null) {
    headers['Authorization'] = 'Bearer $accessToken';
  }

  late http.Response resp;
  Map<String, Object?>? jsonResp = <String, Object?>{};
  try {
    switch (type) {
      case RequestType.GET:
        resp = await httpClient.get(url, headers: headers);
        break;
      case RequestType.POST:
        resp = await httpClient.post(url, body: json, headers: headers);
        break;
      case RequestType.PUT:
        resp = await httpClient.put(url, body: json, headers: headers);
        break;
      case RequestType.DELETE:
        resp = await httpClient.delete(url, headers: headers);
        break;
    }
    var respBody = resp.body;
    try {
      respBody = utf8.decode(resp.bodyBytes);
    } catch (_) {
      // No-OP
    }
    if (resp.statusCode >= 500 && resp.statusCode < 600) {
      throw Exception(respBody);
    }
    var jsonString = String.fromCharCodes(respBody.runes);
    if (jsonString.startsWith('[') && jsonString.endsWith(']')) {
      jsonString = '{"chunk":$jsonString}';
    }
    jsonResp = jsonDecode(jsonString)
        as Map<String, Object?>?; // May throw FormatException
  } catch (e, s) {
    throw SDNConnectionException(e, s);
  }
  if (resp.statusCode >= 400 && resp.statusCode < 500) {
    throw SDNException(resp);
  }

  return jsonResp!;
}