Search in sources :

Example 1 with HeaderField

use of io.undertow.protocols.http2.Hpack.HeaderField in project undertow by undertow-io.

the class HpackDecoder method addEntryToHeaderTable.

private void addEntryToHeaderTable(HeaderField entry) {
    if (entry.size > specifiedMemorySize) {
        //it is to big to fit, so we just completely clear the table.
        while (filledTableSlots > 0) {
            headerTable[firstSlotPosition] = null;
            firstSlotPosition++;
            if (firstSlotPosition == headerTable.length) {
                firstSlotPosition = 0;
            }
            filledTableSlots--;
        }
        currentMemorySize = 0;
        return;
    }
    resizeIfRequired();
    int newTableSlots = filledTableSlots + 1;
    int tableLength = headerTable.length;
    int index = (firstSlotPosition + filledTableSlots) % tableLength;
    headerTable[index] = entry;
    int newSize = currentMemorySize + entry.size;
    while (newSize > specifiedMemorySize) {
        int clearIndex = firstSlotPosition;
        firstSlotPosition++;
        if (firstSlotPosition == tableLength) {
            firstSlotPosition = 0;
        }
        HeaderField oldData = headerTable[clearIndex];
        headerTable[clearIndex] = null;
        newSize -= oldData.size;
        newTableSlots--;
    }
    this.filledTableSlots = newTableSlots;
    currentMemorySize = newSize;
}
Also used : HeaderField(io.undertow.protocols.http2.Hpack.HeaderField)

Example 2 with HeaderField

use of io.undertow.protocols.http2.Hpack.HeaderField in project undertow by undertow-io.

the class HpackDecoder method addStaticTableEntry.

private void addStaticTableEntry(int index) throws HpackException {
    //adds an entry from the static table.
    HeaderField entry = Hpack.STATIC_TABLE[index];
    headerEmitter.emitHeader(entry.name, entry.value == null ? "" : entry.value, false);
}
Also used : HeaderField(io.undertow.protocols.http2.Hpack.HeaderField)

Example 3 with HeaderField

use of io.undertow.protocols.http2.Hpack.HeaderField in project undertow by undertow-io.

the class HpackDecoder method decode.

/**
     * 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
     */
public void decode(ByteBuffer buffer, boolean moreData) throws HpackException {
    while (buffer.hasRemaining()) {
        int originalPos = buffer.position();
        byte b = buffer.get();
        if ((b & 0b10000000) != 0) {
            first = false;
            //if the first bit is set it is an indexed header field
            //unget the byte
            buffer.position(buffer.position() - 1);
            //prefix is 7
            int index = Hpack.decodeInteger(buffer, 7);
            if (index == -1) {
                if (!moreData) {
                    throw UndertowMessages.MESSAGES.hpackFailed();
                }
                buffer.position(originalPos);
                return;
            } else if (index == 0) {
                throw UndertowMessages.MESSAGES.zeroNotValidHeaderTableIndex();
            }
            handleIndex(index);
        } else if ((b & 0b01000000) != 0) {
            first = false;
            //Literal Header Field with Incremental Indexing
            HttpString headerName = readHeaderName(buffer, 6);
            if (headerName == null) {
                if (!moreData) {
                    throw UndertowMessages.MESSAGES.hpackFailed();
                }
                buffer.position(originalPos);
                return;
            }
            String headerValue = readHpackString(buffer);
            if (headerValue == null) {
                if (!moreData) {
                    throw UndertowMessages.MESSAGES.hpackFailed();
                }
                buffer.position(originalPos);
                return;
            }
            headerEmitter.emitHeader(headerName, headerValue, false);
            addEntryToHeaderTable(new HeaderField(headerName, headerValue));
        } else if ((b & 0b11110000) == 0) {
            first = false;
            //Literal Header Field without Indexing
            HttpString headerName = readHeaderName(buffer, 4);
            if (headerName == null) {
                if (!moreData) {
                    throw UndertowMessages.MESSAGES.hpackFailed();
                }
                buffer.position(originalPos);
                return;
            }
            String headerValue = readHpackString(buffer);
            if (headerValue == null) {
                if (!moreData) {
                    throw UndertowMessages.MESSAGES.hpackFailed();
                }
                buffer.position(originalPos);
                return;
            }
            headerEmitter.emitHeader(headerName, headerValue, false);
        } else if ((b & 0b11110000) == 0b00010000) {
            first = false;
            //Literal Header Field never indexed
            HttpString headerName = readHeaderName(buffer, 4);
            if (headerName == null) {
                buffer.position(originalPos);
                return;
            }
            String headerValue = readHpackString(buffer);
            if (headerValue == null) {
                if (!moreData) {
                    throw UndertowMessages.MESSAGES.hpackFailed();
                }
                buffer.position(originalPos);
                return;
            }
            headerEmitter.emitHeader(headerName, headerValue, true);
        } else if ((b & 0b11100000) == 0b00100000) {
            if (!first) {
                throw new HpackException();
            }
            //context update max table size change
            if (!handleMaxMemorySizeChange(buffer, originalPos)) {
                return;
            }
        } else {
            throw UndertowMessages.MESSAGES.invalidHpackEncoding(b);
        }
    }
    if (!moreData) {
        first = true;
    }
}
Also used : HeaderField(io.undertow.protocols.http2.Hpack.HeaderField) HttpString(io.undertow.util.HttpString) HttpString(io.undertow.util.HttpString)

Example 4 with HeaderField

use of io.undertow.protocols.http2.Hpack.HeaderField in project undertow by undertow-io.

the class HpackDecoder method handleIndexedHeaderName.

private HttpString handleIndexedHeaderName(int index) throws HpackException {
    if (index <= Hpack.STATIC_TABLE_LENGTH) {
        return Hpack.STATIC_TABLE[index].name;
    } else {
        if (index >= Hpack.STATIC_TABLE_LENGTH + filledTableSlots) {
            throw new HpackException();
        }
        int adjustedIndex = getRealIndex(index - Hpack.STATIC_TABLE_LENGTH);
        HeaderField res = headerTable[adjustedIndex];
        if (res == null) {
            throw new HpackException();
        }
        return res.name;
    }
}
Also used : HeaderField(io.undertow.protocols.http2.Hpack.HeaderField)

Example 5 with HeaderField

use of io.undertow.protocols.http2.Hpack.HeaderField in project undertow by undertow-io.

the class HpackDecoder method handleMaxMemorySizeChange.

private boolean handleMaxMemorySizeChange(ByteBuffer buffer, int originalPos) throws HpackException {
    //unget the byte
    buffer.position(buffer.position() - 1);
    int size = Hpack.decodeInteger(buffer, 5);
    if (size == -1) {
        buffer.position(originalPos);
        return false;
    }
    if (size > maxAllowedMemorySize) {
        throw new HpackException(Http2Channel.ERROR_PROTOCOL_ERROR);
    }
    specifiedMemorySize = size;
    if (currentMemorySize > specifiedMemorySize) {
        int newTableSlots = filledTableSlots;
        int tableLength = headerTable.length;
        int newSize = currentMemorySize;
        while (newSize > specifiedMemorySize) {
            int clearIndex = firstSlotPosition;
            firstSlotPosition++;
            if (firstSlotPosition == tableLength) {
                firstSlotPosition = 0;
            }
            HeaderField oldData = headerTable[clearIndex];
            headerTable[clearIndex] = null;
            newSize -= oldData.size;
            newTableSlots--;
        }
        this.filledTableSlots = newTableSlots;
        currentMemorySize = newSize;
    }
    return true;
}
Also used : HeaderField(io.undertow.protocols.http2.Hpack.HeaderField)

Aggregations

HeaderField (io.undertow.protocols.http2.Hpack.HeaderField)6 HttpString (io.undertow.util.HttpString)1