org.reaktivity.nukleus.http2.internal.Http2Writer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nukleus-http2 Show documentation
Show all versions of nukleus-http2 Show documentation
HTTP/2 Nukleus Implementation
The newest version!
/**
* Copyright 2016-2019 The Reaktivity Project
*
* The Reaktivity Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.reaktivity.nukleus.http2.internal;
import java.util.function.BiConsumer;
import org.agrona.DirectBuffer;
import org.agrona.MutableDirectBuffer;
import org.reaktivity.nukleus.function.MessageConsumer;
import org.reaktivity.nukleus.http2.internal.types.ArrayFW;
import org.reaktivity.nukleus.http2.internal.types.HttpHeaderFW;
import org.reaktivity.nukleus.http2.internal.types.stream.DataFW;
import org.reaktivity.nukleus.http2.internal.types.stream.EndFW;
import org.reaktivity.nukleus.http2.internal.types.stream.HpackHeaderBlockFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2DataFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2ErrorCode;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2Flags;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2GoawayFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2HeadersFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2PingFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2PushPromiseFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2RstStreamFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2SettingsFW;
import org.reaktivity.nukleus.http2.internal.types.stream.Http2WindowUpdateFW;
class Http2Writer
{
private final DataFW.Builder dataRW = new DataFW.Builder();
private final EndFW.Builder endRW = new EndFW.Builder();
private final Http2SettingsFW.Builder settingsRW = new Http2SettingsFW.Builder();
private final Http2RstStreamFW.Builder http2ResetRW = new Http2RstStreamFW.Builder();
private final Http2GoawayFW.Builder goawayRW = new Http2GoawayFW.Builder();
private final Http2PingFW.Builder pingRW = new Http2PingFW.Builder();
private final Http2WindowUpdateFW.Builder http2WindowRW = new Http2WindowUpdateFW.Builder();
private final Http2DataFW.Builder http2DataRW = new Http2DataFW.Builder();
private final Http2HeadersFW.Builder http2HeadersRW = new Http2HeadersFW.Builder();
private final Http2PushPromiseFW.Builder pushPromiseRW = new Http2PushPromiseFW.Builder();
final MutableDirectBuffer writeBuffer;
Http2Writer(
MutableDirectBuffer writeBuffer)
{
this.writeBuffer = writeBuffer;
}
void doData(
MessageConsumer receiver,
long routeId,
long streamId,
long traceId,
int padding,
MutableDirectBuffer payload,
int offset,
int length)
{
assert offset >= DataFW.FIELD_OFFSET_PAYLOAD;
final DataFW data = dataRW.wrap(payload, offset - DataFW.FIELD_OFFSET_PAYLOAD, offset + length)
.routeId(routeId)
.streamId(streamId)
.trace(traceId)
.groupId(0)
.padding(padding)
.payload(p -> p.set((b, o, l) -> length))
.build();
receiver.accept(data.typeId(), data.buffer(), data.offset(), data.sizeof());
}
void doEnd(
MessageConsumer receiver,
long routeId,
long streamId)
{
final EndFW end = endRW.wrap(writeBuffer, 0, writeBuffer.capacity())
.routeId(routeId)
.streamId(streamId)
.build();
receiver.accept(end.typeId(), end.buffer(), end.offset(), end.sizeof());
}
int settings(
int offset,
int length,
int maxConcurrentStreams,
int initialWindowSize)
{
int written = settingsRW.wrap(writeBuffer, offset, offset + length)
.maxConcurrentStreams(maxConcurrentStreams)
.initialWindowSize(initialWindowSize)
.build()
.sizeof();
assert written == length;
return written;
}
int settingsAck(
int offset,
int length)
{
int written = settingsRW.wrap(writeBuffer, offset, offset + length)
.ack()
.build()
.sizeof();
assert written == length;
return written;
}
int rst(
int offset,
int length,
int streamId,
Http2ErrorCode errorCode)
{
int written = http2ResetRW.wrap(writeBuffer, offset, offset + length)
.streamId(streamId)
.errorCode(errorCode)
.build()
.sizeof();
assert written == length;
return written;
}
int goaway(
int offset,
int length,
int lastStreamId,
Http2ErrorCode errorCode)
{
int written = goawayRW.wrap(writeBuffer, offset, offset + length)
.lastStreamId(lastStreamId)
.errorCode(errorCode)
.build()
.sizeof();
assert written == length;
return written;
}
int pingAck(
int offset,
int length,
DirectBuffer payloadBuffer,
int payloadOffset,
int payloadLength)
{
int written = pingRW.wrap(writeBuffer, offset, offset + length)
.ack()
.payload(payloadBuffer, payloadOffset, payloadLength)
.build()
.sizeof();
assert written == length;
return written;
}
int windowUpdate(
int offset,
int length,
int streamId,
int update)
{
int written = http2WindowRW.wrap(writeBuffer, offset, offset + length)
.streamId(streamId)
.size(update)
.build()
.sizeof();
assert written == length;
return written;
}
int data(
int offset,
int length,
int streamId,
DirectBuffer payloadBuffer,
int payloadOffset,
int payloadLength)
{
int written = http2DataRW.wrap(writeBuffer, offset, offset + length)
.streamId(streamId)
.payload(payloadBuffer, payloadOffset, payloadLength)
.build()
.sizeof();
assert written == length;
return written;
}
int dataEos(
int offset,
int length,
int streamId)
{
assert streamId != 0;
int written = http2DataRW.wrap(writeBuffer, offset, offset + length)
.streamId(streamId)
.endStream()
.build()
.sizeof();
assert written == length;
return written;
}
int headers(
int offset,
int lengthGuess,
int streamId,
byte flags,
ArrayFW headers,
BiConsumer, HpackHeaderBlockFW.Builder> builder)
{
byte headersFlags = (byte) (flags | Http2Flags.END_HEADERS);
int written = http2HeadersRW.wrap(writeBuffer, offset, offset + lengthGuess)
.streamId(streamId)
.flags(headersFlags)
.headers(b -> builder.accept(headers, b))
.build()
.sizeof();
assert written <= lengthGuess;
return written;
}
int headers(
int offset,
int length,
int streamId,
byte flags,
DirectBuffer blockBuffer,
int blockOffset,
int blockLength)
{
assert streamId != 0;
byte headersFlags = (byte) (flags | Http2Flags.END_HEADERS);
int written = http2HeadersRW.wrap(writeBuffer, offset, offset + length)
.streamId(streamId)
.flags(headersFlags)
.payload(blockBuffer, blockOffset, blockLength)
.build()
.sizeof();
assert written == length;
return written;
}
int pushPromise(
int offset,
int lengthGuess,
int streamId,
int promisedStreamId,
ArrayFW headers,
BiConsumer, HpackHeaderBlockFW.Builder> builder)
{
int written = pushPromiseRW.wrap(writeBuffer, offset, offset + lengthGuess)
.streamId(streamId)
.promisedStreamId(promisedStreamId)
.endHeaders()
.headers(b -> builder.accept(headers, b))
.build()
.sizeof();
assert written <= lengthGuess;
return written;
}
int pushPromise(
int offset,
int length,
int streamId,
int promisedStreamId,
DirectBuffer blockBuffer,
int blockOffset,
int blockLength)
{
assert streamId != 0;
int written = pushPromiseRW.wrap(writeBuffer, offset, offset + length)
.streamId(streamId)
.promisedStreamId(promisedStreamId)
.endHeaders()
.headers(blockBuffer, blockOffset, blockLength)
.build()
.sizeof();
assert written == length;
return written;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy