1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/client/utils/URLEncodedUtils.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,220 @@ 1.4 +/* 1.5 + * ==================================================================== 1.6 + * Licensed to the Apache Software Foundation (ASF) under one 1.7 + * or more contributor license agreements. See the NOTICE file 1.8 + * distributed with this work for additional information 1.9 + * regarding copyright ownership. The ASF licenses this file 1.10 + * to you under the Apache License, Version 2.0 (the 1.11 + * "License"); you may not use this file except in compliance 1.12 + * with the License. You may obtain a copy of the License at 1.13 + * 1.14 + * http://www.apache.org/licenses/LICENSE-2.0 1.15 + * 1.16 + * Unless required by applicable law or agreed to in writing, 1.17 + * software distributed under the License is distributed on an 1.18 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1.19 + * KIND, either express or implied. See the License for the 1.20 + * specific language governing permissions and limitations 1.21 + * under the License. 1.22 + * ==================================================================== 1.23 + * 1.24 + * This software consists of voluntary contributions made by many 1.25 + * individuals on behalf of the Apache Software Foundation. For more 1.26 + * information on the Apache Software Foundation, please see 1.27 + * <http://www.apache.org/>. 1.28 + * 1.29 + */ 1.30 + 1.31 +package ch.boye.httpclientandroidlib.client.utils; 1.32 + 1.33 +import java.io.IOException; 1.34 +import java.io.UnsupportedEncodingException; 1.35 +import java.net.URI; 1.36 +import java.net.URLDecoder; 1.37 +import java.net.URLEncoder; 1.38 +import java.util.ArrayList; 1.39 +import java.util.Collections; 1.40 +import java.util.List; 1.41 +import java.util.Scanner; 1.42 + 1.43 +import ch.boye.httpclientandroidlib.annotation.Immutable; 1.44 + 1.45 +import ch.boye.httpclientandroidlib.Header; 1.46 +import ch.boye.httpclientandroidlib.HeaderElement; 1.47 +import ch.boye.httpclientandroidlib.HttpEntity; 1.48 +import ch.boye.httpclientandroidlib.NameValuePair; 1.49 +import ch.boye.httpclientandroidlib.message.BasicNameValuePair; 1.50 +import ch.boye.httpclientandroidlib.protocol.HTTP; 1.51 +import ch.boye.httpclientandroidlib.util.EntityUtils; 1.52 + 1.53 +/** 1.54 + * A collection of utilities for encoding URLs. 1.55 + * 1.56 + * @since 4.0 1.57 + */ 1.58 +@Immutable 1.59 +public class URLEncodedUtils { 1.60 + 1.61 + public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; 1.62 + private static final String PARAMETER_SEPARATOR = "&"; 1.63 + private static final String NAME_VALUE_SEPARATOR = "="; 1.64 + 1.65 + /** 1.66 + * Returns a list of {@link NameValuePair NameValuePairs} as built from the 1.67 + * URI's query portion. For example, a URI of 1.68 + * http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three 1.69 + * NameValuePairs, one for a=1, one for b=2, and one for c=3. 1.70 + * <p> 1.71 + * This is typically useful while parsing an HTTP PUT. 1.72 + * 1.73 + * @param uri 1.74 + * uri to parse 1.75 + * @param encoding 1.76 + * encoding to use while parsing the query 1.77 + */ 1.78 + public static List <NameValuePair> parse (final URI uri, final String encoding) { 1.79 + List <NameValuePair> result = Collections.emptyList(); 1.80 + final String query = uri.getRawQuery(); 1.81 + if (query != null && query.length() > 0) { 1.82 + result = new ArrayList <NameValuePair>(); 1.83 + parse(result, new Scanner(query), encoding); 1.84 + } 1.85 + return result; 1.86 + } 1.87 + 1.88 + /** 1.89 + * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an 1.90 + * {@link HttpEntity}. The encoding is taken from the entity's 1.91 + * Content-Encoding header. 1.92 + * <p> 1.93 + * This is typically used while parsing an HTTP POST. 1.94 + * 1.95 + * @param entity 1.96 + * The entity to parse 1.97 + * @throws IOException 1.98 + * If there was an exception getting the entity's data. 1.99 + */ 1.100 + public static List <NameValuePair> parse ( 1.101 + final HttpEntity entity) throws IOException { 1.102 + List <NameValuePair> result = Collections.emptyList(); 1.103 + 1.104 + String contentType = null; 1.105 + String charset = null; 1.106 + 1.107 + Header h = entity.getContentType(); 1.108 + if (h != null) { 1.109 + HeaderElement[] elems = h.getElements(); 1.110 + if (elems.length > 0) { 1.111 + HeaderElement elem = elems[0]; 1.112 + contentType = elem.getName(); 1.113 + NameValuePair param = elem.getParameterByName("charset"); 1.114 + if (param != null) { 1.115 + charset = param.getValue(); 1.116 + } 1.117 + } 1.118 + } 1.119 + 1.120 + if (contentType != null && contentType.equalsIgnoreCase(CONTENT_TYPE)) { 1.121 + final String content = EntityUtils.toString(entity, HTTP.ASCII); 1.122 + if (content != null && content.length() > 0) { 1.123 + result = new ArrayList <NameValuePair>(); 1.124 + parse(result, new Scanner(content), charset); 1.125 + } 1.126 + } 1.127 + return result; 1.128 + } 1.129 + 1.130 + /** 1.131 + * Returns true if the entity's Content-Type header is 1.132 + * <code>application/x-www-form-urlencoded</code>. 1.133 + */ 1.134 + public static boolean isEncoded (final HttpEntity entity) { 1.135 + Header h = entity.getContentType(); 1.136 + if (h != null) { 1.137 + HeaderElement[] elems = h.getElements(); 1.138 + if (elems.length > 0) { 1.139 + String contentType = elems[0].getName(); 1.140 + return contentType.equalsIgnoreCase(CONTENT_TYPE); 1.141 + } else { 1.142 + return false; 1.143 + } 1.144 + } else { 1.145 + return false; 1.146 + } 1.147 + } 1.148 + 1.149 + /** 1.150 + * Adds all parameters within the Scanner to the list of 1.151 + * <code>parameters</code>, as encoded by <code>encoding</code>. For 1.152 + * example, a scanner containing the string <code>a=1&b=2&c=3</code> would 1.153 + * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the 1.154 + * list of parameters. 1.155 + * 1.156 + * @param parameters 1.157 + * List to add parameters to. 1.158 + * @param scanner 1.159 + * Input that contains the parameters to parse. 1.160 + * @param encoding 1.161 + * Encoding to use when decoding the parameters. 1.162 + */ 1.163 + public static void parse ( 1.164 + final List <NameValuePair> parameters, 1.165 + final Scanner scanner, 1.166 + final String encoding) { 1.167 + scanner.useDelimiter(PARAMETER_SEPARATOR); 1.168 + while (scanner.hasNext()) { 1.169 + final String[] nameValue = scanner.next().split(NAME_VALUE_SEPARATOR); 1.170 + if (nameValue.length == 0 || nameValue.length > 2) 1.171 + throw new IllegalArgumentException("bad parameter"); 1.172 + 1.173 + final String name = decode(nameValue[0], encoding); 1.174 + String value = null; 1.175 + if (nameValue.length == 2) 1.176 + value = decode(nameValue[1], encoding); 1.177 + parameters.add(new BasicNameValuePair(name, value)); 1.178 + } 1.179 + } 1.180 + 1.181 + /** 1.182 + * Returns a String that is suitable for use as an <code>application/x-www-form-urlencoded</code> 1.183 + * list of parameters in an HTTP PUT or HTTP POST. 1.184 + * 1.185 + * @param parameters The parameters to include. 1.186 + * @param encoding The encoding to use. 1.187 + */ 1.188 + public static String format ( 1.189 + final List <? extends NameValuePair> parameters, 1.190 + final String encoding) { 1.191 + final StringBuilder result = new StringBuilder(); 1.192 + for (final NameValuePair parameter : parameters) { 1.193 + final String encodedName = encode(parameter.getName(), encoding); 1.194 + final String value = parameter.getValue(); 1.195 + final String encodedValue = value != null ? encode(value, encoding) : ""; 1.196 + if (result.length() > 0) 1.197 + result.append(PARAMETER_SEPARATOR); 1.198 + result.append(encodedName); 1.199 + result.append(NAME_VALUE_SEPARATOR); 1.200 + result.append(encodedValue); 1.201 + } 1.202 + return result.toString(); 1.203 + } 1.204 + 1.205 + private static String decode (final String content, final String encoding) { 1.206 + try { 1.207 + return URLDecoder.decode(content, 1.208 + encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET); 1.209 + } catch (UnsupportedEncodingException problem) { 1.210 + throw new IllegalArgumentException(problem); 1.211 + } 1.212 + } 1.213 + 1.214 + private static String encode (final String content, final String encoding) { 1.215 + try { 1.216 + return URLEncoder.encode(content, 1.217 + encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET); 1.218 + } catch (UnsupportedEncodingException problem) { 1.219 + throw new IllegalArgumentException(problem); 1.220 + } 1.221 + } 1.222 + 1.223 +}