io.werval.server.netty.HttpServerChannelInitializer.java Source code

Java tutorial

Introduction

Here is the source code for io.werval.server.netty.HttpServerChannelInitializer.java

Source

/*
 * Copyright (c) 2013-2014 the original author or authors
 *
 * Licensed 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.werval.server.netty;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.HttpContentDecompressor;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import io.werval.api.events.ConnectionEvent;
import io.werval.spi.ApplicationSPI;
import io.werval.spi.dev.DevShellSPI;
import java.net.InetSocketAddress;

import static java.util.Locale.US;
import static java.util.concurrent.TimeUnit.SECONDS;
import static io.werval.runtime.ConfigKeys.WERVAL_HTTP_LOG_LOWLEVEL_ENABLED;
import static io.werval.runtime.ConfigKeys.WERVAL_HTTP_LOG_LOWLEVEL_LEVEL;
import static io.werval.runtime.ConfigKeys.WERVAL_HTTP_TIMEOUT_READ;
import static io.werval.runtime.ConfigKeys.WERVAL_HTTP_TIMEOUT_WRITE;

/* package */ class HttpServerChannelInitializer extends ChannelInitializer<Channel> {
    private final ChannelGroup allChannels;
    private final ApplicationSPI app;
    private final DevShellSPI devSpi;

    /* package */ HttpServerChannelInitializer(ChannelGroup allChannels, ApplicationSPI httpApp,
            DevShellSPI devSpi) {
        this.allChannels = allChannels;
        this.app = httpApp;
        this.devSpi = devSpi;
    }

    @Override
    public void initChannel(Channel channel) {
        ChannelPipeline pipeline = channel.pipeline();

        // Connection Events
        String remoteHostString = ((InetSocketAddress) channel.remoteAddress()).getHostString();
        app.events().emit(new ConnectionEvent.Opened(remoteHostString));
        channel.closeFuture()
                .addListener(future -> app.events().emit(new ConnectionEvent.Closed(remoteHostString)));

        if (app.config().bool(WERVAL_HTTP_LOG_LOWLEVEL_ENABLED)) {
            // Log Netty Bytes
            LogLevel level = LogLevel.valueOf(app.config().string(WERVAL_HTTP_LOG_LOWLEVEL_LEVEL).toUpperCase(US));
            pipeline.addLast("byte-logging", new LoggingHandler("io.werval.server.netty.LowLevelLogger", level));
        }

        // Read/Write Timeout
        long readTimeout = app.config().seconds(WERVAL_HTTP_TIMEOUT_READ);
        long writeTimeout = app.config().seconds(WERVAL_HTTP_TIMEOUT_WRITE);
        pipeline.addLast("read-timeout", new ReadTimeoutHandler(readTimeout, SECONDS));
        pipeline.addLast("write-timeout", new WriteTimeoutHandler(writeTimeout, SECONDS));

        // HTTP Decoding / Encoding
        // HTTP decoders always generates multiple message objects per a single HTTP message:
        //
        //  1       * HttpRequest / HttpResponse
        //  0 - n   * HttpContent
        //  1       * LastHttpContent
        //
        // or a single FullHttpRequest if a handler ask for it
        pipeline.addLast("http-codec", new HttpServerCodec());

        // GZip decompression support
        pipeline.addLast("http-decompressor", new HttpContentDecompressor());

        // Allow to send chunked data
        pipeline.addLast("chunked-write-handler", new ChunkedWriteHandler());

        // Protocol Switching Handler
        pipeline.addLast("subprotocol-switcher", new SubProtocolSwitchHandler(allChannels, app, devSpi));
    }
}