author | chegar |
Wed, 20 Jun 2018 09:05:57 -0700 | |
changeset 50681 | 4254bed3c09d |
parent 49765 | ee6f7a61f3a5 |
child 56795 | 03ece2518428 |
permissions | -rw-r--r-- |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
1 |
/* |
49765 | 2 |
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
4 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. Oracle designates this |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
10 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
15 |
* accompanied this code). |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
16 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
20 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
22 |
* or visit www.oracle.com if you need additional information or have any |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
23 |
* questions. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
24 |
*/ |
49765 | 25 |
package jdk.internal.net.http.hpack; |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
26 |
|
49765 | 27 |
import jdk.internal.net.http.hpack.HPACK.Logger; |
48083 | 28 |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
29 |
import java.nio.ByteBuffer; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
30 |
import java.nio.ReadOnlyBufferException; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
31 |
import java.util.LinkedList; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
32 |
import java.util.List; |
48083 | 33 |
import java.util.concurrent.atomic.AtomicLong; |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
34 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
35 |
import static java.lang.String.format; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
36 |
import static java.util.Objects.requireNonNull; |
49765 | 37 |
import static jdk.internal.net.http.hpack.HPACK.Logger.Level.EXTRA; |
38 |
import static jdk.internal.net.http.hpack.HPACK.Logger.Level.NORMAL; |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
39 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
40 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
41 |
* Encodes headers to their binary representation. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
42 |
* |
48083 | 43 |
* <p> Typical lifecycle looks like this: |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
44 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
45 |
* <p> {@link #Encoder(int) new Encoder} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
46 |
* ({@link #setMaxCapacity(int) setMaxCapacity}? |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
47 |
* {@link #encode(ByteBuffer) encode})* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
48 |
* |
48083 | 49 |
* <p> Suppose headers are represented by {@code Map<String, List<String>>}. |
50 |
* A supplier and a consumer of {@link ByteBuffer}s in forms of |
|
51 |
* {@code Supplier<ByteBuffer>} and {@code Consumer<ByteBuffer>} respectively. |
|
52 |
* Then to encode headers, the following approach might be used: |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
53 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
54 |
* <pre>{@code |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
55 |
* for (Map.Entry<String, List<String>> h : headers.entrySet()) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
56 |
* String name = h.getKey(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
57 |
* for (String value : h.getValue()) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
58 |
* encoder.header(name, value); // Set up header |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
59 |
* boolean encoded; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
60 |
* do { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
61 |
* ByteBuffer b = buffersSupplier.get(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
62 |
* encoded = encoder.encode(b); // Encode the header |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
63 |
* buffersConsumer.accept(b); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
64 |
* } while (!encoded); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
65 |
* } |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
66 |
* } |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
67 |
* }</pre> |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
68 |
* |
48083 | 69 |
* <p> Though the specification <a href="https://tools.ietf.org/html/rfc7541#section-2">does not define</a> |
70 |
* how an encoder is to be implemented, a default implementation is provided by |
|
71 |
* the method {@link #header(CharSequence, CharSequence, boolean)}. |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
72 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
73 |
* <p> To provide a custom encoding implementation, {@code Encoder} has to be |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
74 |
* extended. A subclass then can access methods for encoding using specific |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
75 |
* representations (e.g. {@link #literal(int, CharSequence, boolean) literal}, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
76 |
* {@link #indexed(int) indexed}, etc.) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
77 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
78 |
* @apiNote |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
79 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
80 |
* <p> An Encoder provides an incremental way of encoding headers. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
81 |
* {@link #encode(ByteBuffer)} takes a buffer a returns a boolean indicating |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
82 |
* whether, or not, the buffer was sufficiently sized to hold the |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
83 |
* remaining of the encoded representation. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
84 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
85 |
* <p> This way, there's no need to provide a buffer of a specific size, or to |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
86 |
* resize (and copy) the buffer on demand, when the remaining encoded |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
87 |
* representation will not fit in the buffer's remaining space. Instead, an |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
88 |
* array of existing buffers can be used, prepended with a frame that encloses |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
89 |
* the resulting header block afterwards. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
90 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
91 |
* <p> Splitting the encoding operation into header set up and header encoding, |
48083 | 92 |
* separates long lived arguments ({@code name}, {@code value}, |
93 |
* {@code sensitivity}, etc.) from the short lived ones (e.g. {@code buffer}), |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
94 |
* simplifying each operation itself. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
95 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
96 |
* @implNote |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
97 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
98 |
* <p> The default implementation does not use dynamic table. It reports to a |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
99 |
* coupled Decoder a size update with the value of {@code 0}, and never changes |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
100 |
* it afterwards. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
101 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
102 |
* @since 9 |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
103 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
104 |
public class Encoder { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
105 |
|
48083 | 106 |
private static final AtomicLong ENCODERS_IDS = new AtomicLong(); |
107 |
||
50681 | 108 |
/* Used to calculate the number of bytes required for Huffman encoding */ |
109 |
private final QuickHuffman.Writer huffmanWriter = new QuickHuffman.Writer(); |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
110 |
|
48083 | 111 |
private final Logger logger; |
112 |
private final long id; |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
113 |
private final IndexedWriter indexedWriter = new IndexedWriter(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
114 |
private final LiteralWriter literalWriter = new LiteralWriter(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
115 |
private final LiteralNeverIndexedWriter literalNeverIndexedWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
116 |
= new LiteralNeverIndexedWriter(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
117 |
private final LiteralWithIndexingWriter literalWithIndexingWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
118 |
= new LiteralWithIndexingWriter(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
119 |
private final SizeUpdateWriter sizeUpdateWriter = new SizeUpdateWriter(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
120 |
private final BulkSizeUpdateWriter bulkSizeUpdateWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
121 |
= new BulkSizeUpdateWriter(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
122 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
123 |
private BinaryRepresentationWriter writer; |
49765 | 124 |
// The default implementation of Encoder does not use dynamic region of the |
125 |
// HeaderTable. Thus the performance profile should be similar to that of |
|
126 |
// SimpleHeaderTable. |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
127 |
private final HeaderTable headerTable; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
128 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
129 |
private boolean encoding; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
130 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
131 |
private int maxCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
132 |
private int currCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
133 |
private int lastCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
134 |
private long minCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
135 |
private boolean capacityUpdate; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
136 |
private boolean configuredCapacityUpdate; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
137 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
138 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
139 |
* Constructs an {@code Encoder} with the specified maximum capacity of the |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
140 |
* header table. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
141 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
142 |
* <p> The value has to be agreed between decoder and encoder out-of-band, |
48083 | 143 |
* e.g. by a protocol that uses HPACK |
144 |
* (see <a href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table Size</a>). |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
145 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
146 |
* @param maxCapacity |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
147 |
* a non-negative integer |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
148 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
149 |
* @throws IllegalArgumentException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
150 |
* if maxCapacity is negative |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
151 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
152 |
public Encoder(int maxCapacity) { |
48083 | 153 |
id = ENCODERS_IDS.incrementAndGet(); |
154 |
this.logger = HPACK.getLogger().subLogger("Encoder#" + id); |
|
155 |
if (logger.isLoggable(NORMAL)) { |
|
156 |
logger.log(NORMAL, () -> format("new encoder with maximum table size %s", |
|
157 |
maxCapacity)); |
|
158 |
} |
|
159 |
if (logger.isLoggable(EXTRA)) { |
|
160 |
/* To correlate with logging outside HPACK, knowing |
|
161 |
hashCode/toString is important */ |
|
162 |
logger.log(EXTRA, () -> { |
|
163 |
String hashCode = Integer.toHexString( |
|
164 |
System.identityHashCode(this)); |
|
165 |
/* Since Encoder can be subclassed hashCode AND identity |
|
166 |
hashCode might be different. So let's print both. */ |
|
167 |
return format("toString='%s', hashCode=%s, identityHashCode=%s", |
|
168 |
toString(), hashCode(), hashCode); |
|
169 |
}); |
|
170 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
171 |
if (maxCapacity < 0) { |
48083 | 172 |
throw new IllegalArgumentException( |
173 |
"maxCapacity >= 0: " + maxCapacity); |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
174 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
175 |
// Initial maximum capacity update mechanics |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
176 |
minCapacity = Long.MAX_VALUE; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
177 |
currCapacity = -1; |
48083 | 178 |
setMaxCapacity0(maxCapacity); |
179 |
headerTable = new HeaderTable(lastCapacity, logger.subLogger("HeaderTable")); |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
180 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
181 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
182 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
183 |
* Sets up the given header {@code (name, value)}. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
184 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
185 |
* <p> Fixates {@code name} and {@code value} for the duration of encoding. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
186 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
187 |
* @param name |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
188 |
* the name |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
189 |
* @param value |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
190 |
* the value |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
191 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
192 |
* @throws NullPointerException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
193 |
* if any of the arguments are {@code null} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
194 |
* @throws IllegalStateException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
195 |
* if the encoder hasn't fully encoded the previous header, or |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
196 |
* hasn't yet started to encode it |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
197 |
* @see #header(CharSequence, CharSequence, boolean) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
198 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
199 |
public void header(CharSequence name, CharSequence value) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
200 |
throws IllegalStateException { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
201 |
header(name, value, false); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
202 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
203 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
204 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
205 |
* Sets up the given header {@code (name, value)} with possibly sensitive |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
206 |
* value. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
207 |
* |
48083 | 208 |
* <p> If the {@code value} is sensitive (think security, secrecy, etc.) |
209 |
* this encoder will compress it using a special representation |
|
210 |
* (see <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">6.2.3. Literal Header Field Never Indexed</a>). |
|
211 |
* |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
212 |
* <p> Fixates {@code name} and {@code value} for the duration of encoding. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
213 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
214 |
* @param name |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
215 |
* the name |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
216 |
* @param value |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
217 |
* the value |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
218 |
* @param sensitive |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
219 |
* whether or not the value is sensitive |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
220 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
221 |
* @throws NullPointerException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
222 |
* if any of the arguments are {@code null} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
223 |
* @throws IllegalStateException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
224 |
* if the encoder hasn't fully encoded the previous header, or |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
225 |
* hasn't yet started to encode it |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
226 |
* @see #header(CharSequence, CharSequence) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
227 |
* @see DecodingCallback#onDecoded(CharSequence, CharSequence, boolean) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
228 |
*/ |
48083 | 229 |
public void header(CharSequence name, |
230 |
CharSequence value, |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
231 |
boolean sensitive) throws IllegalStateException { |
48083 | 232 |
if (logger.isLoggable(NORMAL)) { |
233 |
logger.log(NORMAL, () -> format("encoding ('%s', '%s'), sensitive: %s", |
|
234 |
name, value, sensitive)); |
|
235 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
236 |
// Arguably a good balance between complexity of implementation and |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
237 |
// efficiency of encoding |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
238 |
requireNonNull(name, "name"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
239 |
requireNonNull(value, "value"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
240 |
HeaderTable t = getHeaderTable(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
241 |
int index = t.indexOf(name, value); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
242 |
if (index > 0) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
243 |
indexed(index); |
50681 | 244 |
} else { |
245 |
boolean huffmanValue = isHuffmanBetterFor(value); |
|
246 |
if (index < 0) { |
|
247 |
if (sensitive) { |
|
248 |
literalNeverIndexed(-index, value, huffmanValue); |
|
249 |
} else { |
|
250 |
literal(-index, value, huffmanValue); |
|
251 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
252 |
} else { |
50681 | 253 |
boolean huffmanName = isHuffmanBetterFor(name); |
254 |
if (sensitive) { |
|
255 |
literalNeverIndexed(name, huffmanName, value, huffmanValue); |
|
256 |
} else { |
|
257 |
literal(name, huffmanName, value, huffmanValue); |
|
258 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
259 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
260 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
261 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
262 |
|
50681 | 263 |
private boolean isHuffmanBetterFor(CharSequence value) { |
264 |
// prefer Huffman encoding only if it is strictly smaller than Latin-1 |
|
265 |
return huffmanWriter.lengthOf(value) < value.length(); |
|
266 |
} |
|
267 |
||
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
268 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
269 |
* Sets a maximum capacity of the header table. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
270 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
271 |
* <p> The value has to be agreed between decoder and encoder out-of-band, |
48083 | 272 |
* e.g. by a protocol that uses HPACK |
273 |
* (see <a href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table Size</a>). |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
274 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
275 |
* <p> May be called any number of times after or before a complete header |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
276 |
* has been encoded. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
277 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
278 |
* <p> If the encoder decides to change the actual capacity, an update will |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
279 |
* be encoded before a new encoding operation starts. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
280 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
281 |
* @param capacity |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
282 |
* a non-negative integer |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
283 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
284 |
* @throws IllegalArgumentException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
285 |
* if capacity is negative |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
286 |
* @throws IllegalStateException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
287 |
* if the encoder hasn't fully encoded the previous header, or |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
288 |
* hasn't yet started to encode it |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
289 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
290 |
public void setMaxCapacity(int capacity) { |
48083 | 291 |
if (logger.isLoggable(NORMAL)) { |
292 |
logger.log(NORMAL, () -> format("setting maximum table size to %s", |
|
293 |
capacity)); |
|
294 |
} |
|
295 |
setMaxCapacity0(capacity); |
|
296 |
} |
|
297 |
||
298 |
private void setMaxCapacity0(int capacity) { |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
299 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
300 |
if (capacity < 0) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
301 |
throw new IllegalArgumentException("capacity >= 0: " + capacity); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
302 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
303 |
int calculated = calculateCapacity(capacity); |
48083 | 304 |
if (logger.isLoggable(NORMAL)) { |
305 |
logger.log(NORMAL, () -> format("actual maximum table size will be %s", |
|
306 |
calculated)); |
|
307 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
308 |
if (calculated < 0 || calculated > capacity) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
309 |
throw new IllegalArgumentException( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
310 |
format("0 <= calculated <= capacity: calculated=%s, capacity=%s", |
50681 | 311 |
calculated, capacity)); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
312 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
313 |
capacityUpdate = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
314 |
// maxCapacity needs to be updated unconditionally, so the encoder |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
315 |
// always has the newest one (in case it decides to update it later |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
316 |
// unsolicitedly) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
317 |
// Suppose maxCapacity = 4096, and the encoder has decided to use only |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
318 |
// 2048. It later can choose anything else from the region [0, 4096]. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
319 |
maxCapacity = capacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
320 |
lastCapacity = calculated; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
321 |
minCapacity = Math.min(minCapacity, lastCapacity); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
322 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
323 |
|
48083 | 324 |
/** |
325 |
* Calculates actual capacity to be used by this encoder in response to |
|
326 |
* a request to update maximum table size. |
|
327 |
* |
|
328 |
* <p> Default implementation does not add anything to the headers table, |
|
329 |
* hence this method returns {@code 0}. |
|
330 |
* |
|
331 |
* <p> It is an error to return a value {@code c}, where {@code c < 0} or |
|
332 |
* {@code c > maxCapacity}. |
|
333 |
* |
|
334 |
* @param maxCapacity |
|
335 |
* upper bound |
|
336 |
* |
|
337 |
* @return actual capacity |
|
338 |
*/ |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
339 |
protected int calculateCapacity(int maxCapacity) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
340 |
return 0; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
341 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
342 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
343 |
/** |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
344 |
* Encodes the {@linkplain #header(CharSequence, CharSequence) set up} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
345 |
* header into the given buffer. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
346 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
347 |
* <p> The encoder writes as much as possible of the header's binary |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
348 |
* representation into the given buffer, starting at the buffer's position, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
349 |
* and increments its position to reflect the bytes written. The buffer's |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
350 |
* mark and limit will not be modified. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
351 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
352 |
* <p> Once the method has returned {@code true}, the current header is |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
353 |
* deemed encoded. A new header may be set up. |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
354 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
355 |
* @param headerBlock |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
356 |
* the buffer to encode the header into, may be empty |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
357 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
358 |
* @return {@code true} if the current header has been fully encoded, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
359 |
* {@code false} otherwise |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
360 |
* |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
361 |
* @throws NullPointerException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
362 |
* if the buffer is {@code null} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
363 |
* @throws ReadOnlyBufferException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
364 |
* if this buffer is read-only |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
365 |
* @throws IllegalStateException |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
366 |
* if there is no set up header |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
367 |
*/ |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
368 |
public final boolean encode(ByteBuffer headerBlock) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
369 |
if (!encoding) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
370 |
throw new IllegalStateException("A header hasn't been set up"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
371 |
} |
48083 | 372 |
if (logger.isLoggable(EXTRA)) { |
373 |
logger.log(EXTRA, () -> format("writing to %s", headerBlock)); |
|
374 |
} |
|
375 |
if (!prependWithCapacityUpdate(headerBlock)) { // TODO: log |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
376 |
return false; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
377 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
378 |
boolean done = writer.write(headerTable, headerBlock); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
379 |
if (done) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
380 |
writer.reset(); // FIXME: WHY? |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
381 |
encoding = false; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
382 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
383 |
return done; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
384 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
385 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
386 |
private boolean prependWithCapacityUpdate(ByteBuffer headerBlock) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
387 |
if (capacityUpdate) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
388 |
if (!configuredCapacityUpdate) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
389 |
List<Integer> sizes = new LinkedList<>(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
390 |
if (minCapacity < currCapacity) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
391 |
sizes.add((int) minCapacity); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
392 |
if (minCapacity != lastCapacity) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
393 |
sizes.add(lastCapacity); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
394 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
395 |
} else if (lastCapacity != currCapacity) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
396 |
sizes.add(lastCapacity); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
397 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
398 |
bulkSizeUpdateWriter.maxHeaderTableSizes(sizes); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
399 |
configuredCapacityUpdate = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
400 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
401 |
boolean done = bulkSizeUpdateWriter.write(headerTable, headerBlock); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
402 |
if (done) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
403 |
minCapacity = lastCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
404 |
currCapacity = lastCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
405 |
bulkSizeUpdateWriter.reset(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
406 |
capacityUpdate = false; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
407 |
configuredCapacityUpdate = false; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
408 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
409 |
return done; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
410 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
411 |
return true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
412 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
413 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
414 |
protected final void indexed(int index) throws IndexOutOfBoundsException { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
415 |
checkEncoding(); |
48083 | 416 |
if (logger.isLoggable(EXTRA)) { |
417 |
logger.log(EXTRA, () -> format("indexed %s", index)); |
|
418 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
419 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
420 |
writer = indexedWriter.index(index); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
421 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
422 |
|
48083 | 423 |
protected final void literal(int index, |
424 |
CharSequence value, |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
425 |
boolean useHuffman) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
426 |
throws IndexOutOfBoundsException { |
48083 | 427 |
if (logger.isLoggable(EXTRA)) { |
50681 | 428 |
logger.log(EXTRA, () -> format( |
429 |
"literal without indexing (%s, '%s', huffman=%b)", |
|
430 |
index, value, useHuffman)); |
|
48083 | 431 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
432 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
433 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
434 |
writer = literalWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
435 |
.index(index).value(value, useHuffman); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
436 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
437 |
|
48083 | 438 |
protected final void literal(CharSequence name, |
439 |
boolean nameHuffman, |
|
440 |
CharSequence value, |
|
50681 | 441 |
boolean valueHuffman) |
442 |
{ |
|
48083 | 443 |
if (logger.isLoggable(EXTRA)) { |
50681 | 444 |
logger.log(EXTRA, () -> format( |
445 |
"literal without indexing ('%s', huffman=%b, '%s', huffman=%b)", |
|
446 |
name, nameHuffman, value, valueHuffman)); |
|
48083 | 447 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
448 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
449 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
450 |
writer = literalWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
451 |
.name(name, nameHuffman).value(value, valueHuffman); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
452 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
453 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
454 |
protected final void literalNeverIndexed(int index, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
455 |
CharSequence value, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
456 |
boolean valueHuffman) |
50681 | 457 |
throws IndexOutOfBoundsException |
458 |
{ |
|
48083 | 459 |
if (logger.isLoggable(EXTRA)) { |
50681 | 460 |
logger.log(EXTRA, () -> format( |
461 |
"literal never indexed (%s, '%s', huffman=%b)", |
|
462 |
index, value, valueHuffman)); |
|
48083 | 463 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
464 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
465 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
466 |
writer = literalNeverIndexedWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
467 |
.index(index).value(value, valueHuffman); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
468 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
469 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
470 |
protected final void literalNeverIndexed(CharSequence name, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
471 |
boolean nameHuffman, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
472 |
CharSequence value, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
473 |
boolean valueHuffman) { |
48083 | 474 |
if (logger.isLoggable(EXTRA)) { |
50681 | 475 |
logger.log(EXTRA, () -> format( |
476 |
"literal never indexed ('%s', huffman=%b, '%s', huffman=%b)", |
|
477 |
name, nameHuffman, value, valueHuffman)); |
|
48083 | 478 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
479 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
480 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
481 |
writer = literalNeverIndexedWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
482 |
.name(name, nameHuffman).value(value, valueHuffman); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
483 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
484 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
485 |
protected final void literalWithIndexing(int index, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
486 |
CharSequence value, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
487 |
boolean valueHuffman) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
488 |
throws IndexOutOfBoundsException { |
48083 | 489 |
if (logger.isLoggable(EXTRA)) { |
50681 | 490 |
logger.log(EXTRA, () -> format( |
491 |
"literal with incremental indexing (%s, '%s', huffman=%b)", |
|
492 |
index, value, valueHuffman)); |
|
48083 | 493 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
494 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
495 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
496 |
writer = literalWithIndexingWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
497 |
.index(index).value(value, valueHuffman); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
498 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
499 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
500 |
protected final void literalWithIndexing(CharSequence name, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
501 |
boolean nameHuffman, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
502 |
CharSequence value, |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
503 |
boolean valueHuffman) { |
50681 | 504 |
if (logger.isLoggable(EXTRA)) { |
505 |
logger.log(EXTRA, () -> format( |
|
506 |
"literal with incremental indexing ('%s', huffman=%b, '%s', huffman=%b)", |
|
507 |
name, nameHuffman, value, valueHuffman)); |
|
48083 | 508 |
} |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
509 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
510 |
encoding = true; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
511 |
writer = literalWithIndexingWriter |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
512 |
.name(name, nameHuffman).value(value, valueHuffman); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
513 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
514 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
515 |
protected final void sizeUpdate(int capacity) |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
516 |
throws IllegalArgumentException { |
48083 | 517 |
if (logger.isLoggable(EXTRA)) { |
518 |
logger.log(EXTRA, () -> format("dynamic table size update %s", |
|
519 |
capacity)); |
|
520 |
} |
|
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
521 |
checkEncoding(); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
522 |
// Ensure subclass follows the contract |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
523 |
if (capacity > this.maxCapacity) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
524 |
throw new IllegalArgumentException( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
525 |
format("capacity <= maxCapacity: capacity=%s, maxCapacity=%s", |
50681 | 526 |
capacity, maxCapacity)); |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
527 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
528 |
writer = sizeUpdateWriter.maxHeaderTableSize(capacity); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
529 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
530 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
531 |
protected final int getMaxCapacity() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
532 |
return maxCapacity; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
533 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
534 |
|
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
535 |
protected final HeaderTable getHeaderTable() { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
536 |
return headerTable; |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
537 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
538 |
|
48083 | 539 |
protected final void checkEncoding() { // TODO: better name e.g. checkIfEncodingInProgress() |
42460
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
540 |
if (encoding) { |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
541 |
throw new IllegalStateException( |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
542 |
"Previous encoding operation hasn't finished yet"); |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
543 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
544 |
} |
7133f144981a
8170648: Move java.net.http package out of Java SE to incubator namespace
michaelm
parents:
diff
changeset
|
545 |
} |