Skip to content

Instantly share code, notes, and snippets.

@dnys1
Created August 23, 2022 00:12
Show Gist options
  • Save dnys1/1aa4c4e1798fa3056e8dd7b618444711 to your computer and use it in GitHub Desktop.
Save dnys1/1aa4c4e1798fa3056e8dd7b618444711 to your computer and use it in GitHub Desktop.
/*
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import 'dart:async';
import 'dart:convert';
import 'package:async/async.dart';
import 'package:aws_common/aws_common.dart';
Future<void> example() async {
final AWSStreamedHttpRequest request = AWSStreamedHttpRequest.post(
Uri.http('localhost:8000', '/hello'),
body: HttpPayload.string('Hello'), // Stream<List<int>>
);
final AWSStreamedHttpResponse? response =
await request.send().valueOrCancellation();
final String? body = await response?.decodeBody();
safePrint(body);
}
/// {@template aws_common.http.http_payload}
/// An HTTP request's payload.
/// {@endtemplate}
class HttpPayload extends StreamView<List<int>> {
/// {@macro aws_common.http.http_payload}
factory HttpPayload([Object? body]) {
if (body == null) {
return const HttpPayload.empty();
}
if (body is String) {
return HttpPayload.string(body);
}
if (body is List<int>) {
return HttpPayload.bytes(body);
}
if (body is Stream<List<int>>) {
return HttpPayload.streaming(body);
}
if (body is Map<String, String>) {
return HttpPayload.formFields(body);
}
throw ArgumentError('Invalid HTTP payload type: ${body.runtimeType}');
}
/// An empty HTTP body.
const HttpPayload.empty({this.contentType}) : super(const Stream.empty());
/// A UTF-8 encoded HTTP body.
HttpPayload.string(
String body, {
Encoding encoding = utf8,
String? contentType,
}) : contentType = contentType ?? 'text/plain; charset=${encoding.name}',
super(LazyStream(() => Stream.value(encoding.encode(body))));
/// A byte buffer HTTP body.
HttpPayload.bytes(
List<int> body, {
this.contentType,
}) : super(Stream.value(body));
/// A form-encoded body of `key=value` pairs.
HttpPayload.formFields(
Map<String, String> body, {
Encoding encoding = utf8,
String? contentType,
}) : contentType = contentType ??
'application/x-www-form-urlencoded; charset=${encoding.name}',
super(
LazyStream(
() => Stream.value(
encoding.encode(_encodeFormValues(body, encoding: encoding)),
),
),
);
/// Encodes body as a JSON string and sets Content-Type to 'application/json'.
HttpPayload.json(
Object body, {
Encoding encoding = utf8,
String? contentType,
}) : contentType =
contentType ?? 'application/json; charset=${encoding.name}',
super(
LazyStream(
() => Stream.value(encoding.encode(json.encode(body))),
),
);
/// A streaming HTTP body.
const HttpPayload.streaming(
super.body, {
this.contentType,
});
/// The content type of the body.
final String? contentType;
/// Converts a [Map] from parameter names to values to a URL query string.
///
/// _mapToQuery({"foo": "bar", "baz": "bang"});
/// //=> "foo=bar&baz=bang"
///
/// Similar util at https://github.com/dart-lang/http/blob/06649afbb5847dbb0293816ba8348766b116e419/pkgs/http/lib/src/utils.dart#L15
static String _encodeFormValues(
Map<String, String> params, {
required Encoding encoding,
}) =>
params.entries
.map(
(e) => [
Uri.encodeQueryComponent(e.key, encoding: encoding),
Uri.encodeQueryComponent(e.value, encoding: encoding),
].join('='),
)
.join('&');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment