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