001: /*
002: * ====================================================================
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: * ====================================================================
019: *
020: * This software consists of voluntary contributions made by many
021: * individuals on behalf of the Apache Software Foundation. For more
022: * information on the Apache Software Foundation, please see
023: * <http://www.apache.org/>.
024: *
025: * [Additional notices, if required by prior licensing conditions]
026: *
027: */
028:
029: package org.apache.commons.httpclient;
030:
031: import junit.framework.Test;
032: import junit.framework.TestSuite;
033:
034: import java.io.ByteArrayInputStream;
035: import java.io.ByteArrayOutputStream;
036: import java.io.IOException;
037: import java.io.InputStream;
038: import java.util.HashMap;
039: import java.util.Map;
040: import java.util.StringTokenizer;
041:
042: import org.apache.commons.httpclient.methods.GetMethod;
043: import org.apache.commons.httpclient.methods.PostMethod;
044: import org.apache.commons.httpclient.methods.RequestEntity;
045: import org.apache.commons.httpclient.methods.StringRequestEntity;
046: import org.apache.commons.httpclient.util.URIUtil;
047:
048: /**
049: * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
050: * @author <a href="mailto:ajmas@bigfoot.com">Andre John Mas</a>
051: * @author <a href="mailto:laura@lwerner.org">Laura Werner</a>
052: */
053:
054: public class TestMethodCharEncoding extends HttpClientTestBase {
055:
056: static final String CHARSET_DEFAULT = "ISO-8859-1";
057: static final String CHARSET_ASCII = "US-ASCII";
058: static final String CHARSET_UTF8 = "UTF-8";
059: static final String CHARSET_KOI8_R = "KOI8_R";
060: static final String CHARSET_WIN1251 = "Cp1251";
061:
062: static final int SWISS_GERMAN_STUFF_UNICODE[] = { 0x47, 0x72, 0xFC,
063: 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 };
064:
065: static final int SWISS_GERMAN_STUFF_ISO8859_1[] = { 0x47, 0x72,
066: 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 };
067:
068: static final int SWISS_GERMAN_STUFF_UTF8[] = { 0x47, 0x72, 0xC3,
069: 0xBC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xC3, 0xA4, 0x6D, 0xC3,
070: 0xA4 };
071:
072: static final int RUSSIAN_STUFF_UNICODE[] = { 0x412, 0x441, 0x435,
073: 0x43C, 0x5F, 0x43F, 0x440, 0x438, 0x432, 0x435, 0x442 };
074:
075: static final int RUSSIAN_STUFF_UTF8[] = { 0xD0, 0x92, 0xD1, 0x81,
076: 0xD0, 0xB5, 0xD0, 0xBC, 0x5F, 0xD0, 0xBF, 0xD1, 0x80, 0xD0,
077: 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x82 };
078:
079: static final int RUSSIAN_STUFF_KOI8R[] = { 0xF7, 0xD3, 0xC5, 0xCD,
080: 0x5F, 0xD0, 0xD2, 0xC9, 0xD7, 0xC5, 0xD4 };
081:
082: static final int RUSSIAN_STUFF_WIN1251[] = { 0xC2, 0xF1, 0xE5,
083: 0xEC, 0x5F, 0xEF, 0xF0, 0xE8, 0xE2, 0xE5, 0xF2 };
084:
085: // ------------------------------------------------------------ Constructor
086:
087: public TestMethodCharEncoding(final String testName)
088: throws IOException {
089: super (testName);
090: }
091:
092: // ------------------------------------------------------- TestCase Methods
093:
094: public static Test suite() {
095: return new TestSuite(TestMethodCharEncoding.class);
096: }
097:
098: // ----------------------------------------------------------------- Tests
099:
100: public void testRequestCharEncoding() throws IOException {
101:
102: GetMethod httpget = new GetMethod("/");
103: assertEquals(CHARSET_DEFAULT, httpget.getRequestCharSet());
104: httpget.setRequestHeader("Content-Type", "text/plain; charset="
105: + CHARSET_ASCII);
106: assertEquals(CHARSET_ASCII, httpget.getRequestCharSet());
107: httpget.setRequestHeader("Content-Type", "text/plain; charset="
108: + CHARSET_UTF8);
109: assertEquals(CHARSET_UTF8, httpget.getRequestCharSet());
110:
111: }
112:
113: public void testNoExplicitCharEncoding() throws Exception {
114: this .server.setHttpService(new EchoService());
115:
116: GetMethod httpget = new GetMethod("/test/");
117: httpget.setRequestHeader("Content-Type", "text/plain");
118: try {
119: this .client.executeMethod(httpget);
120: assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
121: assertEquals(CHARSET_DEFAULT, httpget.getResponseCharSet());
122: } finally {
123: httpget.releaseConnection();
124: }
125: }
126:
127: public void testExplicitCharEncoding() throws Exception {
128: this .server.setHttpService(new EchoService());
129:
130: GetMethod httpget = new GetMethod("/test/");
131: httpget.setRequestHeader("Content-Type", "text/plain; charset="
132: + CHARSET_UTF8);
133: try {
134: this .client.executeMethod(httpget);
135: assertEquals(HttpStatus.SC_OK, httpget.getStatusCode());
136: assertEquals(CHARSET_UTF8, httpget.getResponseCharSet());
137: } finally {
138: httpget.releaseConnection();
139: }
140: }
141:
142: private String constructString(int[] unicodeChars) {
143: StringBuffer buffer = new StringBuffer();
144: if (unicodeChars != null) {
145: for (int i = 0; i < unicodeChars.length; i++) {
146: buffer.append((char) unicodeChars[i]);
147: }
148: }
149: return buffer.toString();
150: }
151:
152: private void verifyEncoding(RequestEntity entity, int[] sample)
153: throws IOException {
154:
155: assertNotNull("Request body", entity);
156:
157: ByteArrayOutputStream bos = new ByteArrayOutputStream();
158: entity.writeRequest(bos);
159:
160: InputStream instream = new ByteArrayInputStream(bos
161: .toByteArray());
162: for (int i = 0; i < sample.length; i++) {
163: int b = instream.read();
164: assertTrue("Unexpected end of stream", b != -1);
165: if (sample[i] != b) {
166: fail("Invalid request body encoding");
167: }
168: }
169: assertTrue("End of stream expected", instream.read() == -1);
170: }
171:
172: public void testLatinAccentInRequestBody() throws IOException {
173: PostMethod httppost = new PostMethod("/");
174: String s = constructString(SWISS_GERMAN_STUFF_UNICODE);
175: // Test default encoding ISO-8859-1
176: httppost.setRequestEntity(new StringRequestEntity(s,
177: "text/plain", CHARSET_DEFAULT));
178: verifyEncoding(httppost.getRequestEntity(),
179: SWISS_GERMAN_STUFF_ISO8859_1);
180: // Test UTF-8 encoding
181: httppost.setRequestEntity(new StringRequestEntity(s,
182: "text/plain", CHARSET_UTF8));
183: verifyEncoding(httppost.getRequestEntity(),
184: SWISS_GERMAN_STUFF_UTF8);
185:
186: }
187:
188: public void testRussianInRequestBody() throws IOException {
189: PostMethod httppost = new PostMethod("/");
190: String s = constructString(RUSSIAN_STUFF_UNICODE);
191: // Test UTF-8 encoding
192: httppost.setRequestEntity(new StringRequestEntity(s,
193: "text/plain", CHARSET_UTF8));
194: verifyEncoding(httppost.getRequestEntity(), RUSSIAN_STUFF_UTF8);
195: // Test KOI8-R
196: httppost.setRequestEntity(new StringRequestEntity(s,
197: "text/plain", CHARSET_KOI8_R));
198: verifyEncoding(httppost.getRequestEntity(), RUSSIAN_STUFF_KOI8R);
199: // Test WIN1251
200: httppost.setRequestEntity(new StringRequestEntity(s,
201: "text/plain", CHARSET_WIN1251));
202: verifyEncoding(httppost.getRequestEntity(),
203: RUSSIAN_STUFF_WIN1251);
204: }
205:
206: public void testQueryParams() throws Exception {
207:
208: GetMethod get = new GetMethod("/");
209:
210: String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
211: String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
212:
213: get.setQueryString(new NameValuePair[] {
214: new NameValuePair("ru", ru_msg),
215: new NameValuePair("ch", ch_msg) });
216:
217: Map params = new HashMap();
218: StringTokenizer tokenizer = new StringTokenizer(get
219: .getQueryString(), "&");
220: while (tokenizer.hasMoreTokens()) {
221: String s = tokenizer.nextToken();
222: int i = s.indexOf('=');
223: assertTrue("Invalid url-encoded parameters", i != -1);
224: String name = s.substring(0, i).trim();
225: String value = s.substring(i + 1, s.length()).trim();
226: value = URIUtil.decode(value, CHARSET_UTF8);
227: params.put(name, value);
228: }
229: assertEquals(ru_msg, params.get("ru"));
230: assertEquals(ch_msg, params.get("ch"));
231: }
232:
233: public void testUrlEncodedRequestBody() throws Exception {
234:
235: PostMethod httppost = new PostMethod("/");
236:
237: String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
238: String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
239:
240: httppost.setRequestBody(new NameValuePair[] {
241: new NameValuePair("ru", ru_msg),
242: new NameValuePair("ch", ch_msg) });
243:
244: httppost.setRequestHeader("Content-Type",
245: PostMethod.FORM_URL_ENCODED_CONTENT_TYPE + "; charset="
246: + CHARSET_UTF8);
247:
248: ByteArrayOutputStream bos = new ByteArrayOutputStream();
249: httppost.getRequestEntity().writeRequest(bos);
250:
251: Map params = new HashMap();
252: StringTokenizer tokenizer = new StringTokenizer(new String(bos
253: .toByteArray(), CHARSET_UTF8), "&");
254: while (tokenizer.hasMoreTokens()) {
255: String s = tokenizer.nextToken();
256: int i = s.indexOf('=');
257: assertTrue("Invalid url-encoded parameters", i != -1);
258: String name = s.substring(0, i).trim();
259: String value = s.substring(i + 1, s.length()).trim();
260: value = URIUtil.decode(value, CHARSET_UTF8);
261: params.put(name, value);
262: }
263: assertEquals(ru_msg, params.get("ru"));
264: assertEquals(ch_msg, params.get("ch"));
265: }
266:
267: public void testRequestEntityLength() throws IOException {
268: String s = constructString(SWISS_GERMAN_STUFF_UNICODE);
269: RequestEntity requestentity = new StringRequestEntity(s,
270: "text/plain", CHARSET_UTF8);
271: assertEquals(s.getBytes(CHARSET_UTF8).length, requestentity
272: .getContentLength());
273: }
274:
275: }
|