Decodes the provided frame data. If this method leaves data in the buffer then this buffer should be compacted so this data is preserved, unless there is no more data in which case this should be considered a protocol error. @param buffer The buffer @throws HpackException If the packed data is not
(ByteBuffer buffer)
| 94 | * @throws HpackException If the packed data is not valid |
| 95 | */ |
| 96 | void decode(ByteBuffer buffer) throws HpackException { |
| 97 | while (buffer.hasRemaining()) { |
| 98 | int originalPos = buffer.position(); |
| 99 | byte b = buffer.get(); |
| 100 | if ((b & 0b10000000) != 0) { |
| 101 | // if the first bit is set it is an indexed header field |
| 102 | buffer.position(buffer.position() - 1); // unget the byte |
| 103 | int index = Hpack.decodeInteger(buffer, 7); // prefix is 7 |
| 104 | if (index == -1) { |
| 105 | buffer.position(originalPos); |
| 106 | return; |
| 107 | } else if (index == 0) { |
| 108 | throw new HpackException(sm.getString("hpackdecoder.zeroNotValidHeaderTableIndex")); |
| 109 | } |
| 110 | handleIndex(index); |
| 111 | } else if ((b & 0b01000000) != 0) { |
| 112 | // Literal Header Field with Incremental Indexing |
| 113 | String headerName = readHeaderName(buffer, 6); |
| 114 | if (headerName == null) { |
| 115 | buffer.position(originalPos); |
| 116 | return; |
| 117 | } |
| 118 | String headerValue = readHpackString(buffer, false); |
| 119 | if (headerValue == null) { |
| 120 | buffer.position(originalPos); |
| 121 | return; |
| 122 | } |
| 123 | emitHeader(headerName, headerValue); |
| 124 | addEntryToHeaderTable(new Hpack.HeaderField(headerName, headerValue)); |
| 125 | } else if ((b & 0b11110000) == 0) { |
| 126 | // Literal Header Field without Indexing |
| 127 | String headerName = readHeaderName(buffer, 4); |
| 128 | if (headerName == null) { |
| 129 | buffer.position(originalPos); |
| 130 | return; |
| 131 | } |
| 132 | String headerValue = readHpackString(buffer, false); |
| 133 | if (headerValue == null) { |
| 134 | buffer.position(originalPos); |
| 135 | return; |
| 136 | } |
| 137 | emitHeader(headerName, headerValue); |
| 138 | } else if ((b & 0b11110000) == 0b00010000) { |
| 139 | // Literal Header Field never indexed |
| 140 | String headerName = readHeaderName(buffer, 4); |
| 141 | if (headerName == null) { |
| 142 | buffer.position(originalPos); |
| 143 | return; |
| 144 | } |
| 145 | String headerValue = readHpackString(buffer, false); |
| 146 | if (headerValue == null) { |
| 147 | buffer.position(originalPos); |
| 148 | return; |
| 149 | } |
| 150 | emitHeader(headerName, headerValue); |
| 151 | } else if ((b & 0b11100000) == 0b00100000) { |
| 152 | // context update max table size change |
| 153 | if (!handleMaxMemorySizeChange(buffer, originalPos)) { |