1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package javax.servlet.http;
18
19 import javax.servlet.ServletInputStream;
20 import java.util.Hashtable;
21 import java.util.ResourceBundle;
22 import java.util.StringTokenizer;
23 import java.io.IOException;
24
25 /**
26 * @deprecated As of Java(tm) Servlet API 2.3.
27 * These methods were only useful
28 * with the default encoding and have been moved
29 * to the request interfaces.
30 *
31 */
32
33
34 public class HttpUtils {
35
36 private static final String LSTRING_FILE =
37 "javax.servlet.http.LocalStrings";
38 private static ResourceBundle lStrings =
39 ResourceBundle.getBundle(LSTRING_FILE);
40
41
42
43 /**
44 * Constructs an empty <code>HttpUtils</code> object.
45 *
46 */
47
48 public HttpUtils() {}
49
50
51
52
53
54 /**
55 *
56 * Parses a query string passed from the client to the
57 * server and builds a <code>HashTable</code> object
58 * with key-value pairs.
59 * The query string should be in the form of a string
60 * packaged by the GET or POST method, that is, it
61 * should have key-value pairs in the form <i>key=value</i>,
62 * with each pair separated from the next by a & character.
63 *
64 * <p>A key can appear more than once in the query string
65 * with different values. However, the key appears only once in
66 * the hashtable, with its value being
67 * an array of strings containing the multiple values sent
68 * by the query string.
69 *
70 * <p>The keys and values in the hashtable are stored in their
71 * decoded form, so
72 * any + characters are converted to spaces, and characters
73 * sent in hexadecimal notation (like <i>%xx</i>) are
74 * converted to ASCII characters.
75 *
76 * @param s a string containing the query to be parsed
77 *
78 * @return a <code>HashTable</code> object built
79 * from the parsed key-value pairs
80 *
81 * @exception IllegalArgumentException if the query string
82 * is invalid
83 *
84 */
85
86 static public Hashtable parseQueryString(String s) {
87
88 String valArray[] = null;
89
90 if (s == null) {
91 throw new IllegalArgumentException();
92 }
93 Hashtable ht = new Hashtable();
94 StringBuffer sb = new StringBuffer();
95 StringTokenizer st = new StringTokenizer(s, "&");
96 while (st.hasMoreTokens()) {
97 String pair = (String)st.nextToken();
98 int pos = pair.indexOf('=');
99 if (pos == -1) {
100
101
102 throw new IllegalArgumentException();
103 }
104 String key = parseName(pair.substring(0, pos), sb);
105 String val = parseName(pair.substring(pos+1, pair.length()), sb);
106 if (ht.containsKey(key)) {
107 String oldVals[] = (String []) ht.get(key);
108 valArray = new String[oldVals.length + 1];
109 for (int i = 0; i < oldVals.length; i++)
110 valArray[i] = oldVals[i];
111 valArray[oldVals.length] = val;
112 } else {
113 valArray = new String[1];
114 valArray[0] = val;
115 }
116 ht.put(key, valArray);
117 }
118 return ht;
119 }
120
121
122
123
124 /**
125 *
126 * Parses data from an HTML form that the client sends to
127 * the server using the HTTP POST method and the
128 * <i>application/x-www-form-urlencoded</i> MIME type.
129 *
130 * <p>The data sent by the POST method contains key-value
131 * pairs. A key can appear more than once in the POST data
132 * with different values. However, the key appears only once in
133 * the hashtable, with its value being
134 * an array of strings containing the multiple values sent
135 * by the POST method.
136 *
137 * <p>The keys and values in the hashtable are stored in their
138 * decoded form, so
139 * any + characters are converted to spaces, and characters
140 * sent in hexadecimal notation (like <i>%xx</i>) are
141 * converted to ASCII characters.
142 *
143 *
144 *
145 * @param len an integer specifying the length,
146 * in characters, of the
147 * <code>ServletInputStream</code>
148 * object that is also passed to this
149 * method
150 *
151 * @param in the <code>ServletInputStream</code>
152 * object that contains the data sent
153 * from the client
154 *
155 * @return a <code>HashTable</code> object built
156 * from the parsed key-value pairs
157 *
158 *
159 * @exception IllegalArgumentException if the data
160 * sent by the POST method is invalid
161 *
162 */
163
164
165 static public Hashtable parsePostData(int len,
166 ServletInputStream in)
167 {
168
169
170
171 if (len <=0)
172 return new Hashtable();
173
174 if (in == null) {
175 throw new IllegalArgumentException();
176 }
177
178
179
180
181 byte[] postedBytes = new byte [len];
182 try {
183 int offset = 0;
184
185 do {
186 int inputLen = in.read (postedBytes, offset, len - offset);
187 if (inputLen <= 0) {
188 String msg = lStrings.getString("err.io.short_read");
189 throw new IllegalArgumentException (msg);
190 }
191 offset += inputLen;
192 } while ((len - offset) > 0);
193
194 } catch (IOException e) {
195 throw new IllegalArgumentException(e.getMessage());
196 }
197
198
199
200
201
202
203 try {
204 String postedBody = new String(postedBytes, 0, len, "8859_1");
205 return parseQueryString(postedBody);
206 } catch (java.io.UnsupportedEncodingException e) {
207
208
209 throw new IllegalArgumentException(e.getMessage());
210 }
211 }
212
213
214
215
216
217
218
219
220 static private String parseName(String s, StringBuffer sb) {
221 sb.setLength(0);
222 for (int i = 0; i < s.length(); i++) {
223 char c = s.charAt(i);
224 switch (c) {
225 case '+':
226 sb.append(' ');
227 break;
228 case '%':
229 try {
230 sb.append((char) Integer.parseInt(s.substring(i+1, i+3),
231 16));
232 i += 2;
233 } catch (NumberFormatException e) {
234
235
236 throw new IllegalArgumentException();
237 } catch (StringIndexOutOfBoundsException e) {
238 String rest = s.substring(i);
239 sb.append(rest);
240 if (rest.length()==2)
241 i++;
242 }
243
244 break;
245 default:
246 sb.append(c);
247 break;
248 }
249 }
250 return sb.toString();
251 }
252
253
254
255
256 /**
257 *
258 * Reconstructs the URL the client used to make the request,
259 * using information in the <code>HttpServletRequest</code> object.
260 * The returned URL contains a protocol, server name, port
261 * number, and server path, but it does not include query
262 * string parameters.
263 *
264 * <p>Because this method returns a <code>StringBuffer</code>,
265 * not a string, you can modify the URL easily, for example,
266 * to append query parameters.
267 *
268 * <p>This method is useful for creating redirect messages
269 * and for reporting errors.
270 *
271 * @param req a <code>HttpServletRequest</code> object
272 * containing the client's request
273 *
274 * @return a <code>StringBuffer</code> object containing
275 * the reconstructed URL
276 *
277 */
278
279 public static StringBuffer getRequestURL (HttpServletRequest req) {
280 StringBuffer url = new StringBuffer ();
281 String scheme = req.getScheme ();
282 int port = req.getServerPort ();
283 String urlPath = req.getRequestURI();
284
285
286
287
288 url.append (scheme);
289 url.append ("://");
290 url.append (req.getServerName ());
291 if ((scheme.equals ("http") && port != 80)
292 || (scheme.equals ("https") && port != 443)) {
293 url.append (':');
294 url.append (req.getServerPort ());
295 }
296
297
298
299
300 url.append(urlPath);
301 return url;
302 }
303 }
304
305
306