From b99138c61efdba88acf25b84e85028c7332ee343 Mon Sep 17 00:00:00 2001 From: Eric Peters Date: Thu, 17 Feb 2022 10:04:43 -0800 Subject: [PATCH 1/2] Add additional english translations for comments/javadocs --- .../service/bc/BouncyCastleCertGenerator.java | 20 +++++--- .../proxyee/crt/spi/CertGenerator.java | 49 +++++++++++-------- .../proxyee/crt/spi/CertGeneratorInfo.java | 23 ++++++--- .../proxyee/handler/HttpProxyInitializer.java | 3 +- .../handler/HttpProxyServerHandler.java | 24 ++++++--- .../handler/TunnelProxyInitializer.java | 3 +- .../proxyee/intercept/HttpProxyIntercept.java | 18 ++++--- .../intercept/HttpTunnelIntercept.java | 3 +- .../intercept/common/CertDownIntercept.java | 6 ++- .../common/FullRequestIntercept.java | 21 +++++--- .../common/FullResponseIntercept.java | 11 +++-- .../proxyee/server/HttpProxyServer.java | 22 ++++++--- .../server/accept/HttpProxyAcceptHandler.java | 9 ++-- .../monkeywie/proxyee/util/ProtoUtil.java | 33 +++++++++---- 14 files changed, 165 insertions(+), 80 deletions(-) diff --git a/src/main/java/com/github/monkeywie/proxyee/crt/service/bc/BouncyCastleCertGenerator.java b/src/main/java/com/github/monkeywie/proxyee/crt/service/bc/BouncyCastleCertGenerator.java index 52ea434..53ed573 100644 --- a/src/main/java/com/github/monkeywie/proxyee/crt/service/bc/BouncyCastleCertGenerator.java +++ b/src/main/java/com/github/monkeywie/proxyee/crt/service/bc/BouncyCastleCertGenerator.java @@ -24,7 +24,8 @@ import java.util.stream.Stream; /** - * 使用了 BC 套件的证书生成器. + *
使用了 BC 套件的证书生成器.
+ *
Use the BouncyCastle suite's certificate generator.
* * @author LamGC */ @@ -32,7 +33,8 @@ public class BouncyCastleCertGenerator implements CertGenerator { static { - //注册BouncyCastleProvider加密库 + // 注册BouncyCastleProvider加密库 + // Register the BouncyCastleProvider cryptographic library Security.addProvider(new BouncyCastleProvider()); } @@ -44,7 +46,8 @@ public X509Certificate generateServerCert(String issuer, PrivateKey caPriKey, Da String... hosts) throws Exception { /* String issuer = "C=CN, ST=GD, L=SZ, O=lee, OU=study, CN=ProxyeeRoot"; String subject = "C=CN, ST=GD, L=SZ, O=lee, OU=study, CN=" + host;*/ - //根据CA证书subject来动态生成目标服务器证书的issuer和subject + // 根据CA证书subject来动态生成目标服务器证书的issuer和subject + // Dynamically generate the issuer and subject of the target server certificate based on the CA certificate subject String subject = Stream.of(issuer.split(", ")).map(item -> { String[] arr = item.split("="); if ("CN".equals(arr[0])) { @@ -54,22 +57,27 @@ public X509Certificate generateServerCert(String issuer, PrivateKey caPriKey, Da } }).collect(Collectors.joining(", ")); - //doc from https://www.cryptoworkshop.com/guide/ + // doc from https://www.cryptoworkshop.com/guide/ JcaX509v3CertificateBuilder jv3Builder = new JcaX509v3CertificateBuilder(new X500Name(issuer), //issue#3 修复ElementaryOS上证书不安全问题(serialNumber为1时证书会提示不安全),避免serialNumber冲突,采用时间戳+4位随机数生成 + // Fix the insecure certificate issue on ElementaryOS (when serialNumber is 1, the certificate will be + // prompted to be insecure), avoid serialNumber conflict, and use timestamp + 4-digit random number to + // generate BigInteger.valueOf(System.currentTimeMillis() + (long) (Math.random() * 10000) + 1000), caNotBefore, caNotAfter, new X500Name(subject), serverPubKey); - //SAN扩展证书支持的域名,否则浏览器提示证书不安全 + // SAN扩展证书支持的域名,否则浏览器提示证书不安全 + // The domain name supported by the SAN extended certificate, otherwise the browser prompts that the certificate is not secure GeneralName[] generalNames = new GeneralName[hosts.length]; for (int i = 0; i < hosts.length; i++) { generalNames[i] = new GeneralName(GeneralName.dNSName, hosts[i]); } GeneralNames subjectAltName = new GeneralNames(generalNames); jv3Builder.addExtension(Extension.subjectAlternativeName, false, subjectAltName); - //SHA256 用SHA1浏览器可能会提示证书不安全 + // SHA256 用SHA1浏览器可能会提示证书不安全 + // SHA256 and SHA1 browsers may prompt that the certificate is not secure ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(caPriKey); return new JcaX509CertificateConverter().getCertificate(jv3Builder.build(signer)); } diff --git a/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGenerator.java b/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGenerator.java index 6a0f3ce..6efb687 100644 --- a/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGenerator.java +++ b/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGenerator.java @@ -5,38 +5,45 @@ import java.util.Date; /** - * 证书生成器接口. - * - *

该接口用于在无法使用本库内置的 BC 加密套件时, 可自行实现具体加密细节以绕过 BC 加密套件. - *

实现后, 请注意对实现添加 {@link CertGeneratorInfo} 注解, 并按照 SPI 机制规范注册实现. - * + *

+ * 证书生成器接口. + *

该接口用于在无法使用本库内置的 BC 加密套件时, 可自行实现具体加密细节以绕过 BC 加密套件.

+ *

实现后, 请注意对实现添加 {@link CertGeneratorInfo} 注解, 并按照 SPI 机制规范注册实现.

+ *
+ *
+ * Certificate generator interface. + *

This interface is used to implement specific encryption details to bypass the BC cipher suite when the built-in BC cipher suite of this library cannot be used.

+ *

After implementation, please note to add {@link CertGeneratorInfo} annotation to the implementation, and register the implementation according to the SPI mechanism specification.

+ *
* @author LamGC */ public interface CertGenerator { /** - * 生成服务端自签名证书. - * @param issuer 元数据(X509 Names) - * @param caPriKey 用于进行签名的 CA 私钥. - * @param caNotBefore 证书生效时间, 在这个时间之前证书也是失效的. - * @param caNotAfter 证书失效时间, 过了这个时间后证书即失效. - * @param serverPubKey 服务端证书公钥. - * @param hosts 证书所属域名. - * @return 返回指定域名所属的服务端 X509 证书. - * @throws Exception 当发生任意异常时, 异常将直接抛出至调用方. + *
生成服务端自签名证书.
+ *
Generate a server-side self-signed certificate.
+ * @param issuer
元数据(X509 Names)
Metadata (X509 Names)
+ * @param caPriKey
用于进行签名的 CA 私钥.
CA private key used for signing.
+ * @param caNotBefore
证书生效时间, 在这个时间之前证书也是失效的.
The validity time of the certificate, before this time the certificate is also invalid.
+ * @param caNotAfter
证书失效时间, 过了这个时间后证书即失效.
The certificate expiration time, after which the certificate will become invalid.
+ * @param serverPubKey
服务端证书公钥.
Server certificate public key.
+ * @param hosts
证书所属域名.
The domain name to which the certificate belongs.
+ * @return
返回指定域名所属的服务端 X509 证书.
Returns the server X509 certificate to which the specified domain name belongs.
+ * @throws Exception
当发生任意异常时, 异常将直接抛出至调用方.
When any exception occurs, the exception will be thrown directly to the caller.
*/ X509Certificate generateServerCert(String issuer, PrivateKey caPriKey, Date caNotBefore, Date caNotAfter, PublicKey serverPubKey, String... hosts) throws Exception; /** - * 生成 CA 证书(自签名). - * @param subject 元数据(X509 Names) - * @param caNotBefore 证书生效时间, 在这个时间之前证书也是失效的. - * @param caNotAfter 证书失效时间, 过了这个时间后证书即失效. - * @param keyPair RSA 密钥对. - * @return 返回自签名 CA 证书. - * @throws Exception 当发生任意异常时, 异常将直接抛出至调用方. + *
生成 CA 证书(自签名).
+ *
Generate a CA certificate (self-signed).
+ * @param subject
元数据(X509 Names)
Metadata (X509 Names)
+ * @param caNotBefore
证书生效时间, 在这个时间之前证书也是失效的.
证书失效时间, 过了这个时间后证书即失效.
The certificate expiration time, after which the certificate will become invalid.
+ * @param keyPair
RSA 密钥对.
RSA key pair.
+ * @return
返回自签名 CA 证书.
Returns a self-signed CA certificate.
+ * @throws Exception
当发生任意异常时, 异常将直接抛出至调用方.
When any exception occurs, the exception will be thrown directly to the caller.
*/ X509Certificate generateCaCert(String subject, Date caNotBefore, Date caNotAfter, KeyPair keyPair) throws Exception; diff --git a/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGeneratorInfo.java b/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGeneratorInfo.java index 2bbc4fe..36b95d1 100644 --- a/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGeneratorInfo.java +++ b/src/main/java/com/github/monkeywie/proxyee/crt/spi/CertGeneratorInfo.java @@ -3,9 +3,14 @@ import java.lang.annotation.*; /** - * 证书生成器注解. - *

用于标注声明生成器的具体不可变信息. - * + *

+ * 证书生成器注解. + *

用于标注声明生成器的具体不可变信息.

+ *
+ *
+ * Certificate generator annotations. + *

Concrete immutable information used to annotate the declaration generator.

+ *
* @author LamGC */ @Target(ElementType.TYPE) @@ -13,9 +18,15 @@ public @interface CertGeneratorInfo { /** - * 生成器名称, 该名称要求唯一, 不可重复. - *

当遇到名称相同的不同生成器实例时, 将选择第一个加载的实现. - * @return 返回生成器唯一名称. + *

+ * 生成器名称, 该名称要求唯一, 不可重复. + *

当遇到名称相同的不同生成器实例时, 将选择第一个加载的实现.

+ *
+ *
+ * Generator name, the name must be unique and cannot be repeated. + *

When a different generator instance with the same name is encountered, the first loaded implementation will be chosen.

+ *
+ * @return
返回生成器唯一名称.
Returns the generator unique name.
*/ String name(); diff --git a/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyInitializer.java b/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyInitializer.java index 0bc65ca..2cc7628 100644 --- a/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyInitializer.java +++ b/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyInitializer.java @@ -7,7 +7,8 @@ import io.netty.handler.proxy.ProxyHandler; /** - * HTTP代理,转发解码后的HTTP报文 + *
HTTP proxy, forwarding decoded HTTP packets
+ *
HTTP代理,转发解码后的HTTP报文
*/ public class HttpProxyInitializer extends ChannelInitializer { diff --git a/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyServerHandler.java b/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyServerHandler.java index 5c18730..6e4dd70 100644 --- a/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyServerHandler.java +++ b/src/main/java/com/github/monkeywie/proxyee/handler/HttpProxyServerHandler.java @@ -120,6 +120,7 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) throw if (msg instanceof HttpRequest) { HttpRequest request = (HttpRequest) msg; // 第一次建立连接取host和端口号和处理代理握手 + // The first connection is established to take the host and port number and handle the proxy handshake if (getStatus() == 0) { setRequestProto(ProtoUtil.getRequestProto(request)); if (getRequestProto() == null) { // bad request @@ -127,6 +128,7 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) throw return; } // 首次连接处理 + // first connection handling if (getServerConfig().getHttpProxyAcceptHandler() != null && !getServerConfig().getHttpProxyAcceptHandler().onAccept(request, ctx.channel())) { setStatus(2); @@ -134,6 +136,7 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) throw return; } // 代理身份验证 + // proxy authentication if (!authenticate(ctx, request)) { setStatus(2); ctx.channel().close(); @@ -165,9 +168,9 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) throw ReferenceCountUtil.release(msg); setStatus(1); } - } else { // ssl和websocket的握手处理 + } else { // ssl和websocket的握手处理 | Handshake processing of ssl and websocket ByteBuf byteBuf = (ByteBuf) msg; - if (getServerConfig().isHandleSsl() && byteBuf.getByte(0) == 22) {// ssl握手 + if (getServerConfig().isHandleSsl() && byteBuf.getByte(0) == 22) {// ssl握手 | ssl handshake getRequestProto().setSsl(true); int port = ((InetSocketAddress) ctx.channel().localAddress()).getPort(); SslContext sslCtx = SslContextBuilder @@ -182,6 +185,7 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) throw return; } // 如果connect后面跑的是HTTP报文,也可以抓包处理 + // If the HTTP packet is running behind the connect, you can also capture the packet and process it. if (isHttp(byteBuf)) { ctx.pipeline().addFirst("httpCodec", new HttpServerCodec()); ctx.pipeline().fireChannelRead(msg); @@ -244,6 +248,7 @@ private boolean authenticate(ChannelHandlerContext ctx, HttpRequest request) { private void handleProxyData(Channel channel, Object msg, boolean isHttp) throws Exception { if (getChannelFuture() == null) { // connection异常 还有HttpContent进来,不转发 + // connection exception and HttpContent comes in, not forwarded if (isHttp && !(msg instanceof HttpRequest)) { return; } @@ -261,9 +266,11 @@ private void handleProxyData(Channel channel, Object msg, boolean isHttp) throws if (isHttp) { HttpRequest httpRequest = (HttpRequest) msg; // 检查requestProto是否有修改 + // Check if requestProto is modified RequestProto newRP = ProtoUtil.getRequestProto(httpRequest); if (!newRP.equals(requestProto)) { // 更新Host请求头 + // Update the Host request header if ((getRequestProto().getSsl() && getRequestProto().getPort() == 443) || (!getRequestProto().getSsl() && getRequestProto().getPort() == 80)) { httpRequest.headers().set(HttpHeaderNames.HOST, getRequestProto().getHost()); @@ -277,15 +284,19 @@ private void handleProxyData(Channel channel, Object msg, boolean isHttp) throws * 添加SSL client hello的Server Name Indication extension(SNI扩展) 有些服务器对于client * hello不带SNI扩展时会直接返回Received fatal alert: handshake_failure(握手错误) * 例如:https://cdn.mdn.mozilla.net/static/img/favicon32.7f3da72dcea1.png + * + * Add the Server Name Indication extension (SNI extension) of the SSL client hello to some servers for the client + * Received fatal alert: handshake_failure (handshake error) will be returned directly without the SNI extension. + * For example: https://cdn.mdn.mozilla.net/static/img/favicon32.7f3da72dcea1.png */ ChannelInitializer channelInitializer = isHttp ? new HttpProxyInitializer(channel, requestProto, proxyHandler) : new TunnelProxyInitializer(channel, proxyHandler); Bootstrap bootstrap = new Bootstrap(); - bootstrap.group(getServerConfig().getProxyLoopGroup()) // 注册线程池 - .channel(NioSocketChannel.class) // 使用NioSocketChannel来作为连接用的channel类 + bootstrap.group(getServerConfig().getProxyLoopGroup()) // 注册线程池 | register thread pool + .channel(NioSocketChannel.class) // 使用NioSocketChannel来作为连接用的channel类 | Use NioSocketChannel as the connection channel class .handler(channelInitializer); if (proxyHandler != null) { - // 代理服务器解析DNS和连接 + // 代理服务器解析DNS和连接 | Proxy server resolves DNS and connects bootstrap.resolver(NoopAddressResolverGroup.INSTANCE); } else { bootstrap.resolver(getServerConfig().resolver()); @@ -338,7 +349,7 @@ public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpRespo HttpProxyInterceptPipeline pipeline) throws Exception { clientChannel.writeAndFlush(httpResponse); if (HttpHeaderValues.WEBSOCKET.toString().equals(httpResponse.headers().get(HttpHeaderNames.UPGRADE))) { - // websocket转发原始报文 + // websocket转发原始报文 | Websocket forwards original packets proxyChannel.pipeline().remove("httpCodec"); clientChannel.pipeline().remove("httpCodec"); } @@ -355,6 +366,7 @@ public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpConte } // fix issue #186: 不拦截https报文时,暴露一个扩展点用于代理设置,并且保持一致的编程接口 + // When not intercepting https messages, expose an extension point for proxy settings and maintain a consistent programming interface private HttpProxyInterceptPipeline buildOnlyConnectPipeline() { HttpProxyInterceptPipeline interceptPipeline = new HttpProxyInterceptPipeline(new HttpProxyIntercept()); getInterceptInitializer().init(interceptPipeline); diff --git a/src/main/java/com/github/monkeywie/proxyee/handler/TunnelProxyInitializer.java b/src/main/java/com/github/monkeywie/proxyee/handler/TunnelProxyInitializer.java index cf7ddfd..4f3c6f6 100644 --- a/src/main/java/com/github/monkeywie/proxyee/handler/TunnelProxyInitializer.java +++ b/src/main/java/com/github/monkeywie/proxyee/handler/TunnelProxyInitializer.java @@ -8,7 +8,8 @@ import io.netty.handler.proxy.ProxyHandler; /** - * http代理隧道,转发原始报文 + *
http代理隧道,转发原始报文
+ *
http proxy tunnel, forwarding original packets
*/ public class TunnelProxyInitializer extends ChannelInitializer { diff --git a/src/main/java/com/github/monkeywie/proxyee/intercept/HttpProxyIntercept.java b/src/main/java/com/github/monkeywie/proxyee/intercept/HttpProxyIntercept.java index 0a0df18..df175c0 100644 --- a/src/main/java/com/github/monkeywie/proxyee/intercept/HttpProxyIntercept.java +++ b/src/main/java/com/github/monkeywie/proxyee/intercept/HttpProxyIntercept.java @@ -6,19 +6,22 @@ import io.netty.handler.codec.http.HttpResponse; /** - * http拦截器 + *
http拦截器
+ *
http interceptor
* beforeForward -> beforeRequest -> afterResponse */ public class HttpProxyIntercept { /** - * 在与目标服务器建立连接之前拦截 + *
在与目标服务器建立连接之前拦截
+ *
Intercept before establishing a connection with the target server
*/ public void beforeConnect(Channel clientChannel, HttpProxyInterceptPipeline pipeline) throws Exception { } /** - * 拦截代理服务器到目标服务器的请求头 + *
拦截代理服务器到目标服务器的请求头
+ *
Intercept the request header from the proxy server to the target server
*/ public void beforeRequest(Channel clientChannel, HttpRequest httpRequest, HttpProxyInterceptPipeline pipeline) throws Exception { @@ -26,7 +29,8 @@ public void beforeRequest(Channel clientChannel, HttpRequest httpRequest, } /** - * 拦截代理服务器到目标服务器的请求体 + *
拦截代理服务器到目标服务器的请求体
+ *
Intercept the request body from the proxy server to the target server
*/ public void beforeRequest(Channel clientChannel, HttpContent httpContent, HttpProxyInterceptPipeline pipeline) throws Exception { @@ -34,7 +38,8 @@ public void beforeRequest(Channel clientChannel, HttpContent httpContent, } /** - * 拦截代理服务器到客户端的响应头 + *
拦截代理服务器到客户端的响应头
+ *
Intercept the response headers from the proxy server to the client
*/ public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) throws Exception { @@ -43,7 +48,8 @@ public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpRespo /** - * 拦截代理服务器到客户端的响应体 + *
拦截代理服务器到客户端的响应体
+ *
Intercept the response body from the proxy server to the client
*/ public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpContent httpContent, HttpProxyInterceptPipeline pipeline) diff --git a/src/main/java/com/github/monkeywie/proxyee/intercept/HttpTunnelIntercept.java b/src/main/java/com/github/monkeywie/proxyee/intercept/HttpTunnelIntercept.java index 27659d2..e641d2f 100644 --- a/src/main/java/com/github/monkeywie/proxyee/intercept/HttpTunnelIntercept.java +++ b/src/main/java/com/github/monkeywie/proxyee/intercept/HttpTunnelIntercept.java @@ -4,7 +4,8 @@ /** * @Author LiWei - * @Description 用于拦截隧道请求,在代理服务器与目标服务器连接前 + * @Description
用于拦截隧道请求,在代理服务器与目标服务器连接前
+ *
Used to intercept tunnel requests before the proxy server connects to the target server
* @Date 2019/11/4 9:57 */ public interface HttpTunnelIntercept { diff --git a/src/main/java/com/github/monkeywie/proxyee/intercept/common/CertDownIntercept.java b/src/main/java/com/github/monkeywie/proxyee/intercept/common/CertDownIntercept.java index 0b4261e..0cf8505 100644 --- a/src/main/java/com/github/monkeywie/proxyee/intercept/common/CertDownIntercept.java +++ b/src/main/java/com/github/monkeywie/proxyee/intercept/common/CertDownIntercept.java @@ -11,7 +11,9 @@ import java.security.cert.X509Certificate; /** - * 处理证书下载页面 http://proxyServerIp:proxyServerPort + *
处理证书下载页面
+ *
Process the certificate download page
+ * http://proxyServerIp:proxyServerPort */ public class CertDownIntercept extends HttpProxyIntercept { @@ -73,7 +75,7 @@ public void beforeRequest(Channel clientChannel, HttpRequest httpRequest, clientChannel.close(); } else if (httpRequest.uri().matches("^.*/favicon.ico$")) { clientChannel.close(); - } else { //跳转下载页面 + } else { // 跳转下载页面 | Jump to download page HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); String html = "
ProxyeeRoot ca.crt
"; diff --git a/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullRequestIntercept.java b/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullRequestIntercept.java index a5ece92..a77aa22 100644 --- a/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullRequestIntercept.java +++ b/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullRequestIntercept.java @@ -34,13 +34,17 @@ public final void beforeRequest(Channel clientChannel, HttpRequest httpRequest, fullHttpRequest.headers().set(HttpHeaderNames.CONTENT_LENGTH, fullHttpRequest.content().readableBytes()); } } else if (match(httpRequest, pipeline)) { - //重置拦截器 + // 重置拦截器 + // reset interceptor pipeline.resetBeforeHead(); - //添加gzip解压处理 + // 添加gzip解压处理 + // Add gzip decompression processing clientChannel.pipeline().addAfter("httpCodec", "decompress", new HttpContentDecompressor()); - //添加Full request解码器 + // 添加Full request解码器 + // Add Full request decoder clientChannel.pipeline().addAfter("decompress", "aggregator", new HttpObjectAggregator(maxContentLength)); - //重新过一遍处理器链 + // 重新过一遍处理器链 + // Go through the processor chain all over again clientChannel.pipeline().fireChannelRead(httpRequest); return; } @@ -49,7 +53,8 @@ public final void beforeRequest(Channel clientChannel, HttpRequest httpRequest, @Override public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) throws Exception { - //如果是FullHttpRequest + // 如果是FullHttpRequest + // If it is FullHttpRequest if (pipeline.getHttpRequest() instanceof FullHttpRequest) { if (clientChannel.pipeline().get("decompress") != null) { clientChannel.pipeline().remove("decompress"); @@ -64,12 +69,14 @@ public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpRespo } /** - * 匹配到的请求会解码成FullRequest + *
匹配到的请求会解码成FullRequest
+ *
The matched request will be decoded into FullRequest
*/ public abstract boolean match(HttpRequest httpRequest, HttpProxyInterceptPipeline pipeline); /** - * 拦截并处理响应 + *
拦截并处理响应
+ *
Intercept and process the response
*/ public void handleRequest(FullHttpRequest httpRequest, HttpProxyInterceptPipeline pipeline) { } diff --git a/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullResponseIntercept.java b/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullResponseIntercept.java index 9e43b24..927afe4 100644 --- a/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullResponseIntercept.java +++ b/src/main/java/com/github/monkeywie/proxyee/intercept/common/FullResponseIntercept.java @@ -32,8 +32,10 @@ public final void afterResponse(Channel clientChannel, Channel proxyChannel, if (httpResponse instanceof FullHttpResponse) { FullHttpResponse fullHttpResponse = (FullHttpResponse) httpResponse; // 判断是第一个处理FullResponse的拦截器是否匹配 + // Determine whether the first interceptor that handles FullResponse matches boolean isFirstMatch = isMatch != null && isMatch == true; // 判断后续的拦截器是否匹配 + // Determine whether subsequent interceptors match boolean isAfterMatch = isFirstMatch ? false : match(pipeline.getHttpRequest(), pipeline.getHttpResponse(), pipeline); if (isFirstMatch || isAfterMatch) { handleResponse(pipeline.getHttpRequest(), fullHttpResponse, pipeline); @@ -66,7 +68,8 @@ public final void afterResponse(Channel clientChannel, Channel proxyChannel, @Deprecated /** - * 剥离到工具类中了:{@link com.github.monkeywie.proxyee.util#isHtml(HttpRequest, HttpResponse)} + *
剥离到工具类中了:{@link com.github.monkeywie.proxyee.util#isHtml(HttpRequest, HttpResponse)}
+ *
Stripped into the tool class: {@link com.github.monkeywie.proxyee.util#isHtml(HttpRequest, HttpResponse)}
*/ protected boolean isHtml(HttpRequest httpRequest, HttpResponse httpResponse) { String accept = httpRequest.headers().get(HttpHeaderNames.ACCEPT); @@ -77,13 +80,15 @@ protected boolean isHtml(HttpRequest httpRequest, HttpResponse httpResponse) { } /** - * 匹配到的响应会解码成FullResponse + *
匹配到的响应会解码成FullResponse
+ *
The matched response will be decoded into FullResponse
*/ public abstract boolean match(HttpRequest httpRequest, HttpResponse httpResponse, HttpProxyInterceptPipeline pipeline); /** - * 拦截并处理响应 + *
拦截并处理响应
+ *
Intercept and process the response
*/ public void handleResponse(HttpRequest httpRequest, FullHttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) { diff --git a/src/main/java/com/github/monkeywie/proxyee/server/HttpProxyServer.java b/src/main/java/com/github/monkeywie/proxyee/server/HttpProxyServer.java index c28b933..8ce2018 100644 --- a/src/main/java/com/github/monkeywie/proxyee/server/HttpProxyServer.java +++ b/src/main/java/com/github/monkeywie/proxyee/server/HttpProxyServer.java @@ -33,7 +33,8 @@ public class HttpProxyServer { private final static InternalLogger log = InternalLoggerFactory.getInstance(HttpProxyServer.class); - //http代理隧道握手成功 + // http代理隧道握手成功 + // http proxy tunnel handshake successful public final static HttpResponseStatus SUCCESS = new HttpResponseStatus(200, "Connection established"); public final static HttpResponseStatus UNAUTHORIZED = new HttpResponseStatus(407, @@ -69,14 +70,19 @@ private void init() { caCert = caCertFactory.getCACert(); caPriKey = caCertFactory.getCAPriKey(); } - //读取CA证书使用者信息 + // 读取CA证书使用者信息 + // Read CA certificate user information serverConfig.setIssuer(CertUtil.getSubject(caCert)); - //读取CA证书有效时段(server证书有效期超出CA证书的,在手机上会提示证书不安全) + // 读取CA证书有效时段(server证书有效期超出CA证书的,在手机上会提示证书不安全) + // Read the validity period of the CA certificate (if the validity period of the server certificate + // exceeds the CA certificate, the mobile phone will prompt that the certificate is not safe) serverConfig.setCaNotBefore(caCert.getNotBefore()); serverConfig.setCaNotAfter(caCert.getNotAfter()); - //CA私钥用于给动态生成的网站SSL证书签证 + // CA私钥用于给动态生成的网站SSL证书签证 + // The CA private key is used to sign the dynamically generated website SSL certificate serverConfig.setCaPriKey(caPriKey); - //生产一对随机公私钥用于网站SSL证书动态创建 + // 生产一对随机公私钥用于网站SSL证书动态创建 + // Generate a pair of random public and private keys for dynamic creation of website SSL certificates KeyPair keyPair = CertUtil.genKeyPair(); serverConfig.setServerPriKey(keyPair.getPrivate()); serverConfig.setServerPubKey(keyPair.getPublic()); @@ -187,7 +193,8 @@ protected void initChannel(Channel ch) throws Exception { } /** - * 释放资源 + *
释放资源
+ *
release resources
*/ public void close() { EventLoopGroup eventLoopGroup = serverConfig.getProxyLoopGroup(); @@ -205,7 +212,8 @@ public void close() { } /** - * 注册JVM关闭的钩子以释放资源 + *
注册JVM关闭的钩子以释放资源
+ *
Register hooks for JVM shutdown to release resources
*/ public void shutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread(this::close, "Server Shutdown Thread")); diff --git a/src/main/java/com/github/monkeywie/proxyee/server/accept/HttpProxyAcceptHandler.java b/src/main/java/com/github/monkeywie/proxyee/server/accept/HttpProxyAcceptHandler.java index f50dcef..dc18b04 100644 --- a/src/main/java/com/github/monkeywie/proxyee/server/accept/HttpProxyAcceptHandler.java +++ b/src/main/java/com/github/monkeywie/proxyee/server/accept/HttpProxyAcceptHandler.java @@ -10,16 +10,19 @@ */ public interface HttpProxyAcceptHandler { /** - * 客户端有新的连接建立时触发 + *
客户端有新的连接建立时触发
+ *
Triggered when the client has a new connection established
* * @param request * @param clientChannel - * @return 返回true表示放行,返回false则断开连接 + * @return
返回true表示放行,返回false则断开连接
+ *
Return true to release, return false to disconnect
*/ boolean onAccept(HttpRequest request, Channel clientChannel); /** - * 客户端连接关闭时触发 + *
客户端连接关闭时触发
+ *
Fired when the client connection is closed
* * @param clientChannel */ diff --git a/src/main/java/com/github/monkeywie/proxyee/util/ProtoUtil.java b/src/main/java/com/github/monkeywie/proxyee/util/ProtoUtil.java index d62c708..ff45ce5 100644 --- a/src/main/java/com/github/monkeywie/proxyee/util/ProtoUtil.java +++ b/src/main/java/com/github/monkeywie/proxyee/util/ProtoUtil.java @@ -10,15 +10,27 @@ public class ProtoUtil { - /* - 代理服务器需要处理两种握手类型,一种是非CONNECT的http报文代理,另外一种是CONNECT的TCP报文原始转发 - 示例: - GET http://www.google.com/ HTTP/1.1 - CONNECT www.google.com:443 HTTP/1.1 - CONNECT echo.websocket.org:443 HTTP/1.1 - CONNECT echo.websocket.org:80 HTTP/1.1 - 当客户端请求协议为TLS(https、wss)、WebSocket(ws)的时候,都会发起CONNECT请求进行原始转发, - 所以在握手的时候是无法区分客户端原始请求是否为TLS。 + /** + *
+ * 代理服务器需要处理两种握手类型,一种是非CONNECT的http报文代理,另外一种是CONNECT的TCP报文原始转发 + * 示例: + * GET http://www.google.com/ HTTP/1.1 + * CONNECT www.google.com:443 HTTP/1.1 + * CONNECT echo.websocket.org:443 HTTP/1.1 + * CONNECT echo.websocket.org:80 HTTP/1.1 + * 当客户端请求协议为TLS(https、wss)、WebSocket(ws)的时候,都会发起CONNECT请求进行原始转发, + * 所以在握手的时候是无法区分客户端原始请求是否为TLS。 + *
+ *
+ * The proxy server needs to handle two types of handshakes, one is the non-CONNECT http message proxy, and the other is the CONNECT TCP message original forwarding + * Example: + * GET http://www.google.com/ HTTP/1.1 + * CONNECT www.google.com:443 HTTP/1.1 + * CONNECT echo.websocket.org:443 HTTP/1.1 + * CONNECT echo.websocket.org:80 HTTP/1.1 + * When the client request protocol is TLS (https, wss), WebSocket (ws), it will initiate a CONNECT request for original forwarding, + * So it is impossible to distinguish whether the original request of the client is TLS or not during the handshake. + *
*/ public static RequestProto getRequestProto(HttpRequest httpRequest) { RequestProto requestProto = new RequestProto(); @@ -44,7 +56,8 @@ public static class RequestProto implements Serializable { private static final long serialVersionUID = -6471051659605127698L; /** - * 请求是否来源于http代理,用于区分是通过代理服务访问的还是直接通过http访问的代理服务器 + *
请求是否来源于http代理,用于区分是通过代理服务访问的还是直接通过http访问的代理服务器
+ *
Whether the request comes from an http proxy, which is used to distinguish whether it is accessed through a proxy service or a proxy server accessed directly through http
*/ private boolean proxy; private String host; From c822e7c2764d4c6e3b1efa9afe95f08a25b6075a Mon Sep 17 00:00:00 2001 From: Eric Peters Date: Thu, 17 Feb 2022 10:09:16 -0800 Subject: [PATCH 2/2] Add javadoc link to README.md files --- README.md | 1 + README_zh-CN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 3c49acb..1f1589a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![maven](https://img.shields.io/maven-central/v/com.github.monkeywie/proxyee.svg)](https://search.maven.org/search?q=com.github.monkeywie) [![license](https://img.shields.io/github/license/monkeywie/proxyee.svg)](https://opensource.org/licenses/MIT) +[![javadoc](https://javadoc.io/badge2/com.github.monkeywie/proxyee/javadoc.svg)](https://javadoc.io/doc/com.github.monkeywie/proxyee)

diff --git a/README_zh-CN.md b/README_zh-CN.md index bb14429..6be86e6 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -4,6 +4,7 @@ [![maven](https://img.shields.io/maven-central/v/com.github.monkeywie/proxyee.svg)](https://search.maven.org/search?q=com.github.monkeywie) [![license](https://img.shields.io/github/license/monkeywie/proxyee.svg)](https://opensource.org/licenses/MIT) + [![javadoc](https://javadoc.io/badge2/com.github.monkeywie/proxyee/javadoc.svg)](https://javadoc.io/doc/com.github.monkeywie/proxyee)