or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compression-utilities.mdcontent-management.mdcookie-handling.mdhttp-headers.mdhttp-methods-status.mdhttp-parsing-generation.mdindex.mdmultipart-processing.mdpath-mapping.mduri-processing.md

compression-utilities.mddocs/

0

# Compression Utilities

1

2

HPACK compression utilities for HTTP/2 header compression including N-bit integer encoding/decoding, Huffman coding, and efficient stream processing.

3

4

## Capabilities

5

6

### N-bit Integer Encoding

7

8

HPACK integer encoding with configurable bit prefixes for efficient header compression.

9

10

```java { .api }

11

/**

12

* N-bit integer encoder for HPACK compression

13

*/

14

class NBitIntegerEncoder {

15

/** Calculate octets needed to encode value with prefix */

16

static int octetsNeeded(int prefix, long value);

17

18

/** Encode integer value into buffer with bit prefix */

19

static void encode(ByteBuffer buffer, int prefix, long value);

20

21

/** Encode integer with specific prefix bits */

22

static void encode(ByteBuffer buffer, int prefixBits, int prefix, long value);

23

}

24

```

25

26

### N-bit Integer Decoding

27

28

HPACK integer decoding with state management for streaming processing.

29

30

```java { .api }

31

/**

32

* N-bit integer decoder for HPACK decompression

33

*/

34

class NBitIntegerDecoder {

35

/** Create decoder */

36

NBitIntegerDecoder();

37

38

/** Set bit prefix for next decode operation */

39

void setPrefix(int prefix);

40

41

/** Decode integer from buffer as int */

42

int decodeInt(ByteBuffer buffer);

43

44

/** Decode integer from buffer as long */

45

long decodeLong(ByteBuffer buffer);

46

47

/** Reset decoder state for next value */

48

void reset();

49

50

/** Check if decoder is in reset state */

51

boolean isReset();

52

}

53

```

54

55

### N-bit String Decoding

56

57

HPACK string decoding with Huffman support and streaming capabilities.

58

59

```java { .api }

60

/**

61

* N-bit string decoder for HPACK decompression

62

*/

63

class NBitStringDecoder {

64

/** Create string decoder */

65

NBitStringDecoder();

66

67

/** Create with specific Huffman decoder */

68

NBitStringDecoder(HuffmanDecoder huffmanDecoder);

69

70

/** Set bit prefix for string length */

71

void setPrefix(int prefix);

72

73

/** Decode string from buffer */

74

String decode(ByteBuffer buffer);

75

76

/** Reset decoder state */

77

void reset();

78

79

/** Check if decoder needs more data */

80

boolean isNeedMoreData();

81

}

82

```

83

84

### Huffman Coding

85

86

Huffman encoding and decoding for HPACK string compression.

87

88

```java { .api }

89

/**

90

* Huffman coding utilities for HPACK

91

*/

92

class Huffman {

93

/** Huffman encoder for string compression */

94

static class HuffmanEncoder {

95

/** Calculate octets needed for string */

96

static int octetsNeeded(String s);

97

98

/** Calculate octets needed for byte array */

99

static int octetsNeeded(byte[] b);

100

101

/** Encode string into buffer */

102

static void encode(ByteBuffer buffer, String s);

103

104

/** Encode byte array into buffer */

105

static void encode(ByteBuffer buffer, byte[] b);

106

107

/** Calculate octets needed for lowercase encoding */

108

static int octetsNeededLowerCase(String s);

109

110

/** Encode string as lowercase into buffer */

111

static void encodeLowerCase(ByteBuffer buffer, String s);

112

}

113

114

/** Huffman decoder for string decompression */

115

static class HuffmanDecoder {

116

/** Create decoder */

117

HuffmanDecoder();

118

119

/** Set expected decoded length */

120

void setLength(int length);

121

122

/** Decode buffer content to string */

123

String decode(ByteBuffer buffer);

124

125

/** Reset decoder state */

126

void reset();

127

128

/** Check if decoding is complete */

129

boolean isComplete();

130

}

131

}

132

```

133

134

### GZIP Content Decoding

135

136

GZIP content decompression for HTTP content handling.

137

138

```java { .api }

139

/**

140

* GZIP content decoder with streaming support

141

*/

142

class GZIPContentDecoder implements Destroyable {

143

/** Create GZIP decoder */

144

GZIPContentDecoder();

145

146

/** Create with buffer pool */

147

GZIPContentDecoder(ByteBufferPool byteBufferPool);

148

149

/** Create with buffer pool and buffer size */

150

GZIPContentDecoder(ByteBufferPool byteBufferPool, int bufferSize);

151

152

/** Decode compressed content */

153

Content.Chunk decode(Content.Chunk chunk);

154

155

/** Check if decoder is finished */

156

boolean isFinished();

157

158

/** Reset decoder for new stream */

159

void reset();

160

161

/** Destroy decoder and release resources */

162

void destroy();

163

164

/** Get buffer pool */

165

ByteBufferPool getByteBufferPool();

166

167

/** Get buffer size */

168

int getBufferSize();

169

}

170

```

171

172

### Encoding Exception

173

174

Exception class for compression/decompression errors.

175

176

```java { .api }

177

/**

178

* Exception for compression encoding/decoding errors

179

*/

180

class EncodingException extends Exception {

181

/** Create encoding exception with message */

182

EncodingException(String message);

183

184

/** Create encoding exception with message and cause */

185

EncodingException(String message, Throwable cause);

186

}

187

```

188

189

**Usage Examples:**

190

191

```java

192

import org.eclipse.jetty.http.compression.*;

193

import java.nio.ByteBuffer;

194

195

// N-bit integer encoding for HPACK

196

ByteBuffer buffer = ByteBuffer.allocate(16);

197

198

// Encode integer with 5-bit prefix

199

long value = 1024;

200

int prefixBits = 5;

201

202

int octetsNeeded = NBitIntegerEncoder.octetsNeeded(prefixBits, value);

203

NBitIntegerEncoder.encode(buffer, prefixBits, value);

204

205

buffer.flip(); // Prepare for reading

206

207

// N-bit integer decoding

208

NBitIntegerDecoder intDecoder = new NBitIntegerDecoder();

209

intDecoder.setPrefix(prefixBits);

210

211

long decodedValue = intDecoder.decodeLong(buffer); // 1024

212

intDecoder.reset(); // Reset for next value

213

214

// Huffman string encoding

215

String headerValue = "www.example.com";

216

217

// Calculate space needed

218

int huffmanSize = Huffman.HuffmanEncoder.octetsNeeded(headerValue);

219

ByteBuffer huffmanBuffer = ByteBuffer.allocate(huffmanSize + 10);

220

221

// Encode with Huffman compression

222

Huffman.HuffmanEncoder.encode(huffmanBuffer, headerValue);

223

224

// Encode as lowercase (useful for header names)

225

String headerName = "Content-Type";

226

int lowerSize = Huffman.HuffmanEncoder.octetsNeededLowerCase(headerName);

227

ByteBuffer lowerBuffer = ByteBuffer.allocate(lowerSize + 10);

228

Huffman.HuffmanEncoder.encodeLowerCase(lowerBuffer, headerName);

229

230

huffmanBuffer.flip();

231

232

// Huffman string decoding

233

Huffman.HuffmanDecoder huffmanDecoder = new Huffman.HuffmanDecoder();

234

huffmanDecoder.setLength(headerValue.length()); // Expected decoded length

235

236

String decoded = huffmanDecoder.decode(huffmanBuffer);

237

System.out.println(decoded); // "www.example.com"

238

239

huffmanDecoder.reset(); // Reset for next string

240

241

// N-bit string decoding with Huffman support

242

NBitStringDecoder stringDecoder = new NBitStringDecoder(huffmanDecoder);

243

244

// Prepare string with length prefix and Huffman flag

245

ByteBuffer stringBuffer = ByteBuffer.allocate(64);

246

247

// Encode string length with Huffman flag (bit 7 set)

248

int stringLength = huffmanSize;

249

boolean huffmanEncoded = true;

250

int lengthPrefix = huffmanEncoded ? (0x80 | stringLength) : stringLength;

251

252

stringBuffer.put((byte) lengthPrefix);

253

stringBuffer.put(huffmanBuffer.array(), 0, huffmanSize);

254

stringBuffer.flip();

255

256

// Decode string

257

stringDecoder.setPrefix(7); // 7-bit prefix for string length

258

String decodedString = stringDecoder.decode(stringBuffer);

259

stringDecoder.reset();

260

261

// GZIP content decoding

262

ByteBufferPool bufferPool = new ArrayByteBufferPool();

263

GZIPContentDecoder gzipDecoder = new GZIPContentDecoder(bufferPool, 8192);

264

265

// Simulate compressed content chunks

266

byte[] compressedData = compressWithGzip("Hello, World!");

267

Content.Chunk compressedChunk = Content.Chunk.from(ByteBuffer.wrap(compressedData), false);

268

269

// Decode content

270

Content.Chunk decodedChunk = gzipDecoder.decode(compressedChunk);

271

if (decodedChunk != null) {

272

ByteBuffer decodedBuffer = decodedChunk.getByteBuffer();

273

String decodedText = StandardCharsets.UTF_8.decode(decodedBuffer).toString();

274

System.out.println(decodedText); // "Hello, World!"

275

}

276

277

// Check if decoding is complete

278

boolean finished = gzipDecoder.isFinished();

279

280

// Reset for new stream

281

gzipDecoder.reset();

282

283

// Clean up

284

gzipDecoder.destroy();

285

286

// Complete HPACK header encoding example

287

class HPACKHeaderEncoder {

288

private final ByteBuffer buffer;

289

290

HPACKHeaderEncoder() {

291

this.buffer = ByteBuffer.allocate(4096);

292

}

293

294

void encodeHeader(String name, String value, boolean huffman) {

295

// Encode header name

296

if (huffman) {

297

int nameSize = Huffman.HuffmanEncoder.octetsNeededLowerCase(name);

298

// Set Huffman flag (bit 7) and encode length with 7-bit prefix

299

NBitIntegerEncoder.encode(buffer, 7, 0x80 | nameSize);

300

Huffman.HuffmanEncoder.encodeLowerCase(buffer, name);

301

} else {

302

NBitIntegerEncoder.encode(buffer, 7, name.length());

303

buffer.put(name.toLowerCase().getBytes(StandardCharsets.UTF_8));

304

}

305

306

// Encode header value

307

if (huffman) {

308

int valueSize = Huffman.HuffmanEncoder.octetsNeeded(value);

309

NBitIntegerEncoder.encode(buffer, 7, 0x80 | valueSize);

310

Huffman.HuffmanEncoder.encode(buffer, value);

311

} else {

312

NBitIntegerEncoder.encode(buffer, 7, value.length());

313

buffer.put(value.getBytes(StandardCharsets.UTF_8));

314

}

315

}

316

317

ByteBuffer getBuffer() {

318

buffer.flip();

319

return buffer.asReadOnlyBuffer();

320

}

321

}

322

323

// Use HPACK encoder

324

HPACKHeaderEncoder encoder = new HPACKHeaderEncoder();

325

encoder.encodeHeader("content-type", "application/json", true);

326

encoder.encodeHeader("content-length", "1024", false);

327

328

ByteBuffer encodedHeaders = encoder.getBuffer();

329

330

// Error handling

331

try {

332

// Encoding/decoding operations that might fail

333

Huffman.HuffmanDecoder decoder = new Huffman.HuffmanDecoder();

334

decoder.setLength(100);

335

String result = decoder.decode(corruptedBuffer);

336

} catch (Exception e) {

337

if (e.getCause() instanceof EncodingException) {

338

EncodingException encodingError = (EncodingException) e.getCause();

339

System.err.println("Compression error: " + encodingError.getMessage());

340

}

341

}

342

343

// Helper method for GZIP compression (implementation would use actual GZIP)

344

private byte[] compressWithGzip(String data) {

345

// Implementation would use GZIPOutputStream

346

return data.getBytes(StandardCharsets.UTF_8); // Simplified

347

}

348

```