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

Fix for Request set bodyFields, need to be able to have List<String> … #49

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,3 @@ main() async {
print('Response body: ${response.body}');
}
```

## Filing issues

Please file issues for the http package at [http://dartbug.com/new][bugs].

[bugs]: http://dartbug.com/new
[docs]: https://api.dartlang.org/docs/channels/dev/latest/http.html
8 changes: 5 additions & 3 deletions lib/src/request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import 'base_request.dart';
import 'byte_stream.dart';
import 'utils.dart';

import 'package:collection/collection.dart';

/// An HTTP request where the entire request body is known in advance.
class Request extends BaseRequest {
/// The size of the request body, in bytes. This is calculated from
Expand Down Expand Up @@ -105,18 +107,18 @@ class Request extends BaseRequest {
/// `application/x-www-form-urlencoded`.
///
/// This map should only be set, not modified in place.
Map<String, String> get bodyFields {
MultiMap<String, String> get bodyFields {
var contentType = _contentType;
if (contentType == null ||
contentType.mimeType != "application/x-www-form-urlencoded") {
throw new StateError('Cannot access the body fields of a Request without '
'content-type "application/x-www-form-urlencoded".');
}

return Uri.splitQueryString(body, encoding: encoding);
return MultiMap.splitQueryString(body, encoding: encoding);
}

set bodyFields(Map<String, String> fields) {
set bodyFields(Map<String, Object> fields) {
var contentType = _contentType;
if (contentType == null) {
_contentType = new MediaType("application", "x-www-form-urlencoded");
Expand Down
26 changes: 21 additions & 5 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,31 @@ import 'dart:typed_data';

import 'byte_stream.dart';

import 'package:collection/collection.dart';

/// Converts a [Map] from parameter names to values to a URL query string.
/// Values may either be a String or List<String>.
///
/// mapToQuery({"foo": "bar", "baz": "bang"});
/// //=> "foo=bar&baz=bang"
String mapToQuery(Map<String, String> map, {Encoding encoding}) {
/// mapToQuery({"foo": "bar", "baz": "bang", "fi":["fo","fum"]});
/// //=> "foo=bar&baz=bang&fi=fo&fi=fum"
String mapToQuery(Map<String, Object> map, {Encoding encoding}) {
var pairs = <List<String>>[];
map.forEach((key, value) =>

void iterateMapEntry(key, value) {
if (value is List) {
value.forEach((subvalue) =>
pairs.add([Uri.encodeQueryComponent(key, encoding: encoding),
Uri.encodeQueryComponent(subvalue, encoding: encoding)]));
}
else if (value is String) {
pairs.add([Uri.encodeQueryComponent(key, encoding: encoding),
Uri.encodeQueryComponent(value, encoding: encoding)]));
Uri.encodeQueryComponent(value, encoding: encoding)]);
}
}

if (map is MultiMap) (map as MultiMap).forEachMultiple(iterateMapEntry);
else map.forEach(iterateMapEntry);

return pairs.map((pair) => "${pair[0]}=${pair[1]}").join("&");
}

Expand Down
24 changes: 24 additions & 0 deletions test/request_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import 'package:unittest/unittest.dart';

import 'utils.dart';

import 'package:collection/collection.dart';

void main() {
group('#contentLength', () {
test('is computed from bodyBytes', () {
Expand Down Expand Up @@ -153,6 +155,28 @@ void main() {
expect(request.bodyFields, equals({'hello': 'world'}));
});

test('can be set with a value that is a List<String> and bodyFields returns value as list', () {
var request = new http.Request('POST', dummyUrl);
request.bodyFields = {'hello': ['world', 'solar system', 'galaxy', 'universe']};
expect(request.bodyFields, equals({'hello': 'universe'}));
expect(request.bodyFields.multiple('hello'), equals(['world', 'solar system', 'galaxy', 'universe']));
});

test('can be set with a value that is a List<String> and body returns multi-assigned parameter', () {
var request = new http.Request('POST', dummyUrl);
request.bodyFields = {'hello': ['world', 'solar system', 'galaxy', 'universe']};
expect(request.body, equals('hello=world&hello=solar+system&hello=galaxy&hello=universe'));
});

test('can be set with a MultiMap that has multiple values', () {
var request = new http.Request('POST', dummyUrl);
MultiMap<String, String> map = new MultiMap<String, String>.from({'hello': ['world', 'solar system', 'galaxy', 'universe']});
expect(map, equals({'hello': 'universe'}));
request.bodyFields = map;
expect(request.bodyFields, equals({'hello': 'universe'}));
expect(request.bodyFields.multiple('hello'), equals(['world', 'solar system', 'galaxy', 'universe']));
});

test('changes when body changes', () {
var request = new http.Request('POST', dummyUrl);
request.headers['Content-Type'] =
Expand Down