Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding support for multipart/related requests #1181

Open
natebosch opened this issue Apr 25, 2024 · 0 comments
Open

Consider adding support for multipart/related requests #1181

natebosch opened this issue Apr 25, 2024 · 0 comments
Labels
package:http type-enhancement A request for a change that isn't a bug

Comments

@natebosch
Copy link
Member

We currently support multipart/form-data with MultipartRequest, but we don't support multipart/related.

I needed a multipart/related request and it ended up being easiest to copy some values from this implementation.

import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

(String boundary, Uint8List requestBytes) formatMultipartRelated(
    {String? name,
    String? displayName,
    required String mimeType,
    required Uint8List fileBytes}) {
  final boundary = _boundaryString();
  final separator = '--$boundary';
  final close = utf8.encode('\r\n--$boundary--\r\n');
  final metadata = <String>[
    separator,
    'Content-Type: application/json',
    '',
    jsonEncode({
      'file': {
        if (name != null && name.isNotEmpty) 'name': name,
        if (displayName != null && displayName.isNotEmpty)
          'displayName': displayName,
      }
    }),
    separator,
    'Content-Type: $mimeType',
    '',
    ''
  ].join('\r\n');
  return (
    boundary,
    Uint8List.fromList([...utf8.encode(metadata), ...fileBytes, ...close]),
  );
}

final Random _random = Random();

/// Returns a randomly-generated multipart boundary string
String _boundaryString() {
  /// The total length of the multipart boundaries used when building the
  /// request body.
  ///
  /// According to http://tools.ietf.org/html/rfc1341.html, this can't be longer
  /// than 70.
  const boundaryLength = 70;
  final prefix = 'dart-http-boundary-';
  final list = List<int>.generate(
      boundaryLength - prefix.length,
      (index) =>
          _boundaryCharacters[_random.nextInt(_boundaryCharacters.length)],
      growable: false);
  return '$prefix${String.fromCharCodes(list)}';
}

/// All character codes that are valid in multipart boundaries.
///
/// This is the intersection of the characters allowed in the `bcharsnospace`
/// production defined in [RFC 2046][] and those allowed in the `token`
/// production defined in [RFC 1521][].
///
/// [RFC 2046]: http://tools.ietf.org/html/rfc2046#section-5.1.1.
/// [RFC 1521]: https://tools.ietf.org/html/rfc1521#section-4
const List<int> _boundaryCharacters = <int>[
  43, 95, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, //
  69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
  87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
  109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122
];
@natebosch natebosch added type-enhancement A request for a change that isn't a bug package:http labels Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package:http type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

1 participant