Class HttpStreamsClientHandler

java.lang.Object
io.netty.channel.ChannelHandlerAdapter
io.netty.channel.ChannelInboundHandlerAdapter
io.netty.channel.ChannelDuplexHandler
io.micronaut.http.netty.stream.HttpStreamsClientHandler
All Implemented Interfaces:
io.netty.channel.ChannelHandler, io.netty.channel.ChannelInboundHandler, io.netty.channel.ChannelOutboundHandler

@Internal public class HttpStreamsClientHandler extends io.netty.channel.ChannelDuplexHandler
Handler that converts written StreamedHttpRequest messages into HttpRequest messages followed by HttpContent messages and reads HttpResponse messages followed by HttpContent messages and produces StreamedHttpResponse messages.

This allows request and response bodies to be handled using reactive streams.

There are two types of messages that this handler accepts for writing, StreamedHttpRequest and FullHttpRequest. Writing any other messages may potentially lead to HTTP message mangling.

There are two types of messages that this handler will send down the chain, StreamedHttpResponse, and FullHttpResponse. If ChannelOption.AUTO_READ is false for the channel, then any StreamedHttpResponse messages must be subscribed to consume the body, otherwise it's possible that no read will be done of the messages.

As long as messages are returned in the order that they arrive, this handler implicitly supports HTTP pipelining.

Since:
1.0
Author:
jroper, Graeme Rocher
  • Nested Class Summary

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

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

    Fields
    Modifier and Type
    Field
    Description
    static final String
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    Default constructor.
  • 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)
     
    void
    channelWritabilityChanged(io.netty.channel.ChannelHandlerContext ctx)
     
    void
    close(io.netty.channel.ChannelHandlerContext ctx, io.netty.channel.ChannelPromise future)
     
    protected void
    consumedInMessage(io.netty.channel.ChannelHandlerContext ctx)
    Invoked when an incoming message is fully consumed.
    protected io.netty.handler.codec.http.HttpResponse
    createEmptyMessage(io.netty.handler.codec.http.HttpResponse response)
    Create an empty incoming message.
    protected io.netty.handler.codec.http.HttpResponse
    createStreamedMessage(io.netty.handler.codec.http.HttpResponse response, Publisher<? extends io.netty.handler.codec.http.HttpContent> stream)
    Create a streamed incoming message with the given stream.
    protected boolean
    hasBody(io.netty.handler.codec.http.HttpResponse response)
    Whether the given incoming message has a body.
    protected final boolean
     
    protected boolean
     
    protected boolean
     
    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.
    protected void
    sentOutMessage(io.netty.channel.ChannelHandlerContext ctx)
    Invoked when an outgoing message is fully sent.
    protected void
    subscribeSubscriberToStream(StreamedHttpMessage msg, 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, io.netty.handler.codec.http.HttpRequest message, io.netty.channel.ChannelPromise promise)
     
    void
    write(io.netty.channel.ChannelHandlerContext ctx, Object msg, io.netty.channel.ChannelPromise promise)
     

    Methods inherited from class io.netty.channel.ChannelDuplexHandler

    bind, connect, deregister, disconnect, flush, read

    Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter

    channelActive, channelInactive, channelRegistered, channelUnregistered, 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

  • Constructor Details

    • HttpStreamsClientHandler

      public HttpStreamsClientHandler()
      Default constructor.
  • Method Details

    • hasBody

      protected boolean hasBody(io.netty.handler.codec.http.HttpResponse response)
      Whether the given incoming message has a body.
      Parameters:
      response - The incoming message
      Returns:
      Whether the incoming message has body
    • close

      public void close(io.netty.channel.ChannelHandlerContext ctx, io.netty.channel.ChannelPromise future) throws Exception
      Specified by:
      close in interface io.netty.channel.ChannelOutboundHandler
      Overrides:
      close in class io.netty.channel.ChannelDuplexHandler
      Throws:
      Exception
    • consumedInMessage

      protected void consumedInMessage(io.netty.channel.ChannelHandlerContext ctx)
      Invoked when an incoming message is fully consumed.

      Overridden by subclasses for state tracking.

      Parameters:
      ctx - The channel handler context
    • receivedOutMessage

      protected void receivedOutMessage(io.netty.channel.ChannelHandlerContext ctx)
      Invoked when an outgoing message is first received.

      Overridden by subclasses for state tracking.

      Parameters:
      ctx - The channel handler context
    • sentOutMessage

      protected void sentOutMessage(io.netty.channel.ChannelHandlerContext ctx)
      Invoked when an outgoing message is fully sent.

      Overridden by subclasses for state tracking.

      Parameters:
      ctx - The channel handler context
    • createEmptyMessage

      protected io.netty.handler.codec.http.HttpResponse createEmptyMessage(io.netty.handler.codec.http.HttpResponse response)
      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.
      Parameters:
      response - The incoming message
      Returns:
      An empty incoming message
    • createStreamedMessage

      protected io.netty.handler.codec.http.HttpResponse createStreamedMessage(io.netty.handler.codec.http.HttpResponse response, Publisher<? extends io.netty.handler.codec.http.HttpContent> stream)
      Create a streamed incoming message with the given stream.
      Parameters:
      response - The incoming message
      stream - The publisher for the Http Content
      Returns:
      A streamed incoming message
    • subscribeSubscriberToStream

      protected void subscribeSubscriberToStream(StreamedHttpMessage msg, 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.

      Parameters:
      msg - The streamed Http message
      subscriber - The subscriber for the Http Content
    • isClient

      protected final boolean isClient()
      Returns:
      Whether this is the client stream handler.
    • channelRead

      public void channelRead(io.netty.channel.ChannelHandlerContext ctx, Object msg) throws Exception
      Specified by:
      channelRead in interface io.netty.channel.ChannelInboundHandler
      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
      Throws:
      Exception
    • receivedInMessage

      protected void receivedInMessage(io.netty.channel.ChannelHandlerContext ctx)
      Invoked when an incoming message is first received.

      Overridden by subclasses for state tracking.

      Parameters:
      ctx - The channel handler context
    • 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.

      Parameters:
      ctx - The channel handler context
    • 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
    • channelWritabilityChanged

      public void channelWritabilityChanged(io.netty.channel.ChannelHandlerContext ctx)
      Specified by:
      channelWritabilityChanged in interface io.netty.channel.ChannelInboundHandler
      Overrides:
      channelWritabilityChanged in class io.netty.channel.ChannelInboundHandlerAdapter
    • unbufferedWrite

      protected void unbufferedWrite(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpRequest message, io.netty.channel.ChannelPromise promise)
      Parameters:
      ctx - The channel handler context
      message - The message
      promise - The promise
    • isValidOutMessage

      protected boolean isValidOutMessage(Object msg)
      Parameters:
      msg - The message
      Returns:
      True if the handler should write the message
    • isValidInMessage

      protected boolean isValidInMessage(Object msg)
      Parameters:
      msg - The message
      Returns:
      True if the handler should read the message