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