1 /*
2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.incubator.http.internal.hpack;
24
25 import org.testng.annotations.Test;
26
27 import java.nio.Buffer;
28 import java.nio.ByteBuffer;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Iterator;
32 import java.util.LinkedList;
33 import java.util.List;
34 import java.util.function.Consumer;
35 import java.util.function.Function;
36
37 import static jdk.incubator.http.internal.hpack.BuffersTestingKit.concat;
38 import static jdk.incubator.http.internal.hpack.BuffersTestingKit.forEachSplit;
39 import static jdk.incubator.http.internal.hpack.SpecHelper.toHexdump;
40 import static jdk.incubator.http.internal.hpack.TestHelper.assertVoidThrows;
41 import static java.util.Arrays.asList;
42 import static org.testng.Assert.assertEquals;
43 import static org.testng.Assert.assertTrue;
44
45 // TODO: map textual representation of commands from the spec to actual
46 // calls to encoder (actually, this is a good idea for decoder as well)
503 e.encode(output);
504
505 output.flip();
506
507 test(e, output,
508
509 "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
510 "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
511 "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
512 "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
513 "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
514
515 "[ 1] (s = 98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
516 "[ 2] (s = 52) content-encoding: gzip\n" +
517 "[ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
518 " Table size: 215");
519 // @formatter:on
520 }
521
522 @Test
523 public void initialSizeUpdateDefaultEncoder() {
524 Function<Integer, Encoder> e = Encoder::new;
525 testSizeUpdate(e, 1024, asList(), asList(0));
526 testSizeUpdate(e, 1024, asList(1024), asList(0));
527 testSizeUpdate(e, 1024, asList(1024, 1024), asList(0));
528 testSizeUpdate(e, 1024, asList(1024, 512), asList(0));
529 testSizeUpdate(e, 1024, asList(512, 1024), asList(0));
530 testSizeUpdate(e, 1024, asList(512, 2048), asList(0));
531 }
532
533 @Test
534 public void initialSizeUpdateCustomEncoder() {
535 Function<Integer, Encoder> e = EncoderTest::newCustomEncoder;
536 testSizeUpdate(e, 1024, asList(), asList(1024));
537 testSizeUpdate(e, 1024, asList(1024), asList(1024));
538 testSizeUpdate(e, 1024, asList(1024, 1024), asList(1024));
539 testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
540 testSizeUpdate(e, 1024, asList(512, 1024), asList(1024));
541 testSizeUpdate(e, 1024, asList(512, 2048), asList(2048));
542 }
543
544 @Test
545 public void seriesOfSizeUpdatesDefaultEncoder() {
546 Function<Integer, Encoder> e = c -> {
547 Encoder encoder = new Encoder(c);
548 drainInitialUpdate(encoder);
549 return encoder;
550 };
551 testSizeUpdate(e, 0, asList(0), asList());
552 testSizeUpdate(e, 1024, asList(1024), asList());
553 testSizeUpdate(e, 1024, asList(2048), asList());
554 testSizeUpdate(e, 1024, asList(512), asList());
555 testSizeUpdate(e, 1024, asList(1024, 1024), asList());
556 testSizeUpdate(e, 1024, asList(1024, 2048), asList());
557 testSizeUpdate(e, 1024, asList(2048, 1024), asList());
558 testSizeUpdate(e, 1024, asList(1024, 512), asList());
559 testSizeUpdate(e, 1024, asList(512, 1024), asList());
560 }
561
562 //
563 // https://tools.ietf.org/html/rfc7541#section-4.2
564 //
565 @Test
566 public void seriesOfSizeUpdatesCustomEncoder() {
567 Function<Integer, Encoder> e = c -> {
568 Encoder encoder = newCustomEncoder(c);
569 drainInitialUpdate(encoder);
570 return encoder;
571 };
572 testSizeUpdate(e, 0, asList(0), asList());
573 testSizeUpdate(e, 1024, asList(1024), asList());
574 testSizeUpdate(e, 1024, asList(2048), asList(2048));
575 testSizeUpdate(e, 1024, asList(512), asList(512));
576 testSizeUpdate(e, 1024, asList(1024, 1024), asList());
577 testSizeUpdate(e, 1024, asList(1024, 2048), asList(2048));
578 testSizeUpdate(e, 1024, asList(2048, 1024), asList());
579 testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
580 testSizeUpdate(e, 1024, asList(512, 1024), asList(512, 1024));
581 }
582
583 @Test
584 public void callSequenceViolations() {
585 { // Hasn't set up a header
586 Encoder e = new Encoder(0);
621 }
622
623 private static void test(Encoder encoder,
624 ByteBuffer output,
625 String expectedHexdump,
626 String expectedTableState) {
627
628 String actualTableState = encoder.getHeaderTable().getStateString();
629 assertEquals(actualTableState, expectedTableState);
630
631 String actualHexdump = toHexdump(output);
632 assertEquals(actualHexdump, expectedHexdump.replaceAll("\\n", " "));
633 }
634
635 // initial size - the size encoder is constructed with
636 // updates - a sequence of values for consecutive calls to encoder.setMaxCapacity
637 // expected - a sequence of values expected to be decoded by a decoder
638 private void testSizeUpdate(Function<Integer, Encoder> encoder,
639 int initialSize,
640 List<Integer> updates,
641 List<Integer> expected) {
642 Encoder e = encoder.apply(initialSize);
643 updates.forEach(e::setMaxCapacity);
644 ByteBuffer b = ByteBuffer.allocate(64);
645 e.header("a", "b");
646 e.encode(b);
647 b.flip();
648 Decoder d = new Decoder(updates.isEmpty() ? initialSize : Collections.max(updates));
649 List<Integer> actual = new ArrayList<>();
650 d.decode(b, true, new DecodingCallback() {
651 @Override
652 public void onDecoded(CharSequence name, CharSequence value) { }
653
654 @Override
655 public void onSizeUpdate(int capacity) {
656 actual.add(capacity);
657 }
658 });
659 assertEquals(actual, expected);
660 }
661
|
1 /*
2 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.incubator.http.internal.hpack;
24
25 import org.testng.annotations.Test;
26
27 import java.io.IOException;
28 import java.nio.Buffer;
29 import java.nio.ByteBuffer;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.Iterator;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.function.Consumer;
36 import java.util.function.Function;
37
38 import static jdk.incubator.http.internal.hpack.BuffersTestingKit.concat;
39 import static jdk.incubator.http.internal.hpack.BuffersTestingKit.forEachSplit;
40 import static jdk.incubator.http.internal.hpack.SpecHelper.toHexdump;
41 import static jdk.incubator.http.internal.hpack.TestHelper.assertVoidThrows;
42 import static java.util.Arrays.asList;
43 import static org.testng.Assert.assertEquals;
44 import static org.testng.Assert.assertTrue;
45
46 // TODO: map textual representation of commands from the spec to actual
47 // calls to encoder (actually, this is a good idea for decoder as well)
504 e.encode(output);
505
506 output.flip();
507
508 test(e, output,
509
510 "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
511 "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
512 "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
513 "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
514 "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
515
516 "[ 1] (s = 98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
517 "[ 2] (s = 52) content-encoding: gzip\n" +
518 "[ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
519 " Table size: 215");
520 // @formatter:on
521 }
522
523 @Test
524 public void initialSizeUpdateDefaultEncoder() throws IOException {
525 Function<Integer, Encoder> e = Encoder::new;
526 testSizeUpdate(e, 1024, asList(), asList(0));
527 testSizeUpdate(e, 1024, asList(1024), asList(0));
528 testSizeUpdate(e, 1024, asList(1024, 1024), asList(0));
529 testSizeUpdate(e, 1024, asList(1024, 512), asList(0));
530 testSizeUpdate(e, 1024, asList(512, 1024), asList(0));
531 testSizeUpdate(e, 1024, asList(512, 2048), asList(0));
532 }
533
534 @Test
535 public void initialSizeUpdateCustomEncoder() throws IOException {
536 Function<Integer, Encoder> e = EncoderTest::newCustomEncoder;
537 testSizeUpdate(e, 1024, asList(), asList(1024));
538 testSizeUpdate(e, 1024, asList(1024), asList(1024));
539 testSizeUpdate(e, 1024, asList(1024, 1024), asList(1024));
540 testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
541 testSizeUpdate(e, 1024, asList(512, 1024), asList(1024));
542 testSizeUpdate(e, 1024, asList(512, 2048), asList(2048));
543 }
544
545 @Test
546 public void seriesOfSizeUpdatesDefaultEncoder() throws IOException {
547 Function<Integer, Encoder> e = c -> {
548 Encoder encoder = new Encoder(c);
549 drainInitialUpdate(encoder);
550 return encoder;
551 };
552 testSizeUpdate(e, 0, asList(0), asList());
553 testSizeUpdate(e, 1024, asList(1024), asList());
554 testSizeUpdate(e, 1024, asList(2048), asList());
555 testSizeUpdate(e, 1024, asList(512), asList());
556 testSizeUpdate(e, 1024, asList(1024, 1024), asList());
557 testSizeUpdate(e, 1024, asList(1024, 2048), asList());
558 testSizeUpdate(e, 1024, asList(2048, 1024), asList());
559 testSizeUpdate(e, 1024, asList(1024, 512), asList());
560 testSizeUpdate(e, 1024, asList(512, 1024), asList());
561 }
562
563 //
564 // https://tools.ietf.org/html/rfc7541#section-4.2
565 //
566 @Test
567 public void seriesOfSizeUpdatesCustomEncoder() throws IOException {
568 Function<Integer, Encoder> e = c -> {
569 Encoder encoder = newCustomEncoder(c);
570 drainInitialUpdate(encoder);
571 return encoder;
572 };
573 testSizeUpdate(e, 0, asList(0), asList());
574 testSizeUpdate(e, 1024, asList(1024), asList());
575 testSizeUpdate(e, 1024, asList(2048), asList(2048));
576 testSizeUpdate(e, 1024, asList(512), asList(512));
577 testSizeUpdate(e, 1024, asList(1024, 1024), asList());
578 testSizeUpdate(e, 1024, asList(1024, 2048), asList(2048));
579 testSizeUpdate(e, 1024, asList(2048, 1024), asList());
580 testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
581 testSizeUpdate(e, 1024, asList(512, 1024), asList(512, 1024));
582 }
583
584 @Test
585 public void callSequenceViolations() {
586 { // Hasn't set up a header
587 Encoder e = new Encoder(0);
622 }
623
624 private static void test(Encoder encoder,
625 ByteBuffer output,
626 String expectedHexdump,
627 String expectedTableState) {
628
629 String actualTableState = encoder.getHeaderTable().getStateString();
630 assertEquals(actualTableState, expectedTableState);
631
632 String actualHexdump = toHexdump(output);
633 assertEquals(actualHexdump, expectedHexdump.replaceAll("\\n", " "));
634 }
635
636 // initial size - the size encoder is constructed with
637 // updates - a sequence of values for consecutive calls to encoder.setMaxCapacity
638 // expected - a sequence of values expected to be decoded by a decoder
639 private void testSizeUpdate(Function<Integer, Encoder> encoder,
640 int initialSize,
641 List<Integer> updates,
642 List<Integer> expected) throws IOException {
643 Encoder e = encoder.apply(initialSize);
644 updates.forEach(e::setMaxCapacity);
645 ByteBuffer b = ByteBuffer.allocate(64);
646 e.header("a", "b");
647 e.encode(b);
648 b.flip();
649 Decoder d = new Decoder(updates.isEmpty() ? initialSize : Collections.max(updates));
650 List<Integer> actual = new ArrayList<>();
651 d.decode(b, true, new DecodingCallback() {
652 @Override
653 public void onDecoded(CharSequence name, CharSequence value) { }
654
655 @Override
656 public void onSizeUpdate(int capacity) {
657 actual.add(capacity);
658 }
659 });
660 assertEquals(actual, expected);
661 }
662
|