All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.netty.springboot.server.HttpServletProtocolSpringAdapter Maven / Gradle / Ivy

The newest version!
package com.github.netty.springboot.server;

import com.github.netty.core.AbstractNettyServer;
import com.github.netty.core.util.LoggerFactoryX;
import com.github.netty.core.util.LoggerX;
import com.github.netty.core.util.StringUtil;
import com.github.netty.protocol.HttpServletProtocol;
import com.github.netty.protocol.servlet.*;
import com.github.netty.protocol.servlet.util.Protocol;
import com.github.netty.springboot.NettyProperties;
import com.github.netty.springboot.SpringUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.ssl.SslContextBuilder;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
import org.springframework.boot.web.server.*;
import org.springframework.util.ClassUtils;

import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

/**
 * HttpServlet protocol registry (spring adapter)
 *
 * @author wangzihao
 * 2018/11/12/012
 */
public class HttpServletProtocolSpringAdapter extends HttpServletProtocol {
    private static final LoggerX LOGGER = LoggerFactoryX.getLogger(HttpServletProtocol.class);
    private final NettyProperties properties;
    private Supplier serverPropertiesSupplier;
    private Supplier multipartPropertiesSupplier;

    public HttpServletProtocolSpringAdapter(NettyProperties properties, ClassLoader classLoader,
                                            Supplier executorSupplier, Supplier defaultExecutorSupplier) {
        super(new ServletContext(classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader), executorSupplier, defaultExecutorSupplier);
        this.properties = properties;
    }

    public void setMultipartPropertiesSupplier(Supplier multipartPropertiesSupplier) {
        this.multipartPropertiesSupplier = multipartPropertiesSupplier;
    }

    public void setServerPropertiesSupplier(Supplier serverPropertiesSupplier) {
        this.serverPropertiesSupplier = serverPropertiesSupplier;
    }

    /**
     * skip for {@link NettyRequestUpgradeStrategy}
     *
     * @param ctx     netty ctx
     * @param request netty request
     * @see NettyRequestUpgradeStrategy the handler
     */
    @Override
    public void upgradeWebsocket(ChannelHandlerContext ctx, HttpRequest request) {
        // for spring upgradeWebsocket NettyRequestUpgradeStrategy
        ChannelPipeline pipeline = ctx.pipeline();
        addServletPipeline(pipeline, Protocol.http1_1);
        pipeline.fireChannelRegistered();
        pipeline.fireChannelActive();
        pipeline.fireChannelRead(request);
    }

    @Override
    public  void onServerStart(T server) throws Exception {
        initializerStartup();

        ServletContext servletContext = getServletContext();

        LOGGER.info("Netty servlet on port: {}, with context path '{}'",
                servletContext.getServerAddress().getPort(),
                servletContext.getContextPath()
        );
//        application.scanner("com.github.netty").inject();
    }


    public void configurableServletContext(NettyTcpServerFactory webServerFactory) throws Exception {
        ServletContext servletContext = getServletContext();
        ServerProperties serverProperties = serverPropertiesSupplier != null ? serverPropertiesSupplier.get() : null;
        MultipartProperties multipartProperties = multipartPropertiesSupplier != null ? multipartPropertiesSupplier.get() : null;
        NettyProperties.HttpServlet httpServlet = properties.getHttpServlet();

        InetSocketAddress address = NettyTcpServerFactory.getServerSocketAddress(webServerFactory.getAddress(), webServerFactory.getPort());
        //Server port
        servletContext.setServerAddress(address);
        servletContext.setEnableLookupFlag(httpServlet.isEnableNsLookup());
        servletContext.setAutoFlush(httpServlet.getAutoFlushIdleMs() > 0);
        servletContext.setUploadFileTimeoutMs(httpServlet.getUploadFileTimeoutMs());
        servletContext.setContextPath(webServerFactory.getContextPath());
        servletContext.setServerHeader(webServerFactory.getServerHeader());
        servletContext.setServletContextName(webServerFactory.getDisplayName());
        servletContext.getErrorPageManager().setShowErrorMessage(httpServlet.isShowExceptionMessage());
        //Session timeout
        servletContext.setSessionTimeout((int) webServerFactory.getSession().getTimeout().getSeconds());
        servletContext.setSessionService(newSessionService(properties, servletContext));
        for (MimeMappings.Mapping mapping : webServerFactory.getMimeMappings()) {
            servletContext.getMimeMappings().add(mapping.getExtension(), mapping.getMimeType());
        }
        servletContext.getNotExistBodyParameters().addAll(Arrays.asList(httpServlet.getNotExistBodyParameter()));

        Compression compression = webServerFactory.getCompression();
        if (compression != null && compression.getEnabled()) {
            super.setEnableContentCompression(compression.getEnabled());
            super.setContentSizeThreshold((SpringUtil.getNumberBytes(compression, "getMinResponseSize")).intValue());
            super.setCompressionMimeTypes(compression.getMimeTypes().clone());
        }
        if (serverProperties != null) {
            super.setMaxHeaderSize((SpringUtil.getNumberBytes(serverProperties, "getMaxHttpHeaderSize")).intValue());
        }
        Boolean enableH2 = httpServlet.getEnableH2();
        if (enableH2 == null) {
            enableH2 = webServerFactory.getHttp2().isEnabled();
        }
        // https2
        super.setEnableH2(enableH2);
        // http2
        super.setEnableH2c(httpServlet.isEnableH2c());
        // ws
        super.setEnableWebsocket(httpServlet.isEnableWebsocket());
        // https, wss
        Ssl ssl = webServerFactory.getSsl();
        if (ssl != null && ssl.isEnabled()) {
            SslStoreProvider sslStoreProvider = webServerFactory.getSslStoreProvider();
            SslContextBuilder sslContextBuilder = SpringUtil.newSslContext(ssl, sslStoreProvider);
            super.setSslContextBuilder(sslContextBuilder);
        }

        String location = null;
        if (multipartProperties != null && multipartProperties.getEnabled()) {
            Number maxRequestSize = SpringUtil.getNumberBytes(multipartProperties, "getMaxRequestSize");
            Number fileSizeThreshold = SpringUtil.getNumberBytes(multipartProperties, "getFileSizeThreshold");

            super.setMaxChunkSize(maxRequestSize.longValue());
            servletContext.setFileSizeThreshold(fileSizeThreshold.longValue());
            location = multipartProperties.getLocation();
        }

        if (location != null && !location.isEmpty()) {
            servletContext.setDocBase(location, "");
        } else {
            servletContext.setDocBase(webServerFactory.getDocumentRoot().getAbsolutePath());
        }

        //Error page
        for (ErrorPage errorPage : webServerFactory.getErrorPages()) {
            ServletErrorPage servletErrorPage = new ServletErrorPage(errorPage.getStatusCode(), errorPage.getException(), errorPage.getPath());
            servletContext.getErrorPageManager().add(servletErrorPage);
        }
    }

    /**
     * New session service
     *
     * @param properties     properties
     * @param servletContext servletContext
     * @return SessionService
     */
    protected SessionService newSessionService(NettyProperties properties, ServletContext servletContext) {
        //Composite session (default local storage)
        SessionService sessionService;
        NettyProperties.HttpServlet httpServlet = properties.getHttpServlet();
        if (StringUtil.isNotEmpty(httpServlet.getSessionRemoteServerAddress())) {
            //Enable session remote storage using RPC
            String remoteSessionServerAddress = httpServlet.getSessionRemoteServerAddress();
            InetSocketAddress address;
            if (remoteSessionServerAddress.contains(":")) {
                String[] addressArr = remoteSessionServerAddress.split(":");
                address = new InetSocketAddress(addressArr[0], Integer.parseInt(addressArr[1]));
            } else {
                address = new InetSocketAddress(remoteSessionServerAddress, 80);
            }
            SessionCompositeServiceImpl compositeSessionService = new SessionCompositeServiceImpl(servletContext);
            compositeSessionService.enableRemoteRpcSession(address,
                    80,
                    1,
                    properties.getNrpc().isClientEnableHeartLog(),
                    properties.getNrpc().getClientHeartIntervalTimeMs(),
                    properties.getNrpc().getClientReconnectScheduledIntervalMs());
            sessionService = compositeSessionService;
        } else if (httpServlet.isEnablesLocalFileSession()) {
            //Enable session file storage
            sessionService = new SessionLocalFileServiceImpl(servletContext.getResourceManager(), servletContext);
        } else {
            sessionService = new SessionLocalMemoryServiceImpl(servletContext);
        }
        return sessionService;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy