|
| 1 | +import 'dart:convert'; |
| 2 | + |
1 | 3 | import 'package:http/http.dart';
|
| 4 | +import 'package:http_parser/http_parser.dart'; |
2 | 5 | import 'package:json_api/http.dart';
|
3 | 6 |
|
4 | 7 | /// A handler using the Dart's built-in http client
|
5 | 8 | class DartHttp implements HttpHandler {
|
6 |
| - DartHttp(this._client); |
| 9 | + DartHttp(this._client, [this._defaultEncoding = utf8]) |
| 10 | + : assert(_defaultEncoding != null, "Default encoding can't be null"); |
7 | 11 |
|
8 | 12 | @override
|
9 | 13 | Future<HttpResponse> call(HttpRequest request) async {
|
10 | 14 | final response = await _send(Request(request.method, request.uri)
|
11 | 15 | ..headers.addAll(request.headers)
|
12 | 16 | ..body = request.body);
|
13 |
| - return HttpResponse(response.statusCode, |
14 |
| - body: response.body, headers: response.headers); |
| 17 | + final responseBody = |
| 18 | + _encodingForHeaders(response.headers).decode(response.bodyBytes); |
| 19 | + return HttpResponse( |
| 20 | + response.statusCode, |
| 21 | + body: responseBody, |
| 22 | + headers: response.headers, |
| 23 | + ); |
15 | 24 | }
|
16 | 25 |
|
17 | 26 | final Client _client;
|
| 27 | + final Encoding _defaultEncoding; |
18 | 28 |
|
19 | 29 | Future<Response> _send(Request dartRequest) async =>
|
20 | 30 | Response.fromStream(await _client.send(dartRequest));
|
| 31 | + |
| 32 | + /// Returns the encoding to use for a response with the given headers. |
| 33 | + /// |
| 34 | + /// Defaults to [_defaultEncoding] if the headers don't specify a charset or if that |
| 35 | + /// charset is unknown. |
| 36 | + Encoding _encodingForHeaders(Map<String, String> headers) => |
| 37 | + _encodingForCharset( |
| 38 | + _contentTypeForHeaders(headers).parameters['charset']); |
| 39 | + |
| 40 | + /// Returns the [Encoding] that corresponds to [charset]. |
| 41 | + /// |
| 42 | + /// Returns [_defaultEncoding] if [charset] is null or if no [Encoding] was found that |
| 43 | + /// corresponds to [charset]. |
| 44 | + Encoding _encodingForCharset(String charset) { |
| 45 | + if (charset == null) return _defaultEncoding; |
| 46 | + return Encoding.getByName(charset) ?? _defaultEncoding; |
| 47 | + } |
| 48 | + |
| 49 | + /// Returns the [MediaType] object for the given headers's content-type. |
| 50 | + /// |
| 51 | + /// Defaults to `application/octet-stream`. |
| 52 | + MediaType _contentTypeForHeaders(Map<String, String> headers) { |
| 53 | + var contentType = headers['content-type']; |
| 54 | + if (contentType != null) return MediaType.parse(contentType); |
| 55 | + return MediaType('application', 'octet-stream'); |
| 56 | + } |
21 | 57 | }
|
0 commit comments