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 
     

    Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler

    io.netty.channel.ChannelHandler.Sharable
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private In
    The incoming message that is currently being streamed out to a subscriber.
    private boolean
    Ignore the remaining reads for the incoming message.
    private final Class<In>
     
    private final Class<Out>
     
     
    private boolean
    Whether a LastHttpContent message needs to be written once the incoming publisher completes.
  • Constructor Summary

    Constructors
    Constructor
    Description
    HttpStreamsHandler(Class<In> inClass, Class<Out> outClass)
     
  • Method Summary

    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, 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
    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, 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, 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<In,Out>.Outgoing out)
     
    void
    write(io.netty.channel.ChannelHandlerContext ctx, 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

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface io.netty.channel.ChannelHandler

    handlerAdded, handlerRemoved
  • Field Details

    • outgoing

      private final Queue<HttpStreamsHandler<In extends io.netty.handler.codec.http.HttpMessage,Out extends io.netty.handler.codec.http.HttpMessage>.Outgoing> outgoing
    • inClass

      private final Class<In extends io.netty.handler.codec.http.HttpMessage> inClass
    • outClass

      private final 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.
  • Constructor Details

    • HttpStreamsHandler

      public HttpStreamsHandler(Class<In> inClass, Class<Out> outClass)
  • Method Details

    • 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, Object msg) throws Exception
      Specified by:
      channelRead in interface io.netty.channel.ChannelInboundHandler
      Overrides:
      channelRead in class io.netty.channel.ChannelInboundHandlerAdapter
      Throws:
      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 Exception
      Specified by:
      channelReadComplete in interface io.netty.channel.ChannelInboundHandler
      Overrides:
      channelReadComplete in class io.netty.channel.ChannelInboundHandlerAdapter
      Throws:
      Exception
    • write

      public void write(io.netty.channel.ChannelHandlerContext ctx, Object msg, io.netty.channel.ChannelPromise promise) throws Exception
      Specified by:
      write in interface io.netty.channel.ChannelOutboundHandler
      Overrides:
      write in class io.netty.channel.ChannelDuplexHandler
      Throws:
      Exception
    • unbufferedWrite

      protected void unbufferedWrite(io.netty.channel.ChannelHandlerContext ctx, HttpStreamsHandler<In,Out>.Outgoing out)
    • completeBody

      private void completeBody(io.netty.channel.ChannelHandlerContext ctx)
    • removeHandlerIfActive

      private void removeHandlerIfActive(io.netty.channel.ChannelHandlerContext ctx, 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, Runnable runnable)