View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http.message;
29  
30  import org.apache.hc.core5.annotation.Contract;
31  import org.apache.hc.core5.annotation.ThreadingBehavior;
32  import org.apache.hc.core5.http.HeaderElement;
33  import org.apache.hc.core5.http.NameValuePair;
34  import org.apache.hc.core5.util.Args;
35  import org.apache.hc.core5.util.CharArrayBuffer;
36  
37  /**
38   * Default {@link org.apache.hc.core5.http.message.HeaderValueFormatter} implementation.
39   *
40   * @since 4.0
41   */
42  @Contract(threading = ThreadingBehavior.IMMUTABLE)
43  public class BasicHeaderValueFormatter implements HeaderValueFormatter {
44  
45      public final static BasicHeaderValueFormatterrValueFormatter.html#BasicHeaderValueFormatter">BasicHeaderValueFormatter INSTANCE = new BasicHeaderValueFormatter();
46  
47      private final static String SEPARATORS = " ;,:@()<>\\\"/[]?={}\t";
48      private final static String UNSAFE_CHARS = "\"\\";
49  
50      public BasicHeaderValueFormatter() {
51          super();
52      }
53  
54      @Override
55      public void formatElements(
56              final CharArrayBuffer buffer, final HeaderElement[] elems, final boolean quote) {
57          Args.notNull(buffer, "Char array buffer");
58          Args.notNull(elems, "Header element array");
59  
60          for (int i = 0; i < elems.length; i++) {
61              if (i > 0) {
62                  buffer.append(", ");
63              }
64              formatHeaderElement(buffer, elems[i], quote);
65          }
66      }
67  
68      @Override
69      public void formatHeaderElement(
70              final CharArrayBuffer buffer, final HeaderElement elem, final boolean quote) {
71          Args.notNull(buffer, "Char array buffer");
72          Args.notNull(elem, "Header element");
73  
74          buffer.append(elem.getName());
75          final String value = elem.getValue();
76          if (value != null) {
77              buffer.append('=');
78              formatValue(buffer, value, quote);
79          }
80  
81          final int c = elem.getParameterCount();
82          if (c > 0) {
83              for (int i = 0; i < c; i++) {
84                  buffer.append("; ");
85                  formatNameValuePair(buffer, elem.getParameter(i), quote);
86              }
87          }
88      }
89  
90      @Override
91      public void formatParameters(
92              final CharArrayBuffer buffer, final NameValuePair[] nvps, final boolean quote) {
93          Args.notNull(buffer, "Char array buffer");
94          Args.notNull(nvps, "Header parameter array");
95  
96          for (int i = 0; i < nvps.length; i++) {
97              if (i > 0) {
98                  buffer.append("; ");
99              }
100             formatNameValuePair(buffer, nvps[i], quote);
101         }
102     }
103 
104     @Override
105     public void formatNameValuePair(
106             final CharArrayBuffer buffer, final NameValuePair nvp, final boolean quote) {
107         Args.notNull(buffer, "Char array buffer");
108         Args.notNull(nvp, "Name / value pair");
109 
110         buffer.append(nvp.getName());
111         final String value = nvp.getValue();
112         if (value != null) {
113             buffer.append('=');
114             formatValue(buffer, value, quote);
115         }
116     }
117 
118     void formatValue(final CharArrayBuffer buffer, final String value, final boolean quote) {
119 
120         boolean quoteFlag = quote;
121         if (!quoteFlag) {
122             for (int i = 0; (i < value.length()) && !quoteFlag; i++) {
123                 quoteFlag = isSeparator(value.charAt(i));
124             }
125         }
126 
127         if (quoteFlag) {
128             buffer.append('"');
129         }
130         for (int i = 0; i < value.length(); i++) {
131             final char ch = value.charAt(i);
132             if (isUnsafe(ch)) {
133                 buffer.append('\\');
134             }
135             buffer.append(ch);
136         }
137         if (quoteFlag) {
138             buffer.append('"');
139         }
140     }
141 
142     boolean isSeparator(final char ch) {
143         return SEPARATORS.indexOf(ch) >= 0;
144     }
145 
146     boolean isUnsafe(final char ch) {
147         return UNSAFE_CHARS.indexOf(ch) >= 0;
148     }
149 
150 }