Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Unified Diff: sdk/lib/io/http_body_impl.dart

Issue 14865008: Extend HttpBody handler to support 'multipart/form-data'. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/io/http_body_impl.dart
diff --git a/sdk/lib/io/http_body_impl.dart b/sdk/lib/io/http_body_impl.dart
index 095b74e7048799b86c14d6e39d8fe32d35018a35..4410a0e29b284701255b97d194b3d1f96b95ce40 100644
--- a/sdk/lib/io/http_body_impl.dart
+++ b/sdk/lib/io/http_body_impl.dart
@@ -33,59 +33,119 @@ class _HttpBodyHandler {
static Future<HttpBody> process(Stream<List<int>> stream,
HttpHeaders headers) {
- return stream.fold(
- new _BufferList(),
- (buffer, data) {
- // TODO(ajohnsen): Add limit for POST data.
- buffer.add(data);
- return buffer;
- })
- .then((list) {
- dynamic content = list.readBytes();
- String type = "binary";
- ContentType contentType = headers.contentType;
- if (contentType == null) {
- return new _HttpBody(null, type, content);
- }
- String asText(Encoding defaultEncoding) {
- var encoding;
- var charset = contentType.charset;
- if (charset != null) encoding = Encoding.fromName(charset);
- if (encoding == null) encoding = defaultEncoding;
- return _decodeString(content, encoding);
- }
- switch (contentType.primaryType) {
- case "text":
- type = "text";
- content = asText(Encoding.ASCII);
- break;
-
- case "application":
- switch (contentType.subType) {
- case "json":
- content = JSON.parse(asText(Encoding.UTF_8));
- type = "json";
- break;
-
- default:
- break;
+ ContentType contentType = headers.contentType;
+
+ Future<HttpBody> asBinary() {
+ return stream
+ .fold(new _BufferList(), (buffer, data) => buffer..add(data))
+ .then((buffer) => new _HttpBody(contentType,
+ "binary",
+ buffer.readBytes()));
+ }
+
+ Future<HttpBody> asText(Encoding defaultEncoding) {
+ var encoding;
+ var charset = contentType.charset;
+ if (charset != null) encoding = Encoding.fromName(charset);
+ if (encoding == null) encoding = defaultEncoding;
+ return stream
+ .transform(new StringDecoder(encoding))
+ .fold(new StringBuffer(), (buffer, data) => buffer..write(data))
+ .then((buffer) => new _HttpBody(contentType,
+ "text",
+ buffer.toString()));
+ }
+
+ Future<HttpBody> asFormData() {
+ return stream
+ .transform(new MimeMultipartTransformer(
+ contentType.parameters['boundary']))
+ .map((HttpMultipartFormData.parse))
+ .map((multipart) {
+ var future;
+ if (multipart.isText) {
+ future = multipart
+ .fold(new StringBuffer(), (b, s) => b..write(s))
+ .then((b) => b.toString());
+ } else {
+ future = multipart
+ .fold(new _BufferList(), (b, d) => b..add(d))
+ .then((b) => b.readBytes());
+ }
+ return future.then((data) {
+ var filename =
+ multipart.contentDisposition.parameters['filename'];
+ if (filename != null) {
+ data = new _HttpBodyFileUpload(multipart.contentType,
+ filename,
+ data);
}
- break;
-
- default:
- break;
- }
- return new _HttpBody(contentType.mimeType, type, content);
- });
+ return [multipart.contentDisposition.parameters['name'], data];
+ });
+ })
+ .fold([], (l, f) => l..add(f))
Søren Gjesse 2013/05/07 09:31:31 Does this ensure that if there are more than one f
Anders Johnsen 2013/06/11 12:23:01 Yep, it preserves the of the fields.
+ .then(Future.wait)
+ .then((parts) {
+ Map<String, dynamic> map = new Map<String, dynamic>();
+ for (var part in parts) {
+ map[part[0]] = part[1]; // Override existing entries.
+ }
+ return new _HttpBody(contentType, 'form', map);
+ });
+ }
+
+ if (contentType == null) {
+ return asBinary();
+ }
+
+ switch (contentType.primaryType) {
+ case "text":
+ return asText(Encoding.ASCII);
+
+ case "application":
+ switch (contentType.subType) {
+ case "json":
+ return asText(Encoding.UTF_8)
+ .then((body) => new _HttpBody(contentType,
+ "json",
+ JSON.parse(body.body)));
+
+ default:
+ break;
+ }
+ break;
+
+ case "multipart":
+ switch (contentType.subType) {
+ case "form-data":
+ return asFormData();
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return asBinary();
}
}
+class _HttpBodyFileUpload implements HttpBodyFileUpload {
+ final ContentType contentType;
+ final String filename;
+ final dynamic content;
+ _HttpBodyFileUpload(this.contentType, this.filename, this.content);
+}
+
class _HttpBody implements HttpBody {
- final String mimeType;
+ final ContentType contentType;
final String type;
final dynamic body;
- _HttpBody(String this.mimeType,
+ _HttpBody(ContentType this.contentType,
String this.type,
dynamic this.body);
}
@@ -97,7 +157,7 @@ class _HttpRequestBody extends _HttpBody implements HttpRequestBody {
final HttpResponse response;
_HttpRequestBody(HttpRequest request, HttpBody body)
- : super(body.mimeType, body.type, body.body),
+ : super(body.contentType, body.type, body.body),
method = request.method,
uri = request.uri,
headers = request.headers,
@@ -109,7 +169,7 @@ class _HttpClientResponseBody
final HttpClientResponse response;
_HttpClientResponseBody(HttpClientResponse response, HttpBody body)
- : super(body.mimeType, body.type, body.body),
+ : super(body.contentType, body.type, body.body),
this.response = response;
int get statusCode => response.statusCode;

Powered by Google App Engine
This is Rietveld 408576698