Search in sources :

Example 1 with ApnProxyRemote

use of com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote in project apn-proxy by apn-proxy.

the class ApnProxyTunnelChannelInitializer method initChannel.

/**
     * @see io.netty.channel.ChannelInitializer#initChannel(io.netty.channel.Channel)
     */
@Override
protected void initChannel(SocketChannel channel) throws Exception {
    ApnProxyRemote apnProxyRemote = uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get().getRemote();
    channel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).set(uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get());
    ChannelPipeline pipeline = channel.pipeline();
    pipeline.addLast("idlestate", new IdleStateHandler(0, 0, 3, TimeUnit.MINUTES));
    pipeline.addLast("idlehandler", new ApnProxyIdleHandler());
    if (apnProxyRemote.getRemoteListenType() == ApnProxyListenType.SSL) {
        SSLEngine engine = ApnProxySSLContextFactory.createClientSSLEnginForRemoteAddress(apnProxyRemote.getRemoteHost(), apnProxyRemote.getRemotePort());
        engine.setUseClientMode(true);
        pipeline.addLast("ssl", new SslHandler(engine));
    } else if (apnProxyRemote.getRemoteListenType() == ApnProxyListenType.AES) {
        byte[] key = ((ApnProxyAESRemote) apnProxyRemote).getKey();
        byte[] iv = ((ApnProxyAESRemote) apnProxyRemote).getIv();
        pipeline.addLast("apnproxy.encrypt", new ApnProxyAESEncoder(key, iv));
        pipeline.addLast("apnproxy.decrypt", new ApnProxyAESDecoder(key, iv));
    }
    if (apnProxyRemote.getRemoteListenType() == ApnProxyListenType.PLAIN) {
    // nothing to do
    }
    pipeline.addLast(new ApnProxyRelayHandler(apnProxyRemote.getRemoteAddr() + " --> UA", uaChannel));
}
Also used : SSLEngine(javax.net.ssl.SSLEngine) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) ApnProxyRemote(com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote) ChannelPipeline(io.netty.channel.ChannelPipeline) SslHandler(io.netty.handler.ssl.SslHandler)

Example 2 with ApnProxyRemote

use of com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote in project apn-proxy by apn-proxy.

the class ApnProxyUserAgentForwardHandler method channelRead.

@Override
public void channelRead(final ChannelHandlerContext uaChannelCtx, final Object msg) throws Exception {
    final Channel uaChannel = uaChannelCtx.channel();
    final ApnProxyRemote apnProxyRemote = uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get().getRemote();
    if (msg instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) msg;
        Channel remoteChannel = remoteChannelMap.get(apnProxyRemote.getRemoteAddr());
        if (remoteChannel != null && remoteChannel.isActive()) {
            LoggerUtil.debug(logger, uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY), "Use old remote channel");
            HttpRequest request = constructRequestForProxy(httpRequest, apnProxyRemote);
            remoteChannel.writeAndFlush(request);
        } else {
            LoggerUtil.debug(logger, uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY), "Create new remote channel");
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(uaChannel.eventLoop()).channel(NioSocketChannel.class).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000).option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT).option(ChannelOption.AUTO_READ, false).handler(new ApnProxyRemoteForwardChannelInitializer(uaChannel, this));
            // set local address
            if (StringUtils.isNotBlank(ApnProxyLocalAddressChooser.choose(apnProxyRemote.getRemoteHost()))) {
                bootstrap.localAddress(new InetSocketAddress((ApnProxyLocalAddressChooser.choose(apnProxyRemote.getRemoteHost())), 0));
            }
            ChannelFuture remoteConnectFuture = bootstrap.connect(apnProxyRemote.getRemoteHost(), apnProxyRemote.getRemotePort());
            remoteChannel = remoteConnectFuture.channel();
            remoteChannelMap.put(apnProxyRemote.getRemoteAddr(), remoteChannel);
            remoteConnectFuture.addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (future.isSuccess()) {
                        future.channel().write(constructRequestForProxy((HttpRequest) msg, apnProxyRemote));
                        for (HttpContent hc : httpContentBuffer) {
                            future.channel().writeAndFlush(hc);
                            if (hc instanceof LastHttpContent) {
                                future.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(new ChannelFutureListener() {

                                    @Override
                                    public void operationComplete(ChannelFuture future) throws Exception {
                                        if (future.isSuccess()) {
                                            future.channel().read();
                                        }
                                    }
                                });
                            }
                        }
                        httpContentBuffer.clear();
                    } else {
                        LoggerUtil.error(logger, uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY), "Remote channel create fail");
                        // send error response
                        String errorMsg = "remote connect to " + uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get().getRemote().getRemoteAddr() + " fail";
                        HttpMessage errorResponseMsg = HttpErrorUtil.buildHttpErrorMessage(HttpResponseStatus.INTERNAL_SERVER_ERROR, errorMsg);
                        uaChannel.writeAndFlush(errorResponseMsg);
                        httpContentBuffer.clear();
                        future.channel().close();
                    }
                }
            });
        }
        ReferenceCountUtil.release(msg);
    } else {
        Channel remoteChannel = remoteChannelMap.get(apnProxyRemote.getRemoteAddr());
        HttpContent hc = ((HttpContent) msg);
        if (remoteChannel != null && remoteChannel.isActive()) {
            remoteChannel.writeAndFlush(hc);
            if (hc instanceof LastHttpContent) {
                remoteChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(new ChannelFutureListener() {

                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        if (future.isSuccess()) {
                            future.channel().read();
                        }
                    }
                });
            }
        } else {
            httpContentBuffer.add(hc);
        }
    }
}
Also used : InetSocketAddress(java.net.InetSocketAddress) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) ApnProxyRemote(com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Bootstrap(io.netty.bootstrap.Bootstrap)

Example 3 with ApnProxyRemote

use of com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote in project apn-proxy by apn-proxy.

the class ApnProxyUserAgentTunnelHandler method channelRead.

@Override
public void channelRead(final ChannelHandlerContext uaChannelCtx, Object msg) throws Exception {
    if (msg instanceof HttpRequest) {
        final HttpRequest httpRequest = (HttpRequest) msg;
        //Channel uaChannel = uaChannelCtx.channel();
        // connect remote
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(uaChannelCtx.channel().eventLoop()).channel(NioSocketChannel.class).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000).option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT).option(ChannelOption.AUTO_READ, false).handler(new ApnProxyTunnelChannelInitializer(uaChannelCtx.channel()));
        final ApnProxyRemote apnProxyRemote = uaChannelCtx.channel().attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get().getRemote();
        // set local address
        if (StringUtils.isNotBlank(ApnProxyLocalAddressChooser.choose(apnProxyRemote.getRemoteHost()))) {
            bootstrap.localAddress(new InetSocketAddress((ApnProxyLocalAddressChooser.choose(apnProxyRemote.getRemoteHost())), 0));
        }
        bootstrap.connect(apnProxyRemote.getRemoteHost(), apnProxyRemote.getRemotePort()).addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(final ChannelFuture future1) throws Exception {
                if (future1.isSuccess()) {
                    if (apnProxyRemote.isAppleyRemoteRule()) {
                        uaChannelCtx.pipeline().remove("codec");
                        uaChannelCtx.pipeline().remove(ApnProxyPreHandler.HANDLER_NAME);
                        uaChannelCtx.pipeline().remove(ApnProxyUserAgentTunnelHandler.HANDLER_NAME);
                        // add relay handler
                        uaChannelCtx.pipeline().addLast(new ApnProxyRelayHandler("UA --> Remote", future1.channel()));
                        future1.channel().writeAndFlush(Unpooled.copiedBuffer(constructConnectRequestForProxy(httpRequest, apnProxyRemote), CharsetUtil.UTF_8)).addListener(new ChannelFutureListener() {

                            @Override
                            public void operationComplete(ChannelFuture future2) throws Exception {
                                if (!future2.channel().config().getOption(ChannelOption.AUTO_READ)) {
                                    future2.channel().read();
                                }
                            }
                        });
                    } else {
                        HttpResponse proxyConnectSuccessResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(200, "Connection established"));
                        uaChannelCtx.writeAndFlush(proxyConnectSuccessResponse).addListener(new ChannelFutureListener() {

                            @Override
                            public void operationComplete(ChannelFuture future2) throws Exception {
                                // remove handlers
                                uaChannelCtx.pipeline().remove("codec");
                                uaChannelCtx.pipeline().remove(ApnProxyPreHandler.HANDLER_NAME);
                                uaChannelCtx.pipeline().remove(ApnProxyUserAgentTunnelHandler.HANDLER_NAME);
                                // add relay handler
                                uaChannelCtx.pipeline().addLast(new ApnProxyRelayHandler("UA --> " + apnProxyRemote.getRemoteAddr(), future1.channel()));
                            }
                        });
                    }
                } else {
                    if (uaChannelCtx.channel().isActive()) {
                        uaChannelCtx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
                    }
                }
            }
        });
    }
    ReferenceCountUtil.release(msg);
}
Also used : InetSocketAddress(java.net.InetSocketAddress) ApnProxyRemote(com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Bootstrap(io.netty.bootstrap.Bootstrap)

Example 4 with ApnProxyRemote

use of com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote in project apn-proxy by apn-proxy.

the class ApnProxyRemoteForwardChannelInitializer method initChannel.

@Override
public void initChannel(SocketChannel channel) throws Exception {
    ApnProxyRemote apnProxyRemote = uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get().getRemote();
    channel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).set(uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).get());
    ChannelPipeline pipeline = channel.pipeline();
    pipeline.addLast("idlestate", new IdleStateHandler(0, 0, 3, TimeUnit.MINUTES));
    pipeline.addLast("idlehandler", new ApnProxyIdleHandler());
    if (apnProxyRemote.getRemoteListenType() == ApnProxyListenType.SSL) {
        SSLEngine engine = ApnProxySSLContextFactory.createClientSSLEnginForRemoteAddress(apnProxyRemote.getRemoteHost(), apnProxyRemote.getRemotePort());
        engine.setUseClientMode(true);
        pipeline.addLast("ssl", new SslHandler(engine));
    } else if (apnProxyRemote.getRemoteListenType() == ApnProxyListenType.AES) {
        byte[] key = ((ApnProxyAESRemote) apnProxyRemote).getKey();
        byte[] iv = ((ApnProxyAESRemote) apnProxyRemote).getIv();
        pipeline.addLast("apnproxy.encrypt", new ApnProxyAESEncoder(key, iv));
        pipeline.addLast("apnproxy.decrypt", new ApnProxyAESDecoder(key, iv));
    }
    pipeline.addLast("codec", new HttpClientCodec());
    pipeline.addLast(ApnProxyRemoteForwardHandler.HANDLER_NAME, new ApnProxyRemoteForwardHandler(uaChannel, remoteChannelInactiveCallback));
}
Also used : SSLEngine(javax.net.ssl.SSLEngine) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) ApnProxyRemote(com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote) HttpClientCodec(io.netty.handler.codec.http.HttpClientCodec) ChannelPipeline(io.netty.channel.ChannelPipeline) SslHandler(io.netty.handler.ssl.SslHandler)

Example 5 with ApnProxyRemote

use of com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote in project apn-proxy by apn-proxy.

the class ApnProxySchemaHandler method channelRead.

@Override
public void channelRead(ChannelHandlerContext uaChannelCtx, final Object msg) throws Exception {
    if (msg instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) msg;
        String originalHost = HostNamePortUtil.getHostName(httpRequest);
        int originalPort = HostNamePortUtil.getPort(httpRequest);
        ApnProxyRemote apnProxyRemote = ApnProxyRemoteChooser.chooseRemoteAddr(originalHost, originalPort);
        Channel uaChannel = uaChannelCtx.channel();
        ApnProxyConnectionAttribute apnProxyConnectionAttribute = ApnProxyConnectionAttribute.build(uaChannel.remoteAddress().toString(), httpRequest.getMethod().name(), httpRequest.getUri(), httpRequest.getProtocolVersion().text(), httpRequest.headers().get(HttpHeaders.Names.USER_AGENT), apnProxyRemote);
        uaChannelCtx.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).set(apnProxyConnectionAttribute);
        uaChannel.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY).set(apnProxyConnectionAttribute);
        if (httpRequest.getMethod().equals(HttpMethod.CONNECT)) {
            if (uaChannelCtx.pipeline().get(ApnProxyUserAgentForwardHandler.HANDLER_NAME) != null) {
                uaChannelCtx.pipeline().remove(ApnProxyUserAgentForwardHandler.HANDLER_NAME);
            }
            if (uaChannelCtx.pipeline().get(ApnProxyUserAgentTunnelHandler.HANDLER_NAME) == null) {
                uaChannelCtx.pipeline().addLast(ApnProxyUserAgentTunnelHandler.HANDLER_NAME, new ApnProxyUserAgentTunnelHandler());
            }
        } else {
            if (uaChannelCtx.pipeline().get(ApnProxyUserAgentForwardHandler.HANDLER_NAME) == null) {
                uaChannelCtx.pipeline().addLast(ApnProxyUserAgentForwardHandler.HANDLER_NAME, new ApnProxyUserAgentForwardHandler());
            }
        }
    }
    LoggerUtil.debug(logger, uaChannelCtx.attr(ApnProxyConnectionAttribute.ATTRIBUTE_KEY), "UA msg", msg);
    uaChannelCtx.fireChannelRead(msg);
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) Channel(io.netty.channel.Channel) ApnProxyRemote(com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote)

Aggregations

ApnProxyRemote (com.xx_dev.apn.proxy.remotechooser.ApnProxyRemote)5 Bootstrap (io.netty.bootstrap.Bootstrap)2 ChannelPipeline (io.netty.channel.ChannelPipeline)2 SslHandler (io.netty.handler.ssl.SslHandler)2 IdleStateHandler (io.netty.handler.timeout.IdleStateHandler)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 InetSocketAddress (java.net.InetSocketAddress)2 SSLEngine (javax.net.ssl.SSLEngine)2 Channel (io.netty.channel.Channel)1 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)1 HttpClientCodec (io.netty.handler.codec.http.HttpClientCodec)1 HttpRequest (io.netty.handler.codec.http.HttpRequest)1