• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/utils/URLEncodedUtils.java $
3  * $Revision: 655107 $
4  * $Date: 2008-05-10 08:20:42 -0700 (Sat, 10 May 2008) $
5  * ====================================================================
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements.  See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership.  The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License.  You may obtain a copy of the License at
13  *
14  *   http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied.  See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  * ====================================================================
23  *
24  * This software consists of voluntary contributions made by many
25  * individuals on behalf of the Apache Software Foundation.  For more
26  * information on the Apache Software Foundation, please see
27  * <http://www.apache.org/>.
28  *
29  */
30 
31 package org.apache.http.client.utils;
32 
33 import java.io.IOException;
34 import java.io.UnsupportedEncodingException;
35 import java.net.URI;
36 import java.net.URLDecoder;
37 import java.net.URLEncoder;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
41 import java.util.Scanner;
42 import org.apache.http.Header;
43 import org.apache.http.HttpEntity;
44 import org.apache.http.NameValuePair;
45 import org.apache.http.message.BasicNameValuePair;
46 import org.apache.http.protocol.HTTP;
47 import org.apache.http.util.EntityUtils;
48 
49 /**
50  * A collection of utilities for encoding URLs.
51  */
52 public class URLEncodedUtils {
53 
54     public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
55     private static final String PARAMETER_SEPARATOR = "&";
56     private static final String NAME_VALUE_SEPARATOR = "=";
57 
58     /**
59      * Returns a list of {@link NameValuePair NameValuePairs} as built from the
60      * URI's query portion. For example, a URI of
61      * http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three
62      * NameValuePairs, one for a=1, one for b=2, and one for c=3.
63      * <p>
64      * This is typically useful while parsing an HTTP PUT.
65      *
66      * @param uri
67      *            uri to parse
68      * @param encoding
69      *            encoding to use while parsing the query
70      */
parse(final URI uri, final String encoding)71     public static List <NameValuePair> parse (final URI uri, final String encoding) {
72         List <NameValuePair> result = Collections.emptyList();
73         final String query = uri.getRawQuery();
74         if (query != null && query.length() > 0) {
75             result = new ArrayList <NameValuePair>();
76             parse(result, new Scanner(query), encoding);
77         }
78         return result;
79     }
80 
81     /**
82      * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an
83      * {@link HttpEntity}. The encoding is taken from the entity's
84      * Content-Encoding header.
85      * <p>
86      * This is typically used while parsing an HTTP POST.
87      *
88      * @param entity
89      *            The entity to parse
90      * @throws IOException
91      *             If there was an exception getting the entity's data.
92      */
parse( final HttpEntity entity)93     public static List <NameValuePair> parse (
94             final HttpEntity entity) throws IOException {
95         List <NameValuePair> result = Collections.emptyList();
96         if (isEncoded(entity)) {
97             final String content = EntityUtils.toString(entity);
98             final Header encoding = entity.getContentEncoding();
99             if (content != null && content.length() > 0) {
100                 result = new ArrayList <NameValuePair>();
101                 parse(result, new Scanner(content),
102                         encoding != null ? encoding.getValue() : null);
103             }
104         }
105         return result;
106     }
107 
108     /**
109      * Returns true if the entity's Content-Type header is
110      * <code>application/x-www-form-urlencoded</code>.
111      */
isEncoded(final HttpEntity entity)112     public static boolean isEncoded (final HttpEntity entity) {
113         final Header contentType = entity.getContentType();
114         return (contentType != null && contentType.getValue().equalsIgnoreCase(CONTENT_TYPE));
115     }
116 
117     /**
118      * Adds all parameters within the Scanner to the list of
119      * <code>parameters</code>, as encoded by <code>encoding</code>. For
120      * example, a scanner containing the string <code>a=1&b=2&c=3</code> would
121      * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the
122      * list of parameters.
123      *
124      * @param parameters
125      *            List to add parameters to.
126      * @param scanner
127      *            Input that contains the parameters to parse.
128      * @param encoding
129      *            Encoding to use when decoding the parameters.
130      */
parse( final List <NameValuePair> parameters, final Scanner scanner, final String encoding)131     public static void parse (
132             final List <NameValuePair> parameters,
133             final Scanner scanner,
134             final String encoding) {
135         scanner.useDelimiter(PARAMETER_SEPARATOR);
136         while (scanner.hasNext()) {
137             final String[] nameValue = scanner.next().split(NAME_VALUE_SEPARATOR);
138             if (nameValue.length == 0 || nameValue.length > 2)
139                 throw new IllegalArgumentException("bad parameter");
140 
141             final String name = decode(nameValue[0], encoding);
142             String value = null;
143             if (nameValue.length == 2)
144                 value = decode(nameValue[1], encoding);
145             parameters.add(new BasicNameValuePair(name, value));
146         }
147     }
148 
149     /**
150      * Returns a String that is suitable for use as an <code>application/x-www-form-urlencoded</code>
151      * list of parameters in an HTTP PUT or HTTP POST.
152      *
153      * @param parameters  The parameters to include.
154      * @param encoding The encoding to use.
155      */
format( final List <? extends NameValuePair> parameters, final String encoding)156     public static String format (
157             final List <? extends NameValuePair> parameters,
158             final String encoding) {
159         final StringBuilder result = new StringBuilder();
160         for (final NameValuePair parameter : parameters) {
161             final String encodedName = encode(parameter.getName(), encoding);
162             final String value = parameter.getValue();
163             final String encodedValue = value != null ? encode(value, encoding) : "";
164             if (result.length() > 0)
165                 result.append(PARAMETER_SEPARATOR);
166             result.append(encodedName);
167             result.append(NAME_VALUE_SEPARATOR);
168             result.append(encodedValue);
169         }
170         return result.toString();
171     }
172 
decode(final String content, final String encoding)173     private static String decode (final String content, final String encoding) {
174         try {
175             return URLDecoder.decode(content,
176                     encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET);
177         } catch (UnsupportedEncodingException problem) {
178             throw new IllegalArgumentException(problem);
179         }
180     }
181 
encode(final String content, final String encoding)182     private static String encode (final String content, final String encoding) {
183         try {
184             return URLEncoder.encode(content,
185                     encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET);
186         } catch (UnsupportedEncodingException problem) {
187             throw new IllegalArgumentException(problem);
188         }
189     }
190 
191 }
192