Package org.playframework.netty.http
Class HttpStreamsHandler<In extends io.netty.handler.codec.http.HttpMessage,Out extends io.netty.handler.codec.http.HttpMessage>
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- io.netty.channel.ChannelDuplexHandler
-
- org.playframework.netty.http.HttpStreamsHandler<In,Out>
-
- All Implemented Interfaces:
io.netty.channel.ChannelHandler
,io.netty.channel.ChannelInboundHandler
,io.netty.channel.ChannelOutboundHandler
- Direct Known Subclasses:
HttpStreamsClientHandler
,HttpStreamsServerHandler
abstract class HttpStreamsHandler<In extends io.netty.handler.codec.http.HttpMessage,Out extends io.netty.handler.codec.http.HttpMessage> extends io.netty.channel.ChannelDuplexHandler
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) class
HttpStreamsHandler.Outgoing
-
Field Summary
Fields Modifier and Type Field Description private In
currentlyStreamedMessage
The incoming message that is currently being streamed out to a subscriber.private boolean
ignoreBodyRead
Ignore the remaining reads for the incoming message.private java.lang.Class<In>
inClass
private java.lang.Class<Out>
outClass
private java.util.Queue<HttpStreamsHandler.Outgoing>
outgoing
private boolean
sendLastHttpContent
Whether a LastHttpContent message needs to be written once the incoming publisher completes.
-
Constructor Summary
Constructors Constructor Description HttpStreamsHandler(java.lang.Class<In> inClass, java.lang.Class<Out> outClass)
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected void
bodyRequested(io.netty.channel.ChannelHandlerContext ctx)
Invoked every time a read of the incoming body is requested by the subscriber.void
channelRead(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg)
void
channelReadComplete(io.netty.channel.ChannelHandlerContext ctx)
private void
completeBody(io.netty.channel.ChannelHandlerContext ctx)
protected void
consumedInMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an incoming message is fully consumed.protected abstract In
createEmptyMessage(In in)
Create an empty incoming message.protected abstract In
createStreamedMessage(In in, org.reactivestreams.Publisher<io.netty.handler.codec.http.HttpContent> stream)
Create a streamed incoming message with the given stream.private void
executeInEventLoop(io.netty.channel.ChannelHandlerContext ctx, java.lang.Runnable runnable)
private void
flushNext(io.netty.channel.ChannelHandlerContext ctx)
private void
handleCancelled(io.netty.channel.ChannelHandlerContext ctx, In msg)
private void
handleReadHttpContent(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpContent content)
protected abstract boolean
hasBody(In in)
Whether the given incoming message has a body.protected void
receivedInMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an incoming message is first received.protected void
receivedOutMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an outgoing message is first received.private void
removeHandlerIfActive(io.netty.channel.ChannelHandlerContext ctx, java.lang.String name)
Most operations we want to do even if the channel is not active, because if it's not, then we want to encounter the error that occurs when that operation happens and so that it can be passed up to the user.protected void
sentOutMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an outgoing message is fully sent.protected void
subscribeSubscriberToStream(StreamedHttpMessage msg, org.reactivestreams.Subscriber<io.netty.handler.codec.http.HttpContent> subscriber)
Subscribe the given subscriber to the given streamed message.protected void
unbufferedWrite(io.netty.channel.ChannelHandlerContext ctx, HttpStreamsHandler.Outgoing out)
void
write(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg, io.netty.channel.ChannelPromise promise)
-
Methods inherited from class io.netty.channel.ChannelDuplexHandler
bind, close, connect, deregister, disconnect, flush, read
-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelActive, channelInactive, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught, userEventTriggered
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, handlerRemoved, isSharable
-
-
-
-
Field Detail
-
outgoing
private final java.util.Queue<HttpStreamsHandler.Outgoing> outgoing
-
inClass
private final java.lang.Class<In extends io.netty.handler.codec.http.HttpMessage> inClass
-
outClass
private final java.lang.Class<Out extends io.netty.handler.codec.http.HttpMessage> outClass
-
currentlyStreamedMessage
private In extends io.netty.handler.codec.http.HttpMessage currentlyStreamedMessage
The incoming message that is currently being streamed out to a subscriber. This is tracked so that if its subscriber cancels, we can go into a mode where we ignore the rest of the body. Since subscribers may cancel as many times as they like, including well after they've received all their content, we need to track what the current message that's being streamed out is so that we can ignore it if it's not currently being streamed out.
-
ignoreBodyRead
private boolean ignoreBodyRead
Ignore the remaining reads for the incoming message. This is used in conjunction with currentlyStreamedMessage, as well as in situations where we have received the full body, but still might be expecting a last http content message.
-
sendLastHttpContent
private boolean sendLastHttpContent
Whether a LastHttpContent message needs to be written once the incoming publisher completes. Since the publisher may itself publish a LastHttpContent message, we need to track this fact, because if it doesn't, then we need to write one ourselves.
-
-
Method Detail
-
hasBody
protected abstract boolean hasBody(In in)
Whether the given incoming message has a body.
-
createEmptyMessage
protected abstract In createEmptyMessage(In in)
Create an empty incoming message. This must be of type FullHttpMessage, and is invoked when we've determined that an incoming message can't have a body, so we send it on as a FullHttpMessage.
-
createStreamedMessage
protected abstract In createStreamedMessage(In in, org.reactivestreams.Publisher<io.netty.handler.codec.http.HttpContent> stream)
Create a streamed incoming message with the given stream.
-
receivedInMessage
protected void receivedInMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an incoming message is first received. Overridden by sub classes for state tracking.
-
consumedInMessage
protected void consumedInMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an incoming message is fully consumed. Overridden by sub classes for state tracking.
-
receivedOutMessage
protected void receivedOutMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an outgoing message is first received. Overridden by sub classes for state tracking.
-
sentOutMessage
protected void sentOutMessage(io.netty.channel.ChannelHandlerContext ctx)
Invoked when an outgoing message is fully sent. Overridden by sub classes for state tracking.
-
subscribeSubscriberToStream
protected void subscribeSubscriberToStream(StreamedHttpMessage msg, org.reactivestreams.Subscriber<io.netty.handler.codec.http.HttpContent> subscriber)
Subscribe the given subscriber to the given streamed message. Provided so that the client subclass can intercept this to hold off sending the body of an expect 100 continue request.
-
bodyRequested
protected void bodyRequested(io.netty.channel.ChannelHandlerContext ctx)
Invoked every time a read of the incoming body is requested by the subscriber. Provided so that the server subclass can intercept this to send a 100 continue response.
-
channelRead
public void channelRead(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg) throws java.lang.Exception
- Specified by:
channelRead
in interfaceio.netty.channel.ChannelInboundHandler
- Overrides:
channelRead
in classio.netty.channel.ChannelInboundHandlerAdapter
- Throws:
java.lang.Exception
-
handleCancelled
private void handleCancelled(io.netty.channel.ChannelHandlerContext ctx, In msg)
-
handleReadHttpContent
private void handleReadHttpContent(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpContent content)
-
channelReadComplete
public void channelReadComplete(io.netty.channel.ChannelHandlerContext ctx) throws java.lang.Exception
- Specified by:
channelReadComplete
in interfaceio.netty.channel.ChannelInboundHandler
- Overrides:
channelReadComplete
in classio.netty.channel.ChannelInboundHandlerAdapter
- Throws:
java.lang.Exception
-
write
public void write(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg, io.netty.channel.ChannelPromise promise) throws java.lang.Exception
- Specified by:
write
in interfaceio.netty.channel.ChannelOutboundHandler
- Overrides:
write
in classio.netty.channel.ChannelDuplexHandler
- Throws:
java.lang.Exception
-
unbufferedWrite
protected void unbufferedWrite(io.netty.channel.ChannelHandlerContext ctx, HttpStreamsHandler.Outgoing out)
-
completeBody
private void completeBody(io.netty.channel.ChannelHandlerContext ctx)
-
removeHandlerIfActive
private void removeHandlerIfActive(io.netty.channel.ChannelHandlerContext ctx, java.lang.String name)
Most operations we want to do even if the channel is not active, because if it's not, then we want to encounter the error that occurs when that operation happens and so that it can be passed up to the user. However, removing handlers should only be done if the channel is active, because the error that is encountered when they aren't makes no sense to the user (NoSuchElementException).
-
flushNext
private void flushNext(io.netty.channel.ChannelHandlerContext ctx)
-
executeInEventLoop
private void executeInEventLoop(io.netty.channel.ChannelHandlerContext ctx, java.lang.Runnable runnable)
-
-