Line data Source code
1 : import 'package:http_parser/http_parser.dart'; 2 : 3 : typedef HeaderForEachCallback = void Function(String name, List<String> values); 4 : 5 : class Headers { 6 : // Header field name 7 : static const acceptHeader = 'accept'; 8 : static const contentEncodingHeader = 'content-encoding'; 9 : static const contentLengthHeader = 'content-length'; 10 : static const contentTypeHeader = 'content-type'; 11 : static const wwwAuthenticateHeader = 'www-authenticate'; 12 : 13 : // Header field value 14 : static const jsonContentType = 'application/json; charset=utf-8'; 15 : static const formUrlEncodedContentType = 'application/x-www-form-urlencoded'; 16 : 17 9 : static final jsonMimeType = MediaType.parse(jsonContentType); 18 : 19 : final Map<String, List<String>> _map; 20 : 21 2 : Map<String, List<String>> get map => _map; 22 : 23 2 : Headers() : _map = <String, List<String>>{}; 24 : 25 4 : Headers.fromMap(Map<String, List<String>> map) 26 20 : : _map = map.map((k, v) => MapEntry(k.trim().toLowerCase(), v)); 27 : 28 : /// Returns the list of values for the header named [name]. If there 29 : /// is no header with the provided name, [:null:] will be returned. 30 3 : List<String> operator [](String name) { 31 12 : return _map[name.trim().toLowerCase()]; 32 : } 33 : 34 : /// Convenience method for the value for a single valued header. If 35 : /// there is no header with the provided name, [:null:] will be 36 : /// returned. If the header has more than one value an exception is 37 : /// thrown. 38 3 : String value(String name) { 39 3 : var arr = this[name]; 40 : if (arr == null) return null; 41 9 : if (arr.length == 1) return arr.first; 42 1 : throw Exception( 43 1 : '"$name" header has more than one value, please use Headers[name]'); 44 : } 45 : 46 : /// Adds a header value. The header named [name] will have the value 47 : /// [value] added to its list of values. 48 1 : void add(String name, String value) { 49 1 : var arr = this[name]; 50 0 : if (arr == null) return set(name, value); 51 1 : arr.add(value); 52 : } 53 : 54 : /// Sets a header. The header named [name] will have all its values 55 : /// cleared before the value [value] is added as its value. 56 1 : void set(String name, dynamic value) { 57 2 : name = name.trim().toLowerCase(); 58 1 : if (value is List) { 59 6 : _map[name] = value.map<String>((e) => e.toString()).toList(); 60 : } else { 61 4 : _map[name] = [value.trim()]; 62 : } 63 : } 64 : 65 : /// Removes a specific value for a header name. 66 1 : void remove(String name, String value) { 67 1 : var arr = this[name]; 68 : if (arr == null) return; 69 3 : arr.removeWhere((v) => v == value); 70 : } 71 : 72 : /// Removes all values for the specified header name. 73 1 : void removeAll(String name) { 74 2 : _map.remove(name); 75 : } 76 : 77 1 : void clear() { 78 2 : _map.clear(); 79 : } 80 : 81 : /// Enumerates the headers, applying the function [f] to each 82 : /// header. The header name passed in [:name:] will be all lower 83 : /// case. 84 2 : void forEach(HeaderForEachCallback f) { 85 12 : _map.keys.forEach((key) => f(key, this[key])); 86 : } 87 : 88 1 : @override 89 : String toString() { 90 1 : var stringBuffer = StringBuffer(); 91 3 : _map.forEach((key, value) { 92 4 : value.forEach((e) => stringBuffer.writeln('$key: $e')); 93 : }); 94 1 : return stringBuffer.toString(); 95 : } 96 : }