OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library utils; | 5 library oauth2.utils; |
6 | |
7 import 'dart:async'; | |
8 | 6 |
9 /// Adds additional query parameters to [url], overwriting the original | 7 /// Adds additional query parameters to [url], overwriting the original |
10 /// parameters if a name conflict occurs. | 8 /// parameters if a name conflict occurs. |
11 Uri addQueryParameters(Uri url, Map<String, String> parameters) { | 9 Uri addQueryParameters(Uri url, Map<String, String> parameters) => url.replace( |
12 var queryMap = queryToMap(url.query); | 10 queryParameters: new Map.from(url.queryParameters)..addAll(parameters)); |
13 queryMap.addAll(parameters); | |
14 return url.resolve("?${mapToQuery(queryMap)}"); | |
15 } | |
16 | |
17 /// Convert a URL query string (or `application/x-www-form-urlencoded` body) | |
18 /// into a [Map] from parameter names to values. | |
19 Map<String, String> queryToMap(String queryList) { | |
20 var map = {}; | |
21 for (var pair in queryList.split("&")) { | |
22 var split = split1(pair, "="); | |
23 if (split.isEmpty) continue; | |
24 var key = urlDecode(split[0]); | |
25 var value = split.length > 1 ? urlDecode(split[1]) : ""; | |
26 map[key] = value; | |
27 } | |
28 return map; | |
29 } | |
30 | |
31 /// Convert a [Map] from parameter names to values to a URL query string. | |
32 String mapToQuery(Map<String, String> map) { | |
33 var pairs = <List<String>>[]; | |
34 map.forEach((key, value) { | |
35 key = Uri.encodeQueryComponent(key); | |
36 value = (value == null || value.isEmpty) | |
37 ? null | |
38 : Uri.encodeQueryComponent(value); | |
39 pairs.add([key, value]); | |
40 }); | |
41 return pairs.map((pair) { | |
42 if (pair[1] == null) return pair[0]; | |
43 return "${pair[0]}=${pair[1]}"; | |
44 }).join("&"); | |
45 } | |
46 | |
47 /// Decode a URL-encoded string. Unlike [Uri.decodeComponent], this includes | |
48 /// replacing `+` with ` `. | |
49 String urlDecode(String encoded) => | |
50 Uri.decodeComponent(encoded.replaceAll("+", " ")); | |
51 | 11 |
52 /// Like [String.split], but only splits on the first occurrence of the pattern. | 12 /// Like [String.split], but only splits on the first occurrence of the pattern. |
| 13 /// |
53 /// This will always return a list of two elements or fewer. | 14 /// This will always return a list of two elements or fewer. |
54 List<String> split1(String toSplit, String pattern) { | 15 List<String> split1(String toSplit, String pattern) { |
55 if (toSplit.isEmpty) return <String>[]; | 16 if (toSplit.isEmpty) return []; |
56 | 17 |
57 var index = toSplit.indexOf(pattern); | 18 var index = toSplit.indexOf(pattern); |
58 if (index == -1) return [toSplit]; | 19 if (index == -1) return [toSplit]; |
59 return [toSplit.substring(0, index), | 20 return [toSplit.substring(0, index), |
60 toSplit.substring(index + pattern.length)]; | 21 toSplit.substring(index + pattern.length)]; |
61 } | 22 } |
62 | 23 |
63 /// A WWW-Authenticate header value, parsed as per [RFC 2617][]. | 24 /// A WWW-Authenticate header value, parsed as per [RFC 2617][]. |
64 /// | 25 /// |
65 /// [RFC 2617]: http://tools.ietf.org/html/rfc2617 | 26 /// [RFC 2617]: http://tools.ietf.org/html/rfc2617 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 parameters[match.group(1).toLowerCase()] = match.group(2); | 59 parameters[match.group(1).toLowerCase()] = match.group(2); |
99 } while (match.group(3) != null); | 60 } while (match.group(3) != null); |
100 | 61 |
101 if (!paramString.trim().isEmpty) { | 62 if (!paramString.trim().isEmpty) { |
102 throw new FormatException('Invalid WWW-Authenticate header: "$header"'); | 63 throw new FormatException('Invalid WWW-Authenticate header: "$header"'); |
103 } | 64 } |
104 | 65 |
105 return new AuthenticateHeader(scheme, parameters); | 66 return new AuthenticateHeader(scheme, parameters); |
106 } | 67 } |
107 } | 68 } |
OLD | NEW |