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.http.impl.nio.reactor;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.nio.ByteBuffer;
33 import java.nio.channels.Channels;
34 import java.nio.channels.ReadableByteChannel;
35 import java.nio.channels.WritableByteChannel;
36 import java.nio.charset.CharacterCodingException;
37 import java.nio.charset.Charset;
38 import java.nio.charset.CharsetDecoder;
39 import java.nio.charset.CharsetEncoder;
40 import java.nio.charset.CodingErrorAction;
41 import java.util.Arrays;
42 import java.util.Collection;
43
44 import org.apache.http.Consts;
45 import org.apache.http.MessageConstraintException;
46 import org.apache.http.config.MessageConstraints;
47 import org.apache.http.nio.reactor.SessionInputBuffer;
48 import org.apache.http.nio.reactor.SessionOutputBuffer;
49 import org.apache.http.nio.util.ByteBufferAllocator;
50 import org.apache.http.nio.util.DirectByteBufferAllocator;
51 import org.apache.http.nio.util.HeapByteBufferAllocator;
52 import org.apache.http.util.CharArrayBuffer;
53 import org.junit.Assert;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 import org.junit.runners.Parameterized;
57 import org.junit.runners.Parameterized.Parameters;
58
59
60
61
62 @RunWith(Parameterized.class)
63 public class TestSessionInOutBuffers {
64
65 private final ByteBufferAllocator allocator;
66
67 public TestSessionInOutBuffers(final ByteBufferAllocator allocator) {
68 super();
69 this.allocator = allocator;
70 }
71
72 @Parameters
73 public static Collection<Object[]> getParameters() {
74
75 return Arrays.asList(
76 new Object[] { HeapByteBufferAllocator.INSTANCE },
77 new Object[] { DirectByteBufferAllocator.INSTANCE });
78 }
79
80 private static WritableByteChannel newChannel(final ByteArrayOutputStream outStream) {
81 return Channels.newChannel(outStream);
82 }
83
84 private static ReadableByteChannel newChannel(final byte[] bytes) {
85 return Channels.newChannel(new ByteArrayInputStream(bytes));
86 }
87
88 private static ReadableByteChannel newChannel(final String s, final Charset charset) {
89 return Channels.newChannel(new ByteArrayInputStream(s.getBytes(charset)));
90 }
91
92 private static ReadableByteChannel newChannel(final String s) {
93 return newChannel(s, Consts.ASCII);
94 }
95
96 @Test
97 public void testReadLineChunks() throws Exception {
98 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, null, this.allocator);
99
100 ReadableByteChannel channel = newChannel("One\r\nTwo\r\nThree");
101
102 inbuf.fill(channel);
103
104 final CharArrayBuffer line = new CharArrayBuffer(64);
105
106 line.clear();
107 Assert.assertTrue(inbuf.readLine(line, false));
108 Assert.assertEquals("One", line.toString());
109
110 line.clear();
111 Assert.assertTrue(inbuf.readLine(line, false));
112 Assert.assertEquals("Two", line.toString());
113
114 line.clear();
115 Assert.assertFalse(inbuf.readLine(line, false));
116
117 channel = newChannel("\r\nFour");
118 inbuf.fill(channel);
119
120 line.clear();
121 Assert.assertTrue(inbuf.readLine(line, false));
122 Assert.assertEquals("Three", line.toString());
123
124 inbuf.fill(channel);
125
126 line.clear();
127 Assert.assertTrue(inbuf.readLine(line, true));
128 Assert.assertEquals("Four", line.toString());
129
130 line.clear();
131 Assert.assertFalse(inbuf.readLine(line, true));
132 }
133
134 @Test
135 public void testLineLimit() throws Exception {
136 final String s = "LoooooooooooooooooooooooooOOOOOOOOOOOOOOOOOOoooooooooooooooooooooong line\r\n";
137 final CharArrayBuffer line = new CharArrayBuffer(64);
138 final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(128, 128,
139 MessageConstraints.DEFAULT, null, this.allocator);
140 final ReadableByteChannel channel1 = newChannel(s);
141 inbuf1.fill(channel1);
142
143 Assert.assertTrue(inbuf1.readLine(line, false));
144
145 line.clear();
146 final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(128, 128,
147 MessageConstraints.lineLen(10), null, this.allocator);
148 final ReadableByteChannel channel2 = newChannel(s);
149 inbuf2.fill(channel2);
150 try {
151 inbuf2.readLine(line, false);
152 Assert.fail("MessageConstraintException expected");
153 } catch (final MessageConstraintException ex) {
154 }
155 }
156
157 @Test
158 public void testLineLimitBufferFull() throws Exception {
159 final String s = "LoooooooooooooooooooooooooOOOOOOOOOOOOOOOOOOoooooooooooooooooooooong line\r\n";
160 final CharArrayBuffer line = new CharArrayBuffer(64);
161 final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(32, 32,
162 MessageConstraints.DEFAULT, null, this.allocator);
163 final ReadableByteChannel channel1 = newChannel(s);
164 inbuf1.fill(channel1);
165
166 Assert.assertFalse(inbuf1.readLine(line, false));
167
168 line.clear();
169 final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(32, 32,
170 MessageConstraints.lineLen(10), null, this.allocator);
171 final ReadableByteChannel channel2 = newChannel(s);
172 inbuf2.fill(channel2);
173 try {
174 inbuf2.readLine(line, false);
175 Assert.fail("MessageConstraintException expected");
176 } catch (final MessageConstraintException ex) {
177 }
178 }
179
180 @Test
181 public void testWriteLineChunks() throws Exception {
182 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16, null, this.allocator);
183 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, null, this.allocator);
184
185 ReadableByteChannel inChannel = newChannel("One\r\nTwo\r\nThree");
186
187 inbuf.fill(inChannel);
188
189 final CharArrayBuffer line = new CharArrayBuffer(64);
190
191 line.clear();
192 Assert.assertTrue(inbuf.readLine(line, false));
193 Assert.assertEquals("One", line.toString());
194
195 outbuf.writeLine(line);
196
197 line.clear();
198 Assert.assertTrue(inbuf.readLine(line, false));
199 Assert.assertEquals("Two", line.toString());
200
201 outbuf.writeLine(line);
202
203 line.clear();
204 Assert.assertFalse(inbuf.readLine(line, false));
205
206 inChannel = newChannel("\r\nFour");
207 inbuf.fill(inChannel);
208
209 line.clear();
210 Assert.assertTrue(inbuf.readLine(line, false));
211 Assert.assertEquals("Three", line.toString());
212
213 outbuf.writeLine(line);
214
215 inbuf.fill(inChannel);
216
217 line.clear();
218 Assert.assertTrue(inbuf.readLine(line, true));
219 Assert.assertEquals("Four", line.toString());
220
221 outbuf.writeLine(line);
222
223 line.clear();
224 Assert.assertFalse(inbuf.readLine(line, true));
225
226 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
227 final WritableByteChannel outChannel = newChannel(outStream);
228 outbuf.flush(outChannel);
229
230 final String s = new String(outStream.toByteArray(), "US-ASCII");
231 Assert.assertEquals("One\r\nTwo\r\nThree\r\nFour\r\n", s);
232 }
233
234 @Test
235 public void testBasicReadWriteLine() throws Exception {
236
237 final String[] teststrs = new String[5];
238 teststrs[0] = "Hello";
239 teststrs[1] = "This string should be much longer than the size of the line buffer " +
240 "which is only 16 bytes for this test";
241 final StringBuilder buffer = new StringBuilder();
242 for (int i = 0; i < 15; i++) {
243 buffer.append("123456789 ");
244 }
245 buffer.append("and stuff like that");
246 teststrs[2] = buffer.toString();
247 teststrs[3] = "";
248 teststrs[4] = "And goodbye";
249
250 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, null, this.allocator);
251 for (final String teststr : teststrs) {
252 outbuf.writeLine(teststr);
253 }
254
255 outbuf.writeLine((String)null);
256 outbuf.writeLine((CharArrayBuffer)null);
257
258 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
259 final WritableByteChannel outChannel = newChannel(outStream);
260 outbuf.flush(outChannel);
261
262 final ReadableByteChannel channel = newChannel(outStream.toByteArray());
263
264 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, null, this.allocator);
265 inbuf.fill(channel);
266
267 for (final String teststr : teststrs) {
268 Assert.assertEquals(teststr, inbuf.readLine(true));
269 }
270 Assert.assertNull(inbuf.readLine(true));
271 Assert.assertNull(inbuf.readLine(true));
272 }
273
274 @Test
275 public void testComplexReadWriteLine() throws Exception {
276 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, null, this.allocator);
277 outbuf.write(ByteBuffer.wrap(new byte[] {'a', '\n'}));
278 outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\n'}));
279 outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\r', '\n'}));
280 outbuf.write(ByteBuffer.wrap(new byte[] {'\n'}));
281
282 final StringBuilder buffer = new StringBuilder();
283 for (int i = 0; i < 14; i++) {
284 buffer.append("a");
285 }
286 final String s1 = buffer.toString();
287 buffer.append("\r\n");
288 outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes(Consts.ASCII)));
289
290 buffer.setLength(0);
291 for (int i = 0; i < 15; i++) {
292 buffer.append("a");
293 }
294 final String s2 = buffer.toString();
295 buffer.append("\r\n");
296 outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes(Consts.ASCII)));
297
298 buffer.setLength(0);
299 for (int i = 0; i < 16; i++) {
300 buffer.append("a");
301 }
302 final String s3 = buffer.toString();
303 buffer.append("\r\n");
304 outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes(Consts.ASCII)));
305
306 outbuf.write(ByteBuffer.wrap(new byte[] {'a'}));
307
308 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
309 final WritableByteChannel outChannel = newChannel(outStream);
310 outbuf.flush(outChannel);
311
312 final ReadableByteChannel channel = newChannel(outStream.toByteArray());
313
314 final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, null, this.allocator);
315 inbuf.fill(channel);
316
317 Assert.assertEquals("a", inbuf.readLine(true));
318 Assert.assertEquals("", inbuf.readLine(true));
319 Assert.assertEquals("\r", inbuf.readLine(true));
320 Assert.assertEquals("", inbuf.readLine(true));
321 Assert.assertEquals(s1, inbuf.readLine(true));
322 Assert.assertEquals(s2, inbuf.readLine(true));
323 Assert.assertEquals(s3, inbuf.readLine(true));
324 Assert.assertEquals("a", inbuf.readLine(true));
325 Assert.assertNull(inbuf.readLine(true));
326 Assert.assertNull(inbuf.readLine(true));
327 }
328
329 @Test
330 public void testReadOneByte() throws Exception {
331
332 final byte[] out = new byte[40];
333 for (int i = 0; i < out.length; i++) {
334 out[i] = (byte)('0' + i);
335 }
336 final ReadableByteChannel channel = newChannel(out);
337 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, null, this.allocator);
338 while (inbuf.fill(channel) > 0) {
339 }
340
341 final byte[] in = new byte[40];
342 for (int i = 0; i < in.length; i++) {
343 in[i] = (byte)inbuf.read();
344 }
345 for (int i = 0; i < out.length; i++) {
346 Assert.assertEquals(out[i], in[i]);
347 }
348 }
349
350 @Test
351 public void testReadByteBuffer() throws Exception {
352 final byte[] pattern = "0123456789ABCDEF".getBytes(Consts.ASCII);
353 final ReadableByteChannel channel = newChannel(pattern);
354 final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
355 while (inbuf.fill(channel) > 0) {
356 }
357 final ByteBuffer dst = ByteBuffer.allocate(10);
358 Assert.assertEquals(10, inbuf.read(dst));
359 dst.flip();
360 Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 0, 10));
361 dst.clear();
362 Assert.assertEquals(6, inbuf.read(dst));
363 dst.flip();
364 Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 10, 6));
365 }
366
367 @Test
368 public void testReadByteBufferWithMaxLen() throws Exception {
369 final byte[] pattern = "0123456789ABCDEF".getBytes(Consts.ASCII);
370 final ReadableByteChannel channel = newChannel(pattern);
371 final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
372 while (inbuf.fill(channel) > 0) {
373 }
374 final ByteBuffer dst = ByteBuffer.allocate(16);
375 Assert.assertEquals(10, inbuf.read(dst, 10));
376 dst.flip();
377 Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 0, 10));
378 dst.clear();
379 Assert.assertEquals(3, inbuf.read(dst, 3));
380 dst.flip();
381 Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 10, 3));
382 Assert.assertEquals(3, inbuf.read(dst, 20));
383 dst.flip();
384 Assert.assertEquals(dst, ByteBuffer.wrap(pattern, 13, 3));
385 }
386
387 @Test
388 public void testReadToChannel() throws Exception {
389 final byte[] pattern = "0123456789ABCDEF".getBytes(Consts.ASCII);
390 final ReadableByteChannel channel = newChannel(pattern);
391 final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
392 while (inbuf.fill(channel) > 0) {
393 }
394
395 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
396 final WritableByteChannel dst = newChannel(outStream);
397
398 Assert.assertEquals(16, inbuf.read(dst));
399 Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray()));
400 }
401
402 @Test
403 public void testReadToChannelWithMaxLen() throws Exception {
404 final byte[] pattern = "0123456789ABCDEF".getBytes(Consts.ASCII);
405 final ReadableByteChannel channel = newChannel(pattern);
406 final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, null, this.allocator);
407 while (inbuf.fill(channel) > 0) {
408 }
409
410 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
411 final WritableByteChannel dst = newChannel(outStream);
412
413 Assert.assertEquals(10, inbuf.read(dst, 10));
414 Assert.assertEquals(3, inbuf.read(dst, 3));
415 Assert.assertEquals(3, inbuf.read(dst, 10));
416 Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray()));
417 }
418
419 @Test
420 public void testWriteByteBuffer() throws Exception {
421 final byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes(Consts.ASCII);
422
423 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024, null, this.allocator);
424 final ReadableByteChannel src = newChannel(pattern);
425 outbuf.write(src);
426
427 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
428 final WritableByteChannel channel = newChannel(outStream);
429 while (outbuf.flush(channel) > 0) {
430 }
431 Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray()));
432 }
433
434 @Test
435 public void testWriteFromChannel() throws Exception {
436 final byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes(Consts.ASCII);
437
438 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024, null, this.allocator);
439 outbuf.write(ByteBuffer.wrap(pattern, 0, 16));
440 outbuf.write(ByteBuffer.wrap(pattern, 16, 10));
441 outbuf.write(ByteBuffer.wrap(pattern, 26, 6));
442
443 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
444 final WritableByteChannel channel = newChannel(outStream);
445 while (outbuf.flush(channel) > 0) {
446 }
447 Assert.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray()));
448 }
449
450 static final int SWISS_GERMAN_HELLO [] = {
451 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
452 };
453
454 static final int RUSSIAN_HELLO [] = {
455 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
456 0x432, 0x435, 0x442
457 };
458
459 private static String constructString(final int [] unicodeChars) {
460 final StringBuilder buffer = new StringBuilder();
461 if (unicodeChars != null) {
462 for (final int unicodeChar : unicodeChars) {
463 buffer.append((char)unicodeChar);
464 }
465 }
466 return buffer.toString();
467 }
468
469 @Test
470 public void testMultibyteCodedReadWriteLine() throws Exception {
471 final String s1 = constructString(SWISS_GERMAN_HELLO);
472 final String s2 = constructString(RUSSIAN_HELLO);
473 final String s3 = "Like hello and stuff";
474
475 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16,
476 Consts.UTF_8.newEncoder(), this.allocator);
477
478 for (int i = 0; i < 10; i++) {
479 outbuf.writeLine(s1);
480 outbuf.writeLine(s2);
481 outbuf.writeLine(s3);
482 }
483
484 final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
485 final WritableByteChannel outChannel = newChannel(outStream);
486 outbuf.flush(outChannel);
487
488 final byte[] tmp = outStream.toByteArray();
489
490 final ReadableByteChannel channel = newChannel(tmp);
491 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16,
492 Consts.UTF_8.newDecoder(), this.allocator);
493
494 while (inbuf.fill(channel) > 0) {
495 }
496
497 for (int i = 0; i < 10; i++) {
498 Assert.assertEquals(s1, inbuf.readLine(true));
499 Assert.assertEquals(s2, inbuf.readLine(true));
500 Assert.assertEquals(s3, inbuf.readLine(true));
501 }
502 }
503
504 @Test
505 public void testInputMatchesBufferLength() throws Exception {
506 final String s1 = "abcde";
507 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 5, null, this.allocator);
508 outbuf.writeLine(s1);
509 }
510
511 @Test(expected=CharacterCodingException.class)
512 public void testMalformedInputActionReport() throws Exception {
513 final String s = constructString(SWISS_GERMAN_HELLO);
514 final byte[] tmp = s.getBytes(Consts.ISO_8859_1);
515
516 final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
517 decoder.onMalformedInput(CodingErrorAction.REPORT);
518 decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
519 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, decoder, this.allocator);
520 final ReadableByteChannel channel = newChannel(tmp);
521 while (inbuf.fill(channel) > 0) {
522 }
523 inbuf.readLine(true);
524 }
525
526 @Test
527 public void testMalformedInputActionIgnore() throws Exception {
528 final String s = constructString(SWISS_GERMAN_HELLO);
529 final byte[] tmp = s.getBytes(Consts.ISO_8859_1);
530
531 final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
532 decoder.onMalformedInput(CodingErrorAction.IGNORE);
533 decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
534 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, decoder, this.allocator);
535 final ReadableByteChannel channel = newChannel(tmp);
536 while (inbuf.fill(channel) > 0) {
537 }
538 final String result = inbuf.readLine(true);
539 Assert.assertEquals("Grezi_zm", result);
540 }
541
542 @Test
543 public void testMalformedInputActionReplace() throws Exception {
544 final String s = constructString(SWISS_GERMAN_HELLO);
545 final byte[] tmp = s.getBytes(Consts.ISO_8859_1);
546
547 final CharsetDecoder decoder = Consts.UTF_8.newDecoder();
548 decoder.onMalformedInput(CodingErrorAction.REPLACE);
549 decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
550 final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, decoder, this.allocator);
551 final ReadableByteChannel channel = newChannel(tmp);
552 while (inbuf.fill(channel) > 0) {
553 }
554 final String result = inbuf.readLine(true);
555 Assert.assertEquals("Gr\ufffdezi_z\ufffdm\ufffd", result);
556 }
557
558 @Test(expected=CharacterCodingException.class)
559 public void testUnmappableInputActionReport() throws Exception {
560 final String s = "This text contains a circumflex \u0302!!!";
561 final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
562 encoder.onMalformedInput(CodingErrorAction.IGNORE);
563 encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
564 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder, this.allocator);
565 outbuf.writeLine(s);
566 }
567
568 @Test
569 public void testUnmappableInputActionIgnore() throws Exception {
570 final String s = "This text contains a circumflex \u0302!!!";
571 final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
572 encoder.onMalformedInput(CodingErrorAction.IGNORE);
573 encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
574 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder, this.allocator);
575 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
576 final WritableByteChannel channel = newChannel(baos);
577 outbuf.writeLine(s);
578 outbuf.flush(channel);
579
580 final String result = new String(baos.toByteArray(), "US-ASCII");
581 Assert.assertEquals("This text contains a circumflex !!!\r\n", result);
582 }
583
584 @Test
585 public void testUnmappableInputActionReplace() throws Exception {
586 final String s = "This text contains a circumflex \u0302 !!!";
587 final CharsetEncoder encoder = Consts.ISO_8859_1.newEncoder();
588 encoder.onMalformedInput(CodingErrorAction.IGNORE);
589 encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
590 final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder, this.allocator);
591 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
592 final WritableByteChannel channel = newChannel(baos);
593 outbuf.writeLine(s);
594 outbuf.flush(channel);
595
596 final String result = new String(baos.toByteArray(), "US-ASCII");
597 Assert.assertEquals("This text contains a circumflex ? !!!\r\n", result);
598 }
599
600 }