apple / swift-nio

Event-driven network application framework for high performance protocol servers & clients, non-blocking.
https://swiftpackageindex.com/apple/swift-nio/documentation
Apache License 2.0
7.98k stars 650 forks source link

Forward/relay request #638

Closed purkylin closed 6 years ago

purkylin commented 6 years ago

I want to implement a socks proxy and I have look Netty source code. But I don't know how to forward/repay request like Netty, can someone give me some tips?

Promise<Channel> promise = ctx.executor().newPromise();
            promise.addListener(
                    new FutureListener<Channel>() {
                        @Override
                        public void operationComplete(final Future<Channel> future) throws Exception {
                            final Channel outboundChannel = future.getNow();
                            if (future.isSuccess()) {
                                ChannelFuture responseFuture =
                                        ctx.channel().writeAndFlush(new DefaultSocks5CommandResponse(
                                                Socks5CommandStatus.SUCCESS,
                                                request.dstAddrType(),
                                                request.dstAddr(),
                                                request.dstPort()));

                                responseFuture.addListener(new ChannelFutureListener() {
                                    @Override
                                    public void operationComplete(ChannelFuture channelFuture) {
                                        ctx.pipeline().remove(SocksServerConnectHandler.this);
                                        outboundChannel.pipeline().addLast(new RelayHandler(ctx.channel()));
                                        ctx.pipeline().addLast(new RelayHandler(outboundChannel));
                                    }
                                });
                            } else {
                                ctx.channel().writeAndFlush(new DefaultSocks5CommandResponse(
                                        Socks5CommandStatus.FAILURE, request.dstAddrType()));
                                SocksServerUtils.closeOnFlush(ctx.channel());
                            }
                        }
                    });
Lukasa commented 6 years ago

Right now SwiftNIO does not have special hooks for relaying data from one channel to another. However, such a thing is fairly trivial to write for HTTP.

Note that even with an appropriate relay handler, you'll still need a SOCKS server handler, which NIO does not currently ship either.

purkylin commented 6 years ago

Thanks. Any plan to support it or is’t possible without modify the code of nio

Lukasa commented 6 years ago

Both of these things can absolutely be written without modifying the NIO code. SOCKS is a fairly straightforward proxy protocol that can be written as a single ChannelHandler, and the relay code is also fairly straightforward. Both of these things may eventually end up in swift-nio-extras, but they are low-priority so unless the community contributes them I recommend building them yourself.

normanmaurer commented 6 years ago

+1... this sounds like something for swift-nio-extras contributed by the community :)

AlanQuatermain commented 6 years ago

/me looks up the relevant RFCs…