content: /*
   * Copyright 2015 The Netty Project
   *
   * The Netty 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 io.bitchat.http.router;
  
  import io.netty.channel.ChannelHandler.Sharable;
  import io.netty.channel.ChannelHandlerContext;
  import io.netty.channel.SimpleChannelInboundHandler;
  import io.netty.handler.codec.http.LastHttpContent;
  import io.netty.util.internal.logging.InternalLogger;
  import io.netty.util.internal.logging.InternalLoggerFactory;
  
  /**
   * This utility handler should be put at the last position of the inbound pipeline to
   * catch all exceptions caused by bad client (closed connection, malformed request etc.)
   * and server processing, then close the connection.
   *
   * By default exceptions are logged to Netty internal LOGGER. You may need to override
   * {@link #onUnknownMessage(Object)}, {@link #onBadClient(Throwable)}, and
   * {@link #onBadServer(Throwable)} to log to more suitable places.
   */
  @Sharable
  public class BadClientSilencer extends SimpleChannelInboundHandler<Object> {
      private static final InternalLogger log = InternalLoggerFactory.getInstance(BadClientSilencer.class);
  
      /** Logs to Netty internal LOGGER. Override this method to log to other places if you want. */
      protected void onUnknownMessage(Object msg) {
          log.warn("Unknown msg: " + msg);
      }
  
      /** Logs to Netty internal LOGGER. Override this method to log to other places if you want. */
      protected void onBadClient(Throwable e) {
          log.warn("Caught exception (maybe client is bad)", e);
      }
  
      /** Logs to Netty internal LOGGER. Override this method to log to other places if you want. */
      protected void onBadServer(Throwable e) {
          log.warn("Caught exception (maybe server is bad)", e);
      }
  
      //----------------------------------------------------------------------------
  
      @Override
      public void channelRead0(ChannelHandlerContext ctx, Object msg) {
          // This handler is the last inbound handler.
          // This means msg has not been handled by any previous handler.
          ctx.close();
  
          if (msg != LastHttpContent.EMPTY_LAST_CONTENT) {
              onUnknownMessage(msg);
          }
      }
  
      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {
          ctx.close();
  
          // To clarify where exceptions are from, imports are not used
          if (e instanceof java.io.IOException                            ||  // Connection reset by peer, Broken pipe
              e instanceof java.nio.channels.ClosedChannelException       ||
              e instanceof io.netty.handler.codec.DecoderException        ||
              e instanceof io.netty.handler.codec.CorruptedFrameException ||  // Bad WebSocket frame
              e instanceof IllegalArgumentException             ||  // Use https://... to connect to HTTP server
              e instanceof javax.net.ssl.SSLException                     ||  // Use http://... to connect to HTTPS server
              e instanceof io.netty.handler.ssl.NotSslRecordException) {
              onBadClient(e);  // Maybe client is bad
          } else {
              onBadServer(e);  // Maybe server is bad
          }
      }
  }
  