• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderValueFormatter.java $
3  * $Revision: 574185 $
4  * $Date: 2007-09-10 02:19:47 -0700 (Mon, 10 Sep 2007) $
5  *
6  * ====================================================================
7  * Licensed to the Apache Software Foundation (ASF) under one
8  * or more contributor license agreements.  See the NOTICE file
9  * distributed with this work for additional information
10  * regarding copyright ownership.  The ASF licenses this file
11  * to you under the Apache License, Version 2.0 (the
12  * "License"); you may not use this file except in compliance
13  * with the License.  You may obtain a copy of the License at
14  *
15  *   http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing,
18  * software distributed under the License is distributed on an
19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20  * KIND, either express or implied.  See the License for the
21  * specific language governing permissions and limitations
22  * under the License.
23  * ====================================================================
24  *
25  * This software consists of voluntary contributions made by many
26  * individuals on behalf of the Apache Software Foundation.  For more
27  * information on the Apache Software Foundation, please see
28  * <http://www.apache.org/>.
29  *
30  */
31 
32 package org.apache.http.message;
33 
34 import org.apache.http.HeaderElement;
35 import org.apache.http.NameValuePair;
36 import org.apache.http.util.CharArrayBuffer;
37 
38 
39 /**
40  * Basic implementation for formatting header value elements.
41  * Instances of this class are stateless and thread-safe.
42  * Derived classes are expected to maintain these properties.
43  *
44  * @author <a href="mailto:oleg at ural.com">Oleg Kalnichevski</a>
45  * @author and others
46  *
47  *
48  * <!-- empty lines above to avoid 'svn diff' context problems -->
49  * @version $Revision: 574185 $
50  *
51  * @since 4.0
52  *
53  * @deprecated Please use {@link java.net.URL#openConnection} instead.
54  *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
55  *     for further details.
56  */
57 @Deprecated
58 public class BasicHeaderValueFormatter implements HeaderValueFormatter {
59 
60     /**
61      * A default instance of this class, for use as default or fallback.
62      * Note that {@link BasicHeaderValueFormatter} is not a singleton, there
63      * can be many instances of the class itself and of derived classes.
64      * The instance here provides non-customized, default behavior.
65      */
66     public final static
67         BasicHeaderValueFormatter DEFAULT = new BasicHeaderValueFormatter();
68 
69 
70     /**
71      * Special characters that can be used as separators in HTTP parameters.
72      * These special characters MUST be in a quoted string to be used within
73      * a parameter value .
74      */
75     public final static String SEPARATORS = " ;,:@()<>\\\"/[]?={}\t";
76 
77 
78     /**
79      * Unsafe special characters that must be escaped using the backslash
80      * character
81      */
82     public final static String UNSAFE_CHARS = "\"\\";
83 
84 
85 
86     // public default constructor
87 
88 
89 
90     /**
91      * Formats an array of header elements.
92      *
93      * @param elems     the header elements to format
94      * @param quote     <code>true</code> to always format with quoted values,
95      *                  <code>false</code> to use quotes only when necessary
96      * @param formatter         the formatter to use, or <code>null</code>
97      *                          for the {@link #DEFAULT default}
98      *
99      * @return  the formatted header elements
100      */
101     public final static
formatElements(final HeaderElement[] elems, final boolean quote, HeaderValueFormatter formatter)102         String formatElements(final HeaderElement[] elems,
103                               final boolean quote,
104                               HeaderValueFormatter formatter) {
105         if (formatter == null)
106             formatter = BasicHeaderValueFormatter.DEFAULT;
107         return formatter.formatElements(null, elems, quote).toString();
108     }
109 
110 
111     // non-javadoc, see interface HeaderValueFormatter
formatElements(CharArrayBuffer buffer, final HeaderElement[] elems, final boolean quote)112     public CharArrayBuffer formatElements(CharArrayBuffer buffer,
113                                           final HeaderElement[] elems,
114                                           final boolean quote) {
115         if (elems == null) {
116             throw new IllegalArgumentException
117                 ("Header element array must not be null.");
118         }
119 
120         int len = estimateElementsLen(elems);
121         if (buffer == null) {
122             buffer = new CharArrayBuffer(len);
123         } else {
124             buffer.ensureCapacity(len);
125         }
126 
127         for (int i=0; i<elems.length; i++) {
128             if (i > 0) {
129                 buffer.append(", ");
130             }
131             formatHeaderElement(buffer, elems[i], quote);
132         }
133 
134         return buffer;
135     }
136 
137 
138     /**
139      * Estimates the length of formatted header elements.
140      *
141      * @param elems     the header elements to format, or <code>null</code>
142      *
143      * @return  a length estimate, in number of characters
144      */
estimateElementsLen(final HeaderElement[] elems)145     protected int estimateElementsLen(final HeaderElement[] elems) {
146         if ((elems == null) || (elems.length < 1))
147             return 0;
148 
149         int result = (elems.length-1) * 2; // elements separated by ", "
150         for (int i=0; i<elems.length; i++) {
151             result += estimateHeaderElementLen(elems[i]);
152         }
153 
154         return result;
155     }
156 
157 
158 
159     /**
160      * Formats a header element.
161      *
162      * @param elem      the header element to format
163      * @param quote     <code>true</code> to always format with quoted values,
164      *                  <code>false</code> to use quotes only when necessary
165      * @param formatter         the formatter to use, or <code>null</code>
166      *                          for the {@link #DEFAULT default}
167      *
168      * @return  the formatted header element
169      */
170     public final static
formatHeaderElement(final HeaderElement elem, boolean quote, HeaderValueFormatter formatter)171         String formatHeaderElement(final HeaderElement elem,
172                                    boolean quote,
173                                    HeaderValueFormatter formatter) {
174         if (formatter == null)
175             formatter = BasicHeaderValueFormatter.DEFAULT;
176         return formatter.formatHeaderElement(null, elem, quote).toString();
177     }
178 
179 
180     // non-javadoc, see interface HeaderValueFormatter
formatHeaderElement(CharArrayBuffer buffer, final HeaderElement elem, final boolean quote)181     public CharArrayBuffer formatHeaderElement(CharArrayBuffer buffer,
182                                                final HeaderElement elem,
183                                                final boolean quote) {
184         if (elem == null) {
185             throw new IllegalArgumentException
186                 ("Header element must not be null.");
187         }
188 
189         int len = estimateHeaderElementLen(elem);
190         if (buffer == null) {
191             buffer = new CharArrayBuffer(len);
192         } else {
193             buffer.ensureCapacity(len);
194         }
195 
196         buffer.append(elem.getName());
197         final String value = elem.getValue();
198         if (value != null) {
199             buffer.append('=');
200             doFormatValue(buffer, value, quote);
201         }
202 
203         final int parcnt = elem.getParameterCount();
204         if (parcnt > 0) {
205             for (int i=0; i<parcnt; i++) {
206                 buffer.append("; ");
207                 formatNameValuePair(buffer, elem.getParameter(i), quote);
208             }
209         }
210 
211         return buffer;
212     }
213 
214 
215     /**
216      * Estimates the length of a formatted header element.
217      *
218      * @param elem      the header element to format, or <code>null</code>
219      *
220      * @return  a length estimate, in number of characters
221      */
estimateHeaderElementLen(final HeaderElement elem)222     protected int estimateHeaderElementLen(final HeaderElement elem) {
223         if (elem == null)
224             return 0;
225 
226         int result = elem.getName().length(); // name
227         final String value = elem.getValue();
228         if (value != null) {
229             // assume quotes, but no escaped characters
230             result += 3 + value.length(); // ="value"
231         }
232 
233         final int parcnt = elem.getParameterCount();
234         if (parcnt > 0) {
235             for (int i=0; i<parcnt; i++) {
236                 result += 2 +                   // ; <param>
237                     estimateNameValuePairLen(elem.getParameter(i));
238             }
239         }
240 
241         return result;
242     }
243 
244 
245 
246 
247     /**
248      * Formats a set of parameters.
249      *
250      * @param nvps      the parameters to format
251      * @param quote     <code>true</code> to always format with quoted values,
252      *                  <code>false</code> to use quotes only when necessary
253      * @param formatter         the formatter to use, or <code>null</code>
254      *                          for the {@link #DEFAULT default}
255      *
256      * @return  the formatted parameters
257      */
258     public final static
formatParameters(final NameValuePair[] nvps, final boolean quote, HeaderValueFormatter formatter)259         String formatParameters(final NameValuePair[] nvps,
260                                 final boolean quote,
261                                 HeaderValueFormatter formatter) {
262         if (formatter == null)
263             formatter = BasicHeaderValueFormatter.DEFAULT;
264         return formatter.formatParameters(null, nvps, quote).toString();
265     }
266 
267 
268     // non-javadoc, see interface HeaderValueFormatter
formatParameters(CharArrayBuffer buffer, NameValuePair[] nvps, boolean quote)269     public CharArrayBuffer formatParameters(CharArrayBuffer buffer,
270                                             NameValuePair[] nvps,
271                                             boolean quote) {
272         if (nvps == null) {
273             throw new IllegalArgumentException
274                 ("Parameters must not be null.");
275         }
276 
277         int len = estimateParametersLen(nvps);
278         if (buffer == null) {
279             buffer = new CharArrayBuffer(len);
280         } else {
281             buffer.ensureCapacity(len);
282         }
283 
284         for (int i = 0; i < nvps.length; i++) {
285             if (i > 0) {
286                 buffer.append("; ");
287             }
288             formatNameValuePair(buffer, nvps[i], quote);
289         }
290 
291         return buffer;
292     }
293 
294 
295     /**
296      * Estimates the length of formatted parameters.
297      *
298      * @param nvps      the parameters to format, or <code>null</code>
299      *
300      * @return  a length estimate, in number of characters
301      */
estimateParametersLen(final NameValuePair[] nvps)302     protected int estimateParametersLen(final NameValuePair[] nvps) {
303         if ((nvps == null) || (nvps.length < 1))
304             return 0;
305 
306         int result = (nvps.length-1) * 2; // "; " between the parameters
307         for (int i=0; i<nvps.length; i++) {
308             result += estimateNameValuePairLen(nvps[i]);
309         }
310 
311         return result;
312     }
313 
314 
315     /**
316      * Formats a name-value pair.
317      *
318      * @param nvp       the name-value pair to format
319      * @param quote     <code>true</code> to always format with a quoted value,
320      *                  <code>false</code> to use quotes only when necessary
321      * @param formatter         the formatter to use, or <code>null</code>
322      *                          for the {@link #DEFAULT default}
323      *
324      * @return  the formatted name-value pair
325      */
326     public final static
formatNameValuePair(final NameValuePair nvp, final boolean quote, HeaderValueFormatter formatter)327         String formatNameValuePair(final NameValuePair nvp,
328                                    final boolean quote,
329                                    HeaderValueFormatter formatter) {
330         if (formatter == null)
331             formatter = BasicHeaderValueFormatter.DEFAULT;
332         return formatter.formatNameValuePair(null, nvp, quote).toString();
333     }
334 
335 
336     // non-javadoc, see interface HeaderValueFormatter
formatNameValuePair(CharArrayBuffer buffer, final NameValuePair nvp, final boolean quote)337     public CharArrayBuffer formatNameValuePair(CharArrayBuffer buffer,
338                                                final NameValuePair nvp,
339                                                final boolean quote) {
340         if (nvp == null) {
341             throw new IllegalArgumentException
342                 ("NameValuePair must not be null.");
343         }
344 
345         int len = estimateNameValuePairLen(nvp);
346         if (buffer == null) {
347             buffer = new CharArrayBuffer(len);
348         } else {
349             buffer.ensureCapacity(len);
350         }
351 
352         buffer.append(nvp.getName());
353         final String value = nvp.getValue();
354         if (value != null) {
355             buffer.append('=');
356             doFormatValue(buffer, value, quote);
357         }
358 
359         return buffer;
360     }
361 
362 
363     /**
364      * Estimates the length of a formatted name-value pair.
365      *
366      * @param nvp       the name-value pair to format, or <code>null</code>
367      *
368      * @return  a length estimate, in number of characters
369      */
estimateNameValuePairLen(final NameValuePair nvp)370     protected int estimateNameValuePairLen(final NameValuePair nvp) {
371         if (nvp == null)
372             return 0;
373 
374         int result = nvp.getName().length(); // name
375         final String value = nvp.getValue();
376         if (value != null) {
377             // assume quotes, but no escaped characters
378             result += 3 + value.length(); // ="value"
379         }
380         return result;
381     }
382 
383 
384     /**
385      * Actually formats the value of a name-value pair.
386      * This does not include a leading = character.
387      * Called from {@link #formatNameValuePair formatNameValuePair}.
388      *
389      * @param buffer    the buffer to append to, never <code>null</code>
390      * @param value     the value to append, never <code>null</code>
391      * @param quote     <code>true</code> to always format with quotes,
392      *                  <code>false</code> to use quotes only when necessary
393      */
doFormatValue(final CharArrayBuffer buffer, final String value, boolean quote)394     protected void doFormatValue(final CharArrayBuffer buffer,
395                                  final String value,
396                                  boolean quote) {
397 
398         if (!quote) {
399             for (int i = 0; (i < value.length()) && !quote; i++) {
400                 quote = isSeparator(value.charAt(i));
401             }
402         }
403 
404         if (quote) {
405             buffer.append('"');
406         }
407         for (int i = 0; i < value.length(); i++) {
408             char ch = value.charAt(i);
409             if (isUnsafe(ch)) {
410                 buffer.append('\\');
411             }
412             buffer.append(ch);
413         }
414         if (quote) {
415             buffer.append('"');
416         }
417     }
418 
419 
420     /**
421      * Checks whether a character is a {@link #SEPARATORS separator}.
422      *
423      * @param ch        the character to check
424      *
425      * @return  <code>true</code> if the character is a separator,
426      *          <code>false</code> otherwise
427      */
isSeparator(char ch)428     protected boolean isSeparator(char ch) {
429         return SEPARATORS.indexOf(ch) >= 0;
430     }
431 
432 
433     /**
434      * Checks whether a character is {@link #UNSAFE_CHARS unsafe}.
435      *
436      * @param ch        the character to check
437      *
438      * @return  <code>true</code> if the character is unsafe,
439      *          <code>false</code> otherwise
440      */
isUnsafe(char ch)441     protected boolean isUnsafe(char ch) {
442         return UNSAFE_CHARS.indexOf(ch) >= 0;
443     }
444 
445 
446 } // class BasicHeaderValueFormatter
447