requestUploadSlot method

Future<Result<HttpFileUploadSlot, HttpFileUploadError>> requestUploadSlot(
  1. String filename,
  2. int filesize,
  3. {String? contentType}
)

Request a slot to upload a file to. filename is the file's name and filesize is the file's size in octets. contentType is optional and refers to the file's Mime type. Returns an HttpFileUploadSlot if the request was successful; null otherwise.

Implementation

Future<Result<HttpFileUploadSlot, HttpFileUploadError>> requestUploadSlot(
  String filename,
  int filesize, {
  String? contentType,
}) async {
  if (!(await isSupported())) {
    return Result(NoEntityKnownError());
  }

  if (_entityJid == null) {
    logger.warning(
      'Attempted to request HTTP File Upload slot but no entity is known to send this request to.',
    );
    return Result(NoEntityKnownError());
  }

  if (_maxUploadSize != null && filesize > _maxUploadSize!) {
    logger.warning(
      'Attempted to request HTTP File Upload slot for a file that exceeds the filesize limit',
    );
    return Result(FileTooBigError());
  }

  final attrs = getAttributes();
  final response = (await attrs.sendStanza(
    StanzaDetails(
      Stanza.iq(
        to: _entityJid.toString(),
        type: 'get',
        children: [
          XMLNode.xmlns(
            tag: 'request',
            xmlns: httpFileUploadXmlns,
            attributes: {
              'filename': filename,
              'size': filesize.toString(),
              if (contentType != null) 'content-type': contentType,
            },
          ),
        ],
      ),
    ),
  ))!;

  if (response.attributes['type']! != 'result') {
    logger.severe('Failed to request HTTP File Upload slot.');
    // TODO(Unknown): Be more precise
    return Result(UnknownHttpFileUploadError());
  }

  final slot = response.firstTag('slot', xmlns: httpFileUploadXmlns)!;
  final putUrl = slot.firstTag('put')!.attributes['url']! as String;
  final getUrl = slot.firstTag('get')!.attributes['url']! as String;
  final headers = Map<String, String>.fromEntries(
    slot.findTags('header').map((tag) {
      return MapEntry(
        tag.attributes['name']! as String,
        tag.innerText(),
      );
    }),
  );

  return Result(
    HttpFileUploadSlot(
      putUrl,
      getUrl,
      prepareHeaders(headers),
    ),
  );
}