1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.commons.httpclient;
29
30 import junit.framework.Test;
31 import junit.framework.TestCase;
32 import junit.framework.TestSuite;
33
34 import java.io.ByteArrayInputStream;
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.util.HashMap;
39 import java.util.Map;
40 import java.util.StringTokenizer;
41
42 import org.apache.commons.httpclient.methods.GetMethod;
43 import org.apache.commons.httpclient.methods.PostMethod;
44 import org.apache.commons.httpclient.methods.RequestEntity;
45 import org.apache.commons.httpclient.methods.StringRequestEntity;
46 import org.apache.commons.httpclient.util.URIUtil;
47
48 /***
49 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
50 * @author <a href="mailto:ajmas@bigfoot.com">Andre John Mas</a>
51 * @author <a href="mailto:laura@lwerner.org">Laura Werner</a>
52 */
53
54 public class TestMethodCharEncoding extends TestCase {
55
56 static final String CHARSET_DEFAULT = "ISO-8859-1";
57 static final String CHARSET_ASCII = "US-ASCII";
58 static final String CHARSET_UTF8 = "UTF-8";
59 static final String CHARSET_KOI8_R = "KOI8_R";
60 static final String CHARSET_WIN1251 = "Cp1251";
61
62 static final int SWISS_GERMAN_STUFF_UNICODE [] = {
63 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
64 };
65
66 static final int SWISS_GERMAN_STUFF_ISO8859_1 [] = {
67 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
68 };
69
70 static final int SWISS_GERMAN_STUFF_UTF8 [] = {
71 0x47, 0x72, 0xC3, 0xBC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xC3, 0xA4,
72 0x6D, 0xC3, 0xA4
73 };
74
75 static final int RUSSIAN_STUFF_UNICODE [] = {
76 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
77 0x432, 0x435, 0x442
78 };
79
80 static final int RUSSIAN_STUFF_UTF8 [] = {
81 0xD0, 0x92, 0xD1, 0x81, 0xD0, 0xB5, 0xD0, 0xBC, 0x5F,
82 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0,
83 0xB5, 0xD1, 0x82
84 };
85
86 static final int RUSSIAN_STUFF_KOI8R [] = {
87 0xF7, 0xD3, 0xC5, 0xCD, 0x5F, 0xD0, 0xD2, 0xC9, 0xD7,
88 0xC5, 0xD4
89 };
90
91 static final int RUSSIAN_STUFF_WIN1251 [] = {
92 0xC2, 0xF1, 0xE5, 0xEC, 0x5F, 0xEF, 0xF0, 0xE8, 0xE2,
93 0xE5, 0xF2
94 };
95
96
97
98 public TestMethodCharEncoding(String testName) {
99 super(testName);
100 }
101
102
103
104 public static Test suite() {
105 return new TestSuite(TestMethodCharEncoding.class);
106 }
107
108
109
110
111 public void testRequestCharEncoding() throws IOException {
112
113 GetMethod httpget = new GetMethod("/");
114 assertEquals(CHARSET_DEFAULT, httpget.getRequestCharSet());
115 httpget.setRequestHeader("Content-Type", "text/plain; charset=" + CHARSET_ASCII);
116 assertEquals(CHARSET_ASCII, httpget.getRequestCharSet());
117 httpget.setRequestHeader("Content-Type", "text/plain; charset=" + CHARSET_UTF8);
118 assertEquals(CHARSET_UTF8, httpget.getRequestCharSet());
119
120 }
121
122 public void testResponseCharEncoding() throws Exception {
123
124 SimpleHttpConnection conn = new SimpleHttpConnection();
125 String body = "stuff";
126 String headers1 = "HTTP/1.1 200 OK\r\n"
127 +"Content-Length: 5\r\n";
128 conn.addResponse(headers1, body);
129 conn.open();
130 GetMethod httpget = new GetMethod("/");
131 httpget.execute(new HttpState(), conn);
132 assertEquals(CHARSET_DEFAULT, httpget.getResponseCharSet());
133 conn.close();
134
135 httpget = new GetMethod("/");
136 String headers2 = "HTTP/1.1 200 OK\r\n"
137 +"Content-Type: text/plain\r\n"
138 +"Content-Length: 5\r\n";
139 conn.addResponse(headers2, body);
140 conn.open();
141 httpget.execute(new HttpState(), conn);
142 assertEquals(CHARSET_DEFAULT, httpget.getResponseCharSet());
143 conn.close();
144
145 httpget = new GetMethod("/");
146 String headers3 = "HTTP/1.1 200 OK\r\n"
147 +"Content-Type: text/plain; charset=" + CHARSET_UTF8 + "\r\n"
148 +"Content-Length: 5\r\n";
149 conn.addResponse(headers3, body);
150 conn.open();
151 httpget.execute(new HttpState(), conn);
152 assertEquals(CHARSET_UTF8, httpget.getResponseCharSet());
153 conn.close();
154 }
155
156
157 private String constructString(int [] unicodeChars) {
158 StringBuffer buffer = new StringBuffer();
159 if (unicodeChars != null) {
160 for (int i = 0; i < unicodeChars.length; i++) {
161 buffer.append((char)unicodeChars[i]);
162 }
163 }
164 return buffer.toString();
165 }
166
167
168 private void verifyEncoding(RequestEntity entity, int[] sample)
169 throws IOException {
170
171 assertNotNull("Request body", entity);
172
173 ByteArrayOutputStream bos = new ByteArrayOutputStream();
174 entity.writeRequest(bos);
175
176 InputStream instream = new ByteArrayInputStream(bos.toByteArray());
177 for (int i = 0; i < sample.length; i++) {
178 int b = instream.read();
179 assertTrue("Unexpected end of stream", b != -1);
180 if (sample[i] != b) {
181 fail("Invalid request body encoding");
182 }
183 }
184 assertTrue("End of stream expected", instream.read() == -1);
185 }
186
187 public void testLatinAccentInRequestBody() throws IOException {
188 PostMethod httppost = new PostMethod("/");
189 String s = constructString(SWISS_GERMAN_STUFF_UNICODE);
190
191 httppost.setRequestEntity(
192 new StringRequestEntity(s, "text/plain", CHARSET_DEFAULT));
193 verifyEncoding(httppost.getRequestEntity(), SWISS_GERMAN_STUFF_ISO8859_1);
194
195 httppost.setRequestEntity(
196 new StringRequestEntity(s, "text/plain", CHARSET_UTF8));
197 verifyEncoding(httppost.getRequestEntity(), SWISS_GERMAN_STUFF_UTF8);
198
199 }
200
201 public void testRussianInRequestBody() throws IOException {
202 PostMethod httppost = new PostMethod("/");
203 String s = constructString(RUSSIAN_STUFF_UNICODE);
204
205 httppost.setRequestEntity(
206 new StringRequestEntity(s, "text/plain", CHARSET_UTF8));
207 verifyEncoding(httppost.getRequestEntity(), RUSSIAN_STUFF_UTF8);
208
209 httppost.setRequestEntity(
210 new StringRequestEntity(s, "text/plain", CHARSET_KOI8_R));
211 verifyEncoding(httppost.getRequestEntity(), RUSSIAN_STUFF_KOI8R);
212
213 httppost.setRequestEntity(
214 new StringRequestEntity(s, "text/plain", CHARSET_WIN1251));
215 verifyEncoding(httppost.getRequestEntity(), RUSSIAN_STUFF_WIN1251);
216 }
217
218 public void testQueryParams() throws Exception {
219
220 GetMethod get = new GetMethod("/");
221
222 String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
223 String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
224
225 get.setQueryString(new NameValuePair[] {
226 new NameValuePair("ru", ru_msg),
227 new NameValuePair("ch", ch_msg)
228 });
229
230 Map params = new HashMap();
231 StringTokenizer tokenizer = new StringTokenizer(
232 get.getQueryString(), "&");
233 while (tokenizer.hasMoreTokens()) {
234 String s = tokenizer.nextToken();
235 int i = s.indexOf('=');
236 assertTrue("Invalid url-encoded parameters", i != -1);
237 String name = s.substring(0, i).trim();
238 String value = s.substring(i + 1, s.length()).trim();
239 value = URIUtil.decode(value, CHARSET_UTF8);
240 params.put(name, value);
241 }
242 assertEquals(ru_msg, params.get("ru"));
243 assertEquals(ch_msg, params.get("ch"));
244 }
245
246 public void testUrlEncodedRequestBody() throws Exception {
247
248 PostMethod httppost = new PostMethod("/");
249
250 String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
251 String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
252
253 httppost.setRequestBody(new NameValuePair[] {
254 new NameValuePair("ru", ru_msg),
255 new NameValuePair("ch", ch_msg)
256 });
257
258 httppost.setRequestHeader("Content-Type", PostMethod.FORM_URL_ENCODED_CONTENT_TYPE
259 + "; charset=" + CHARSET_UTF8);
260
261 ByteArrayOutputStream bos = new ByteArrayOutputStream();
262 httppost.getRequestEntity().writeRequest(bos);
263
264 Map params = new HashMap();
265 StringTokenizer tokenizer = new StringTokenizer(
266 new String(bos.toByteArray(), CHARSET_UTF8), "&");
267 while (tokenizer.hasMoreTokens()) {
268 String s = tokenizer.nextToken();
269 int i = s.indexOf('=');
270 assertTrue("Invalid url-encoded parameters", i != -1);
271 String name = s.substring(0, i).trim();
272 String value = s.substring(i + 1, s.length()).trim();
273 value = URIUtil.decode(value, CHARSET_UTF8);
274 params.put(name, value);
275 }
276 assertEquals(ru_msg, params.get("ru"));
277 assertEquals(ch_msg, params.get("ch"));
278 }
279
280 }