/* * Copyright 2015 Netflix, Inc. * * 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.reactivex.netty.protocol.http.server; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.logging.LogLevel; import io.netty.util.concurrent.EventExecutorGroup; import io.reactivex.netty.protocol.http.HttpHandlerNames; import io.reactivex.netty.protocol.http.server.events.HttpServerEventPublisher; import io.reactivex.netty.protocol.http.server.events.HttpServerEventsListener; import io.reactivex.netty.protocol.http.ws.server.Ws7To13UpgradeHandler; import io.reactivex.netty.protocol.tcp.server.TcpServer; import io.reactivex.netty.ssl.SslCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rx.Subscription; import rx.functions.Action1; import rx.functions.Func0; import rx.functions.Func1; import rx.subscriptions.CompositeSubscription; import javax.net.ssl.SSLEngine; import java.net.SocketAddress; import java.util.concurrent.TimeUnit; public final class HttpServerImpl<I, O> extends HttpServer<I, O> { private static final Logger logger = LoggerFactory.getLogger(HttpServerImpl.class); private final TcpServer<HttpServerRequest<I>, Object> server; private final HttpServerEventPublisher eventPublisher; private boolean sendHttp10ResponseFor10Request; private HttpServerImpl(TcpServer<HttpServerRequest<I>, Object> server, HttpServerEventPublisher eventPublisher) { this.server = server; this.eventPublisher = eventPublisher; } @Override public <T> HttpServer<I, O> channelOption(ChannelOption<T> option, T value) { return _copy(server.channelOption(option, value), eventPublisher); } @Override public <T> HttpServer<I, O> clientChannelOption(ChannelOption<T> option, T value) { return _copy(server.clientChannelOption(option, value), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerFirst(String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerFirst(name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerFirst(EventExecutorGroup group, String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerFirst(group, name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerLast(String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerLast(name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerLast(EventExecutorGroup group, String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerLast(group, name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerBefore(String baseName, String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerBefore(baseName, name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerBefore(EventExecutorGroup group, String baseName, String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerBefore(group, baseName, name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerAfter(String baseName, String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerAfter(baseName, name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> addChannelHandlerAfter(EventExecutorGroup group, String baseName, String name, Func0<ChannelHandler> handlerFactory) { return _copy(HttpServerImpl.<II>castServer(server.addChannelHandlerAfter(group, baseName, name, handlerFactory)), eventPublisher); } @Override public <II, OO> HttpServer<II, OO> pipelineConfigurator(Action1<ChannelPipeline> pipelineConfigurator) { return _copy(HttpServerImpl.<II>castServer(server.pipelineConfigurator(pipelineConfigurator)), eventPublisher); } @Override public HttpServer<I, O> secure(Func1<ByteBufAllocator, SSLEngine> sslEngineFactory) { return _copy(server.secure(sslEngineFactory), eventPublisher); } @Override public HttpServer<I, O> secure(SSLEngine sslEngine) { return _copy(server.secure(sslEngine), eventPublisher); } @Override public HttpServer<I, O> secure(SslCodec sslCodec) { return _copy(server.secure(sslCodec), eventPublisher); } @Override public HttpServer<I, O> unsafeSecure() { return _copy(server.unsafeSecure(), eventPublisher); } @Override @Deprecated public HttpServer<I, O> enableWireLogging(LogLevel wireLoggingLevel) { return _copy(server.enableWireLogging(wireLoggingLevel), eventPublisher); } @Override public HttpServer<I, O> enableWireLogging(String name, LogLevel wireLoggingLevel) { return _copy(server.enableWireLogging(name, wireLoggingLevel), eventPublisher); } @Override public HttpServer<I, O> sendHttp10ResponseFor10Request(boolean sendHttp10ResponseFor10Request) { HttpServerImpl<I, O> toReturn = _copy(server, eventPublisher); toReturn.sendHttp10ResponseFor10Request = sendHttp10ResponseFor10Request; return toReturn; } @Override public int getServerPort() { return server.getServerPort(); } @Override public SocketAddress getServerAddress() { return server.getServerAddress(); } @Override public HttpServer<I, O> start(RequestHandler<I, O> requestHandler) { server.start(new HttpConnectionHandler<>(requestHandler, eventPublisher, sendHttp10ResponseFor10Request)); return this; } @Override public void shutdown() { server.shutdown(); } @Override public void awaitShutdown() { server.awaitShutdown(); } @Override public void awaitShutdown(long duration, TimeUnit timeUnit) { server.awaitShutdown(duration, timeUnit); } static HttpServer<ByteBuf, ByteBuf> create(final TcpServer<ByteBuf, ByteBuf> tcpServer) { final HttpServerEventPublisher eventPublisher = new HttpServerEventPublisher(tcpServer.getEventPublisher()); return new HttpServerImpl<>( tcpServer.<HttpServerRequest<ByteBuf>, Object>pipelineConfigurator(new Action1<ChannelPipeline>() { @Override public void call(ChannelPipeline pipeline) { pipeline.addLast(HttpHandlerNames.HttpServerEncoder.getName(), new HttpResponseEncoder()); pipeline.addLast(HttpHandlerNames.HttpServerDecoder.getName(), new HttpRequestDecoder()); pipeline.addLast(HttpHandlerNames.WsServerUpgradeHandler.getName(), new Ws7To13UpgradeHandler()); pipeline.addLast(new HttpServerToConnectionBridge<>(eventPublisher)); } }), eventPublisher); } @SuppressWarnings("unchecked") private static <II> TcpServer<HttpServerRequest<II>, Object> castServer(TcpServer<?, ?> rawTypes) { return (TcpServer<HttpServerRequest<II>, Object>)rawTypes; } private static <II, OO> HttpServerImpl<II, OO> _copy(TcpServer<HttpServerRequest<II>, Object> newServer, HttpServerEventPublisher oldEventPublisher) { return new HttpServerImpl<>(newServer, oldEventPublisher.copy(newServer.getEventPublisher())); } @Override public Subscription subscribe(HttpServerEventsListener listener) { final CompositeSubscription cs = new CompositeSubscription(); cs.add(server.subscribe(listener)); cs.add(eventPublisher.subscribe(listener)); return cs; } }