platform/lib/body_parser.dart
2016-03-03 22:47:20 -05:00

67 lines
No EOL
2.1 KiB
Dart

// A library for parsing HTTP request bodies and queries.
library body_parser;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:json_god/json_god.dart';
/// A representation of data from an incoming request.
class BodyParseResult {
/// The parsed body.
Map body = {};
/// The parsed query string.
Map query = {};
}
/// Grabs data from an incoming request.
///
/// Supports urlencoded and JSON.
Future<BodyParseResult> parseBody(HttpRequest request) async {
BodyParseResult result = new BodyParseResult();
ContentType contentType = request.headers.contentType;
// Parse body
if (contentType != null) {
if (contentType.mimeType == 'application/json')
result.body = JSON.decode(await request.transform(UTF8.decoder).join());
else if (contentType.mimeType == 'application/x-www-form-urlencoded') {
String body = await request.transform(UTF8.decoder).join();
buildMapFromUri(result.body, body);
}
}
// Parse query
RegExp queryRgx = new RegExp(r'\?(.+)$');
String uriString = request.requestedUri.toString();
if (queryRgx.hasMatch(uriString)) {
Match queryMatch = queryRgx.firstMatch(uriString);
buildMapFromUri(result.query, queryMatch.group(1));
}
return result;
}
/// Parses a URI-encoded string into real data! **Wow!**
buildMapFromUri(Map map, String body) {
God god = new God();
for (String keyValuePair in body.split('&')) {
if (keyValuePair.contains('=')) {
List<String> split = keyValuePair.split('=');
String key = Uri.decodeQueryComponent(split[0]);
String value = Uri.decodeQueryComponent(split[1]);
num numValue = num.parse(value, (_) => double.NAN);
if (!numValue.isNaN)
map[key] = numValue;
else if (value.startsWith('[') && value.endsWith(']'))
map[key] = god.deserialize(value);
else if (value.startsWith('{') && value.endsWith('}'))
map[key] = god.deserialize(value);
else if (value.trim().toLowerCase() == 'null')
map[key] = null;
else map[key] = value;
} else map[Uri.decodeQueryComponent(keyValuePair)] = true;
}
}