手机端转发请求

This commit is contained in:
wanghongenpin
2023-11-28 03:58:14 +08:00
parent 8d64c58f38
commit eec50eb921
8 changed files with 55 additions and 34 deletions

View File

@@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.9.0'
ext.kotlin_version = '1.9.21'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.3'
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@@ -1,6 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
android.enableJetifier=true

View File

@@ -1,5 +1,6 @@
#Tue Nov 28 00:35:45 CST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip

View File

@@ -22,6 +22,7 @@ import 'dart:typed_data';
import 'package:network_proxy/network/host_port.dart';
import 'package:network_proxy/network/http/codec.dart';
import 'package:network_proxy/network/http/http.dart';
import 'package:network_proxy/network/http_client.dart';
import 'package:network_proxy/network/util/attribute_keys.dart';
import 'package:network_proxy/network/util/logger.dart';
@@ -193,21 +194,34 @@ class ChannelPipeline extends ChannelHandler<Uint8List> {
remoteChannel.pipeline.handle(rawCodec, rawCodec, RelayHandler(clientChannel));
}
///远程转发请求
remoteForward(Channel clientChannel, HostAndPort remote, Uint8List msg) async {
Channel? remoteChannel = clientChannel.getAttribute(clientChannel.id);
remoteChannel = remoteChannel ?? await HttpClients.startConnect(remote, RelayHandler(clientChannel));
if (clientChannel.isSsl && !remoteChannel.isSsl) {
remoteChannel.secureSocket = await SecureSocket.secure(remoteChannel.socket,
host: clientChannel.getAttribute(AttributeKeys.domain), onBadCertificate: (certificate) => true);
}
relay(clientChannel, remoteChannel);
handler.channelRead(clientChannel, msg);
}
@override
void channelRead(Channel channel, Uint8List msg) {
void channelRead(Channel channel, Uint8List msg) async {
try {
//手机扫码连接转发远程
HostAndPort? remote = channel.getAttribute(AttributeKeys.remote);
if (remote != null && channel.getAttribute(channel.id) != null) {
relay(channel, channel.getAttribute(channel.id));
handler.channelRead(channel, msg);
Channel? remoteChannel = channel.getAttribute(channel.id);
if (remote != null) {
remoteForward(channel, remote, msg);
return;
}
buffer.add(msg);
//大body 不解析直接转发
if (buffer.length > Codec.maxBodyLength) {
relay(channel, channel.getAttribute(channel.id));
relay(channel, remoteChannel!);
handler.channelRead(channel, buffer.buffer);
buffer.clear();
return;
@@ -227,7 +241,7 @@ class ChannelPipeline extends ChannelHandler<Uint8List> {
}
//websocket协议
if (data.headers.get("Upgrade") == 'websocket' && channel.getAttribute(channel.id) != null) {
if (data.headers.get("Upgrade") == 'websocket' && remoteChannel != null) {
relay(channel, channel.getAttribute(channel.id));
channel.pipeline.channelRead(channel, msg);
return;

View File

@@ -205,8 +205,6 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
var hostAndPort = httpRequest.hostAndPort ?? getHostAndPort(httpRequest);
clientChannel.putAttribute(AttributeKeys.host, hostAndPort);
var proxyHandler = HttpResponseProxyHandler(clientChannel, listener: listener, requestRewrites: requestRewrites);
//远程转发
HostAndPort? remote = clientChannel.getAttribute(AttributeKeys.remote);
//外部代理
@@ -214,21 +212,33 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
if (remote != null || proxyInfo != null) {
HostAndPort connectHost = remote ?? HostAndPort.host(proxyInfo!.host, proxyInfo.port!);
var proxyChannel = await HttpClients.startConnect(connectHost, proxyHandler);
clientChannel.putAttribute(clientId, proxyChannel);
proxyChannel.write(httpRequest);
var proxyChannel = await connectRemote(clientChannel, connectHost);
if (httpRequest.method == HttpMethod.connect) {
proxyChannel.write(httpRequest);
}
return proxyChannel;
}
var proxyChannel = await HttpClients.startConnect(hostAndPort, proxyHandler);
clientChannel.putAttribute(clientId, proxyChannel);
var proxyChannel = await connectRemote(clientChannel, hostAndPort);
//https代理新建连接请求
if (httpRequest.method == HttpMethod.connect) {
await clientChannel.write(
HttpResponse(HttpStatus.ok.reason('Connection established'), protocolVersion: httpRequest.protocolVersion));
} else if (clientChannel.isSsl) {
}
return proxyChannel;
}
/// 连接远程
Future<Channel> connectRemote(Channel clientChannel, HostAndPort connectHost) async {
var proxyHandler = HttpResponseProxyHandler(clientChannel, listener: listener, requestRewrites: requestRewrites);
var proxyChannel = await HttpClients.startConnect(connectHost, proxyHandler);
String clientId = clientChannel.id;
clientChannel.putAttribute(clientId, proxyChannel);
if (clientChannel.isSsl) {
proxyChannel.secureSocket = await SecureSocket.secure(proxyChannel.socket,
host: hostAndPort.host, onBadCertificate: (certificate) => true);
host: connectHost.host, onBadCertificate: (certificate) => true);
}
return proxyChannel;
}

View File

@@ -122,6 +122,6 @@ class ProxyInfo {
@override
String toString() {
return '{enabled: $enabled, host: $host, port: $port}';
return 'ProxyInfo{enabled: $enabled, capturePacket: $capturePacket, host: $host, port: $port}';
}
}

View File

@@ -92,33 +92,31 @@ class Network {
/// ssl握手
void ssl(Channel channel, HostAndPort? hostAndPort, Uint8List data) async {
try {
if (hostAndPort == null && TLS.getDomain(data) != null) {
hostAndPort = HostAndPort.host(TLS.getDomain(data)!, 443);
}
channel.putAttribute(AttributeKeys.domain, hostAndPort?.host);
Channel? remoteChannel = channel.getAttribute(channel.id);
if (remoteChannel != null) {
remoteChannel.secureSocket = await SecureSocket.secure(remoteChannel.socket,
host: hostAndPort?.host, onBadCertificate: (certificate) => true);
}
String? host = hostAndPort?.host;
host ??= TLS.getDomain(data);
if (HostFilter.filter(host)) {
remoteChannel =
remoteChannel ?? await HttpClients.startConnect(HostAndPort.host(host!, 443), RelayHandler(channel));
if (HostFilter.filter(hostAndPort?.host)) {
remoteChannel = remoteChannel ?? await HttpClients.startConnect(hostAndPort!, RelayHandler(channel));
relay(channel, remoteChannel);
channel.pipeline.channelRead(channel, data);
return;
}
//解析ssl握手协议
//ssl自签证书
var certificate = await CertificateManager.getCertificateContext(host!);
var certificate = await CertificateManager.getCertificateContext(hostAndPort!.host);
//服务端等待客户端ssl握手
channel.secureSocket = await SecureSocket.secureServer(channel.socket, certificate, bufferedData: data);
} catch (error, trace) {
if (error is HandshakeException) {
String? host = hostAndPort?.host;
host ??= TLS.getDomain(data);
channel.putAttribute(AttributeKeys.host, host == null ? null : HostAndPort.host(host, 443));
await subscription?.cancel();
channel.putAttribute(AttributeKeys.host, hostAndPort);
}
channel.pipeline.exceptionCaught(channel, error, trace: trace);
}

View File

@@ -2,6 +2,7 @@
/// 2023/5/23
interface class AttributeKeys {
static const String host = "HOST";
static const String domain = "DOMAIN";
static const String uri = "URI";
static const String request = "REQUEST";
static const String remote = "REMOTE";