Core HTTP protocol support library for Eclipse Jetty providing header handling, parsing, generation, compliance validation, and content processing capabilities
—
HPACK compression utilities for HTTP/2 header compression including N-bit integer encoding/decoding, Huffman coding, and efficient stream processing.
HPACK integer encoding with configurable bit prefixes for efficient header compression.
/**
* N-bit integer encoder for HPACK compression
*/
class NBitIntegerEncoder {
/** Calculate octets needed to encode value with prefix */
static int octetsNeeded(int prefix, long value);
/** Encode integer value into buffer with bit prefix */
static void encode(ByteBuffer buffer, int prefix, long value);
/** Encode integer with specific prefix bits */
static void encode(ByteBuffer buffer, int prefixBits, int prefix, long value);
}HPACK integer decoding with state management for streaming processing.
/**
* N-bit integer decoder for HPACK decompression
*/
class NBitIntegerDecoder {
/** Create decoder */
NBitIntegerDecoder();
/** Set bit prefix for next decode operation */
void setPrefix(int prefix);
/** Decode integer from buffer as int */
int decodeInt(ByteBuffer buffer);
/** Decode integer from buffer as long */
long decodeLong(ByteBuffer buffer);
/** Reset decoder state for next value */
void reset();
/** Check if decoder is in reset state */
boolean isReset();
}HPACK string decoding with Huffman support and streaming capabilities.
/**
* N-bit string decoder for HPACK decompression
*/
class NBitStringDecoder {
/** Create string decoder */
NBitStringDecoder();
/** Create with specific Huffman decoder */
NBitStringDecoder(HuffmanDecoder huffmanDecoder);
/** Set bit prefix for string length */
void setPrefix(int prefix);
/** Decode string from buffer */
String decode(ByteBuffer buffer);
/** Reset decoder state */
void reset();
/** Check if decoder needs more data */
boolean isNeedMoreData();
}Huffman encoding and decoding for HPACK string compression.
/**
* Huffman coding utilities for HPACK
*/
class Huffman {
/** Huffman encoder for string compression */
static class HuffmanEncoder {
/** Calculate octets needed for string */
static int octetsNeeded(String s);
/** Calculate octets needed for byte array */
static int octetsNeeded(byte[] b);
/** Encode string into buffer */
static void encode(ByteBuffer buffer, String s);
/** Encode byte array into buffer */
static void encode(ByteBuffer buffer, byte[] b);
/** Calculate octets needed for lowercase encoding */
static int octetsNeededLowerCase(String s);
/** Encode string as lowercase into buffer */
static void encodeLowerCase(ByteBuffer buffer, String s);
}
/** Huffman decoder for string decompression */
static class HuffmanDecoder {
/** Create decoder */
HuffmanDecoder();
/** Set expected decoded length */
void setLength(int length);
/** Decode buffer content to string */
String decode(ByteBuffer buffer);
/** Reset decoder state */
void reset();
/** Check if decoding is complete */
boolean isComplete();
}
}GZIP content decompression for HTTP content handling.
/**
* GZIP content decoder with streaming support
*/
class GZIPContentDecoder implements Destroyable {
/** Create GZIP decoder */
GZIPContentDecoder();
/** Create with buffer pool */
GZIPContentDecoder(ByteBufferPool byteBufferPool);
/** Create with buffer pool and buffer size */
GZIPContentDecoder(ByteBufferPool byteBufferPool, int bufferSize);
/** Decode compressed content */
Content.Chunk decode(Content.Chunk chunk);
/** Check if decoder is finished */
boolean isFinished();
/** Reset decoder for new stream */
void reset();
/** Destroy decoder and release resources */
void destroy();
/** Get buffer pool */
ByteBufferPool getByteBufferPool();
/** Get buffer size */
int getBufferSize();
}Exception class for compression/decompression errors.
/**
* Exception for compression encoding/decoding errors
*/
class EncodingException extends Exception {
/** Create encoding exception with message */
EncodingException(String message);
/** Create encoding exception with message and cause */
EncodingException(String message, Throwable cause);
}Usage Examples:
import org.eclipse.jetty.http.compression.*;
import java.nio.ByteBuffer;
// N-bit integer encoding for HPACK
ByteBuffer buffer = ByteBuffer.allocate(16);
// Encode integer with 5-bit prefix
long value = 1024;
int prefixBits = 5;
int octetsNeeded = NBitIntegerEncoder.octetsNeeded(prefixBits, value);
NBitIntegerEncoder.encode(buffer, prefixBits, value);
buffer.flip(); // Prepare for reading
// N-bit integer decoding
NBitIntegerDecoder intDecoder = new NBitIntegerDecoder();
intDecoder.setPrefix(prefixBits);
long decodedValue = intDecoder.decodeLong(buffer); // 1024
intDecoder.reset(); // Reset for next value
// Huffman string encoding
String headerValue = "www.example.com";
// Calculate space needed
int huffmanSize = Huffman.HuffmanEncoder.octetsNeeded(headerValue);
ByteBuffer huffmanBuffer = ByteBuffer.allocate(huffmanSize + 10);
// Encode with Huffman compression
Huffman.HuffmanEncoder.encode(huffmanBuffer, headerValue);
// Encode as lowercase (useful for header names)
String headerName = "Content-Type";
int lowerSize = Huffman.HuffmanEncoder.octetsNeededLowerCase(headerName);
ByteBuffer lowerBuffer = ByteBuffer.allocate(lowerSize + 10);
Huffman.HuffmanEncoder.encodeLowerCase(lowerBuffer, headerName);
huffmanBuffer.flip();
// Huffman string decoding
Huffman.HuffmanDecoder huffmanDecoder = new Huffman.HuffmanDecoder();
huffmanDecoder.setLength(headerValue.length()); // Expected decoded length
String decoded = huffmanDecoder.decode(huffmanBuffer);
System.out.println(decoded); // "www.example.com"
huffmanDecoder.reset(); // Reset for next string
// N-bit string decoding with Huffman support
NBitStringDecoder stringDecoder = new NBitStringDecoder(huffmanDecoder);
// Prepare string with length prefix and Huffman flag
ByteBuffer stringBuffer = ByteBuffer.allocate(64);
// Encode string length with Huffman flag (bit 7 set)
int stringLength = huffmanSize;
boolean huffmanEncoded = true;
int lengthPrefix = huffmanEncoded ? (0x80 | stringLength) : stringLength;
stringBuffer.put((byte) lengthPrefix);
stringBuffer.put(huffmanBuffer.array(), 0, huffmanSize);
stringBuffer.flip();
// Decode string
stringDecoder.setPrefix(7); // 7-bit prefix for string length
String decodedString = stringDecoder.decode(stringBuffer);
stringDecoder.reset();
// GZIP content decoding
ByteBufferPool bufferPool = new ArrayByteBufferPool();
GZIPContentDecoder gzipDecoder = new GZIPContentDecoder(bufferPool, 8192);
// Simulate compressed content chunks
byte[] compressedData = compressWithGzip("Hello, World!");
Content.Chunk compressedChunk = Content.Chunk.from(ByteBuffer.wrap(compressedData), false);
// Decode content
Content.Chunk decodedChunk = gzipDecoder.decode(compressedChunk);
if (decodedChunk != null) {
ByteBuffer decodedBuffer = decodedChunk.getByteBuffer();
String decodedText = StandardCharsets.UTF_8.decode(decodedBuffer).toString();
System.out.println(decodedText); // "Hello, World!"
}
// Check if decoding is complete
boolean finished = gzipDecoder.isFinished();
// Reset for new stream
gzipDecoder.reset();
// Clean up
gzipDecoder.destroy();
// Complete HPACK header encoding example
class HPACKHeaderEncoder {
private final ByteBuffer buffer;
HPACKHeaderEncoder() {
this.buffer = ByteBuffer.allocate(4096);
}
void encodeHeader(String name, String value, boolean huffman) {
// Encode header name
if (huffman) {
int nameSize = Huffman.HuffmanEncoder.octetsNeededLowerCase(name);
// Set Huffman flag (bit 7) and encode length with 7-bit prefix
NBitIntegerEncoder.encode(buffer, 7, 0x80 | nameSize);
Huffman.HuffmanEncoder.encodeLowerCase(buffer, name);
} else {
NBitIntegerEncoder.encode(buffer, 7, name.length());
buffer.put(name.toLowerCase().getBytes(StandardCharsets.UTF_8));
}
// Encode header value
if (huffman) {
int valueSize = Huffman.HuffmanEncoder.octetsNeeded(value);
NBitIntegerEncoder.encode(buffer, 7, 0x80 | valueSize);
Huffman.HuffmanEncoder.encode(buffer, value);
} else {
NBitIntegerEncoder.encode(buffer, 7, value.length());
buffer.put(value.getBytes(StandardCharsets.UTF_8));
}
}
ByteBuffer getBuffer() {
buffer.flip();
return buffer.asReadOnlyBuffer();
}
}
// Use HPACK encoder
HPACKHeaderEncoder encoder = new HPACKHeaderEncoder();
encoder.encodeHeader("content-type", "application/json", true);
encoder.encodeHeader("content-length", "1024", false);
ByteBuffer encodedHeaders = encoder.getBuffer();
// Error handling
try {
// Encoding/decoding operations that might fail
Huffman.HuffmanDecoder decoder = new Huffman.HuffmanDecoder();
decoder.setLength(100);
String result = decoder.decode(corruptedBuffer);
} catch (Exception e) {
if (e.getCause() instanceof EncodingException) {
EncodingException encodingError = (EncodingException) e.getCause();
System.err.println("Compression error: " + encodingError.getMessage());
}
}
// Helper method for GZIP compression (implementation would use actual GZIP)
private byte[] compressWithGzip(String data) {
// Implementation would use GZIPOutputStream
return data.getBytes(StandardCharsets.UTF_8); // Simplified
}Install with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty--jetty-http