Git Product home page Git Product logo

proxyee's Introduction

Proxyee

maven license

English | 中文


Introduction

Proxyee is a JAVA written HTTP proxy server library that supports HTTP, HTTPS, Websocket protocols, and supports MITM (Man-in-the-middle), which can capture and tamper with HTTP, HTTPS packet.

Usage

<dependency>
    <groupId>com.github.monkeywie</groupId>
    <artifactId>proxyee</artifactId>
    <version>1.7.6</version>
</dependency>

Demo

  • Normal HTTP proxy
new HttpProxyServer().start(9999);
  • MITM HTTP proxy

The following is a demonstration of a MITM attack that modifies the response header and response body when visiting the Baidu homepage, as shown in the figure below:

20200724152245

Code:

HttpProxyServerConfig config =  new HttpProxyServerConfig();
//enable HTTPS support
//If not enabled, HTTPS will not be intercepted, but forwarded directly to the raw packet.
config.setHandleSsl(true);
new HttpProxyServer()
    .serverConfig(config)
    .proxyInterceptInitializer(new HttpProxyInterceptInitializer() {
      @Override
      public void init(HttpProxyInterceptPipeline pipeline) {
        pipeline.addLast(new FullResponseIntercept() {

          @Override
          public boolean match(HttpRequest httpRequest, HttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) {
            //Insert js when matching to Baidu homepage
            return HttpUtil.checkUrl(pipeline.getHttpRequest(), "^www.baidu.com$")
                && isHtml(httpRequest, httpResponse);
          }

          @Override
          public void handleResponse(HttpRequest httpRequest, FullHttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) {
            //Print raw packet
            System.out.println(httpResponse.toString());
            System.out.println(httpResponse.content().toString(Charset.defaultCharset()));
            //Edit response header and response body
            httpResponse.headers().set("handel", "edit head");
            httpResponse.content().writeBytes("<script>alert('hello proxyee')</script>".getBytes());
          }
        });
      }
    })
    .start(9999);

Note: When https support is enabled, you need to install the CA certificate (src/resources/ca.crt) to a trusted root certificate authority.

More demo code can be found in the test package.

HTTPS support

The CA certificate (src/resources/ca.crt) from the project needs to be imported to a trusted root certificate authority. You can use the CertDownIntercept interceptor to enable the web certificate download feature, visit http://serverIP:serverPort to access.

Note 1: If the certificate installation on Android phones pops up the password stored in your credentials, just enter the lock screen password.

Note 2: Android 7 and above, the system no longer trusts user-installed certificates, you need to root and use the cat ca.crt > $(openssl x509 -inform PEM -subject_hash_old -in ca.crt | head -1).0 command generates the d1488b25.0 file, and then moves the file to the /system/etc/security/cacerts/ And give 644 access.

Note 3: In Android 7 and above, even if you add the certificate to the system certificate, this certificate does not work in chrome. The reason is that chrome will only trust certificates with validity less than 27 months from 2018 (https://www.entrustdatacard.com/blog/2018/february/chrome-requires-ct-after-april-2018). So you need to generate the certificate file yourself.

Custom CA

Since the root certificate and private key attached to the project are public, they are only suitable for local development and debugging, please generate your own root certificate and private key when using in the official environment, otherwise there will be risks.

  • running the main method of thecom.github.monkeywie.proxyee.crt.CertUtil class

  • use openssl

openssl genrsa -out ca.key 2048
openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER -in ca.key -out ca_private.der
openssl req -sha256 -new -x509 -days 365 -key ca.key -out ca.crt \
    -subj "/C=CN/ST=GD/L=SZ/O=lee/OU=study/CN=testRoot"

Copy ca.crt and ca_private.der to the project src/resources/ after generation, or implement the HttpProxyCACertFactory interface to custom load the root certificate and private key.

Rules for MITM

If you only want to perform MITM attacks on certain domains, you can use the HttpProxyServerConfig.setMitmMatcher method to set the matching rule, for example:

HttpProxyServerConfig config = new HttpProxyServerConfig();
config.setHandleSsl(true);
// only MITM on www.baidu.com
config.setMitmMatcher(new DomainHttpProxyMitmMatcher(Arrays.asList("www.baidu.com")));

Now the built-in DomainHttpProxyMitmMatcher is an exact match for the request domain. If you have other requirements, you can implement the HttpProxyMitmMatcher interface to customize the matching rules.

Authentication

Currently only basic authentication are supported.

  • Basic
// curl -i -x 127.0.0.1:9999 -U admin:123456 http://www.baidu.com
HttpProxyServerConfig config = new HttpProxyServerConfig();
        config.setAuthenticationProvider(new BasicHttpProxyAuthenticationProvider() {
            @Override
            protected BasicHttpToken authenticate(String usr, String pwd) {
                if ("admin".equals(usr) && "123456".equals(pwd)) {
                    return new BasicHttpToken(usr, pwd);
                }
                return null;
            }
        });
new HttpProxyServer()
        .serverConfig(config)
        .start(9999);
  • Custom

Customize authentication by implementing the HttpProxyAuthenticationProvider interface.

Authentication context

After the authorization, the token returned from the verification pass can be obtained in the pipeline.

HttpToken token = HttpAuthContext.getToken(clientChannel);

Pre-proxy support

Pre-proxy can be set,support http,socks4,socks5 protocol.

new HttpProxyServer()
    .proxyConfig(new ProxyConfig(ProxyType.SOCKS5, "127.0.0.1", 1085))
    .start(9999);

Donate

If you like this project, please consider donating to support the development of this project, thank you!

Flow

SSL handshake SSL握手

HTTP communication

HTTP通讯

How it works

Thanks

intellij-idea

proxyee's People

Contributors

dependabot[bot] avatar er1c avatar lamgc avatar lax0214 avatar monkeywie avatar rzabini avatar siwee avatar smichea avatar usami-muzugi avatar xujimu avatar xyzj91 avatar zerorooot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proxyee's Issues

Android Studio 开发时出现 Attempt to inmoke virtual method 'void lee.study.proxyee.intercept.HttpProxyInterceptPipeline.beforeRequest(io.netty.channel.Channel, io.netty.handler.codec.http.HttpContent)' on a null object reference'

DEBUG 错误信息如下

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'void lee.study.proxyee.intercept.HttpProxyInterceptPipeline.beforeRequest(io.netty.channel.Channel, io.netty.handler.codec.http.HttpContent)' on a null object reference
                  at lee.study.proxyee.handler.HttpProxyServerHandle.channelRead(HttpProxyServerHandle.java:103)
W/System.err:     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
                  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
                  at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
                  at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
                  at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
                  at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
W/System.err:     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
                  at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
                  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
                  at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
                  at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
                  at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
                  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
W/System.err:     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
                  at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
                  at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
                  at java.lang.Thread.run(Thread.java:776)
W/System.err: java.lang.UnsupportedOperationException
W/System.err:     at java.util.regex.Matcher.group(Matcher.java:383)
                  at lee.study.proxyee.util.ProtoUtil.getRequestProto(ProtoUtil.java:32)
                  at lee.study.proxyee.handler.HttpProxyServerHandle.channelRead(HttpProxyServerHandle.java:81)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
                  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
                  at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
                  at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
                  at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
W/System.err:     at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
                  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
                  at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
                  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
                  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
                  at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
W/System.err:     at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
                  at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
                  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
                  at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
                  at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
                  at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
                  at java.lang.Thread.run(Thread.java:776)

代码如下,点击 Button 的时候启动代理服务,不知道啥原因,点击之后会卡,不过开个线程去启动就行。

ProxyServerUtils.proxyServer = new HttpProxyServer();
        ProxyServerUtils.proxyServer = ProxyServerUtils.proxyServer.proxyInterceptInitializer(new HttpProxyInterceptInitializer()
        {
            @Override
            public void init(HttpProxyInterceptPipeline pipeline)
            {
                pipeline.addLast(new CertDownIntercept());
                pipeline.addLast(new HttpProxyIntercept()
                {

                });
            }
        });
        ProxyServerUtils.proxyServer = ProxyServerUtils.proxyServer.httpProxyExceptionHandle(new HttpProxyExceptionHandle()
        {
            @Override
            public void beforeCatch(Channel clientChannel, Throwable e) throws Exception
            {
                e.printStackTrace();
            }

            @Override
            public void afterCatch(Channel clientChannel, Channel proxyChannel, Throwable e) throws Exception
            {
                e.printStackTrace();
            }
        });

Error:Connection reset by peer

运行test里面的NormalHttpProxyServer会直接提示连接被重置,采用的方法是本地执行,然后Chrome使用SwitchyOmega来代理转发

十一月 12, 2018 8:47:31 上午 io.netty.channel.AbstractChannelHandlerContext invokeExceptionCaught
警告: An exception 'java.lang.Exception: java.io.IOException: Connection reset by peer' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.io.IOException: Connection reset by peer
	at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
	at sun.nio.ch.IOUtil.read(IOUtil.java:192)
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379)
	at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:745)

io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: certificate_unknown

An exception 'java.lang.Exception: io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: certificate_unknown' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: certificate_unknown
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLException: Received fatal alert: certificate_unknown
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634)
at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800)
at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1083)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:907)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:294)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1275)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
... 16 more

楼主,mac电脑下运行代理服务,并且安装了根证书,然后手机也安装了根证书,手机设置代理,访问网络就出现这些问题,请问楼主咋修复了,谢谢回复

请教一个问题

我在修改响应体之后 需要修改一个响应头Content-Length 的 值,现在来说 拦截响应头和响应体 是分开的,有什么办法在修改响应体之后得到这个长度之后我在修改响应头呢

证书生成疑问

我看了CertUtil的类中只有 crt文件的生成方式,请问der的私钥匙怎么生成的啊,导入证书之后一直提示非法链接,网站没法打开了

netty内存泄露

处理CONNECT连接时,需要释放bytebuf,否则会内存泄露。
if ("CONNECT".equalsIgnoreCase(request.method().name())) {//建立代理握手
......
ReferenceCountUtil.release(msg);

关于证书和socks的问题

  1. 项目支持socks代理吗?
  2. 为什么代理服务器也要准备证书呢,是为了方便在客户端和目标服务器之间,拦截查看具体的通信内容吗?
  3. 如果没有“问题2”这个需求,是否不用证书也可以实现https的代转发功能呢?

Too many open files in system

rary/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=64870:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/lib/tools.jar:/Users/didi/dev/GitHome/learn/proxyee/target/test-classes:/Users/didi/dev/GitHome/learn/proxyee/target/classes:/Users/didi/.m2/repository/io/netty/netty-buffer/4.1.25.Final/netty-buffer-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-common/4.1.25.Final/netty-common-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-codec/4.1.25.Final/netty-codec-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-transport/4.1.25.Final/netty-transport-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-resolver/4.1.25.Final/netty-resolver-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-codec-http/4.1.25.Final/netty-codec-http-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-handler/4.1.25.Final/netty-handler-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-handler-proxy/4.1.25.Final/netty-handler-proxy-4.1.25.Final.jar:/Users/didi/.m2/repository/io/netty/netty-codec-socks/4.1.25.Final/netty-codec-socks-4.1.25.Final.jar:/Users/didi/.m2/repository/org/bouncycastle/bcpkix-jdk15on/1.58/bcpkix-jdk15on-1.58.jar:/Users/didi/.m2/repository/org/bouncycastle/bcprov-jdk15on/1.58/bcprov-jdk15on-1.58.jar com.github.monkeywie.proxyee.InterceptResponseContentHttpProxyServer
二月 21, 2019 2:14:28 下午 io.netty.channel.AbstractChannelHandlerContext invokeExceptionCaught
警告: An exception 'java.lang.InternalError: java.io.FileNotFoundException: /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre/lib/ext/localedata.jar (Too many open files in system)' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.io.IOException: Too many open files in system
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
at io.netty.util.internal.SocketUtils$5.run(SocketUtils.java:110)
at io.netty.util.internal.SocketUtils$5.run(SocketUtils.java:107)
at java.security.AccessController.doPrivileged(Native Method)
at io.netty.util.internal.SocketUtils.accept(SocketUtils.java:107)
at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:141)
at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:75)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)

二月 21, 2019 2:14:28 下午 io.netty.channel.AbstractChannelHandlerContext invokeExceptionCaught
警告: An exception 'java.lang.Exception: java.io.IOException: Connection reset by peer' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:192)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)

启动后 访问代理会出现这个问题

io.netty.util.IllegalReferenceCountException: refCnt: 0

作者好,首先感谢作者开源了proxyee,https和http都能支持代理!但是自己使用并测试了一段时间,发现了以下几个报错问题:
1、io.netty.util.IllegalReferenceCountException: refCnt: 0
2、io.netty.handler.codec.DecoderException: java.lang.IllegalArgumentException: initialCapacity: -1130 (expectd: 0+)
有些网站请求会经常出现这个错误,导致部分页面获取响应内容丢失,但是刷新一遍后加载成功,困扰了很久了没找到解决方案。。。求作者科普。。。

正则内存溢出

lee.study.proxyee.util.ProtoUtil
Pattern pattern = Pattern.compile("^(?:https?://)?(?[^:]*)(?::(?\d+))?$");这里使用,在使用时,总是会java.lang.StackOverflowError,调节了-Xms100M -Xmx2200M,依旧没用
帮忙看一下

[nioEventLoopGroup-4-4] WARN io.netty.channel.AbstractChannelHandlerContext - An exception 'java.lang.Exception: io.netty.handler.codec.compression.DecompressionException: Input is not in the GZIP format' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception: io.netty.handler.codec.compression.DecompressionException: Input is not in the GZIP format

吹出现大量的这个问题;

at java.lang.Thread.run(Thread.java:748)
[nioEventLoopGroup-4-4] WARN io.netty.channel.AbstractChannelHandlerContext - An exception 'java.lang.Exception: io.netty.handler.codec.compression.DecompressionException: Input is not in the GZIP format' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception:
io.netty.handler.codec.compression.DecompressionException: Input is not in the GZIP format
at io.netty.handler.codec.compression.JdkZlibDecoder.readGZIPHeader(JdkZlibDecoder.java:260)
at io.netty.handler.codec.compression.JdkZlibDecoder.decode(JdkZlibDecoder.java:163)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:392)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:359)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:342)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1429)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:947)
at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:822)
at io.netty.channel.embedded.EmbeddedEventLoop.runTasks(EmbeddedEventLoop.java:61)
at io.netty.channel.embedded.EmbeddedChannel.runPendingTasks(EmbeddedChannel.java:578)
at io.netty.channel.embedded.EmbeddedChannel$EmbeddedUnsafe$1.close(EmbeddedChannel.java:798)
at io.netty.channel.DefaultChannelPipeline$HeadContext.close(DefaultChannelPipeline.java:1376)
at io.netty.channel.AbstractChannelHandlerContext.invokeClose(AbstractChannelHandlerContext.java:624)
at io.netty.channel.AbstractChannelHandlerContext.close(AbstractChannelHandlerContext.java:608)
at io.netty.channel.DefaultChannelPipeline.close(DefaultChannelPipeline.java:1040)
at io.netty.channel.AbstractChannel.close(AbstractChannel.java:274)
at io.netty.channel.embedded.EmbeddedChannel.close(EmbeddedChannel.java:550)
at io.netty.channel.embedded.EmbeddedChannel.close(EmbeddedChannel.java:537)
at io.netty.channel.embedded.EmbeddedChannel.finish(EmbeddedChannel.java:485)
at io.netty.channel.embedded.EmbeddedChannel.finishAndReleaseAll(EmbeddedChannel.java:475)
at io.netty.handler.codec.http.HttpContentDecoder.cleanup(HttpContentDecoder.java:217)
at io.netty.handler.codec.http.HttpContentDecoder.cleanupSafely(HttpContentDecoder.java:224)
at io.netty.handler.codec.http.HttpContentDecoder.channelInactive(HttpContentDecoder.java:204)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:420)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:377)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:342)
at io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:223)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:377)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:342)
at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1028)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1429)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:947)
at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:822)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:465)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)

连接被重置

异常信息
111111111111111 java.io.IOException: Connection reset by peer at sun.nio.ch.FileDispatcherImpl.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) at sun.nio.ch.IOUtil.read(IOUtil.java:192) at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288) at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1106) at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:373) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:123) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) at java.lang.Thread.run(Thread.java:748)
浏览器是Chrome

Edge返回迷之404

系统:Win10 1083

使用FullResponseIntercept
设置系统代理后,chrome访问一切正常。edge访问很多资源会返回404,甚至会弹出文件下载的对话框。

unknown_ca

io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: unknown_ca

这个问题如何处理?

相应问题

有些情况下一次 beforeRequest 请求会有多次 afterResponse ,如何封装一次完整的请求数据呢?

netty中 response如何和request匹配呢

楼主,请教下netty中,异步请求下返回的response如何匹配到那一个request对象呢,这块有什么好的方法吗?我的目的是当response返回后,需要找到对应的request对象,从而生一个包含request和response相关HTTP数据的新的对象。

在https连接中interceptPipeline = buildPipeline(); 不会执行吗?

你好,在使用https代理的时候interceptPipeline 执行不到吗?
image

当检测到请求的method为CONNECT的时候,函数直接返回了,定义的proxyIntercept拦截器初始化不了,响应拦截的函数也不会被执行。实际运行https代理的时候,访问https://www.baidu.com,响应的内容也没有被修改。

请问是哪个过程有问题呢?我是想测试在https代理中获取请求和响应的内容。谢谢

源码请教

老哥,我最近在阅读您的源码,有些不懂得地方,能要个联系方式请教一下吗?

生成的证书问题

您好,请问你的ca.crt和ca_pub.der、ca_private.pem分别是怎么生成的
我自己采用了生成的证书老有问题
生成步骤:
1、openssl genrsa -out cakey.pem 2048
2、openssl req -new -key cakey.pem -out ca.csr
3、openssl x509 -req -days 365 -sha256 -extensions v3_ca -signkey cakey.pem -in ca.csr -out ca.cer
4、openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER -in cakey.pem -out ca_private.pem
5、openssl rsa -in cakey.pem -pubout -outform DER -out ca_pub.der

可不可以重用eventloopgroup?

我把您的 run()method 稍加修改了一下,特别是现在只用了2个EventLoopGroup。 这是从《Netty In Action》这本书里受到的启发:

Suppose your server is processing a client request that requires it to act as a client to
a third system. This can happen when an application, such as a proxy server, has to
integrate with an organization’s existing systems, such as web services or databases. In
such cases you’ll need to bootstrap a client Channel from a ServerChannel.
You could create a new Bootstrap as described in section 8.2.1, but this is not the
most efficient solution, as it would require you to define another EventLoop for the new
client Channel. This would produce additional threads, necessitating context switching
when exchanging data between the accepted Channel and the client Channel.
A better solution is to share the EventLoop of the accepted Channel by passing it to
the group() method of the Bootstrap. Because all Channels assigned to an EventLoop
use the same thread, this avoids the extra thread creation and related context-switching
mentioned previously.

==================
您觉得这样改合适吗?
-- Babagilo

public void run(int port) throws InterruptedException, CertificateException, InvalidKeySpecException,
		NoSuchAlgorithmException, NoSuchProviderException, IOException {
	bossGroup = new NioEventLoopGroup(1);
	workerGroup = new NioEventLoopGroup();

	try {
		ServerBootstrap b = new ServerBootstrap();
		b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100)
				//.handler(new LoggingHandler(LogLevel.INFO))
				.childHandler(new ChannelInitializer<SocketChannel>() {

					@Override
					protected void initChannel(SocketChannel ch) throws Exception {
						BabagiloProxyHandler serverHandler = proxyMode == ProxyMode.TUNNEL
								? new BabagiloProxyHandler(ch.eventLoop())
								: new BabagiloProxyHandler(ch.eventLoop(), proxyInterceptInitializer,
										proxyConfig, httpProxyExceptionHandle,  serverPrivateKey,  issuer,  ca_private_key,
										 caNotBefore,  caNotAfter,  serverPubKey);

						ch.pipeline().addLast("httpCodec", new HttpServerCodec());
						ch.pipeline().addLast("serverHandle", serverHandler);
					}
				});
		// Start the server
		ChannelFuture f = b.bind(port).sync();
		// Wait until the server socket is closed
		//System.err.format("BabagiloProxy is listening at localhost:%d; Mode: %s%n", port, this.proxyMode);
		f.channel().closeFuture().sync();
		
	} finally {
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
	}
}

通过proxyee部署代理服务器,内网环境不通,本地环境ok

非常感谢开源proxyee,我通过proxyee部署里一台服务器作为代理服务器(内网ip:10.241.51.39)
通过以下curl命令测试代理:
方式1:使用内网ip测试不通,curl --connect-timeout 3 -m 20 -L -x 10.241.51.39:8181 --insecure https://www.taobao.com -t utf-8,报curl: (7) couldn't connect to host
错误
方式2:使用127.0.0.1测试,能正常返回,curl --connect-timeout 3 -m 20 -L -x 127.0.0.1:8181 --insecure https://www.taobao.com -t utf-8

怀疑是防火墙端口未开放,然后给防火墙添加了以下规则
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8181 -j ACCEPT

仍然不通,纠结很久,等待协助解答,万分感谢!

https 报错

io.netty.handler.codec.DecoderException: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record:
ca.crt证书已经导入 “受信任的根证书颁发机构”了 @monkeyWie

请教一个问题

浏览器访问一张图片,如何在代理服务器上进行拦截,将图片下载下来?谢谢!

功能扩展的问题

proxyee代理服务试用了,感觉挺不错的。希望能用proxyee拦截打印出http请求的参数,和代理服务响应的参数。请问下monkeyWie,后面有没有考虑做这方面的功能扩展?或者能不能给我建议下如何实现这样的功能?谢谢!
主要是Content里面的内容不知道如何读取。

运行入口直接报以下问题

十二月 04, 2017 9:25:46 下午 io.netty.channel.DefaultChannelPipeline onUnhandledInboundException
警告: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: unknown_ca
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLException: Received fatal alert: unknown_ca
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634)
at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800)
at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1083)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:907)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:281)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1215)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1127)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1162)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
... 16 more

运行httpProxyServer连上就报以上错误,查了google说是surper.channelRead的方法的问题,但你都override这个方法了,怎么还有这个问题啊。
http://m.php.cn/wenda/94484.html

请教

if ("CONNECT".equalsIgnoreCase(request.method().name())) {//建立代理握手
status = 2;
HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
HttpProxyServer.SUCCESS);
ctx.writeAndFlush(response);
ctx.channel().pipeline().remove("httpCodec");
return;
}
这段代码是什么作用啊? 麻烦解释一下嘛,想了很久没想通,实在困扰。。谢谢了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.