Exemplo n.º 1
0
 public void OnPackageReceived(object sender, PackageEventArgs <ClientPackageInfo> e)
 {
     Task.Run(() =>
     {
         //先gzip压缩  再转为16进制字符串
         var body = DataHelper.Compress(e.Package.Data);
         var pack = new PackJson()
         {
             Host    = PackJson.Host,
             UserId  = PackJson.UserId,
             Content = body
         };
         var json      = JsonHelper.Instance.Serialize(pack);
         var jsonBytes = Encoding.UTF8.GetBytes(json);
         //03 02 数据长度(4) 正文数据(n)   ---tcp响应包
         var sendBytes = new List <byte>()
         {
             0x3, 0x2
         };
         sendBytes.AddRange(BitConverter.GetBytes(jsonBytes.Length).Reverse());
         sendBytes.AddRange(jsonBytes);
         //转发给服务器
         NatClient.Send(sendBytes.ToArray());
         HandleLog.WriteLine($"<---- {PackJson.UserId} 收到报文{e.Package.Data.Length}字节");
     });
 }
Exemplo n.º 2
0
        static void OnClientConnected(Socket socket)
        {
            //发送注册包给服务端
            var pack = PackHelper.CreatePack(new JsonData()
            {
                Type   = (int)JsonType.NAT,
                Action = (int)NatAction.Connect,
                Data   = Secret
            });

            NatClient?.Send(pack);
        }
Exemplo n.º 3
0
        static void OnClientConnected(object sender, EventArgs e)
        {
            //HandleLog.WriteLine($"【{NatClient.LocalEndPoint}】已连接到服务器【{NatClient.Socket.RemoteEndPoint}】");
            //发送注册包
            var packBytes = new List <byte>()
            {
                0x1, 0x1
            };
            var lenBytes = BitConverter.GetBytes(RegPack.Length).Reverse();

            packBytes.AddRange(lenBytes);
            packBytes.AddRange(RegPack);
            NatClient.Send(packBytes.ToArray());
        }
Exemplo n.º 4
0
 static void SendHeart()
 {
     while (IsReConnect)
     {
         Thread.Sleep(50000);
         if (NatClient.IsConnected)
         {
             //发送心跳包给服务端
             var pack = PackHelper.CreatePack(new JsonData()
             {
                 Type   = (int)JsonType.NAT,
                 Action = (int)NatAction.Heart,
                 Data   = Secret
             });
             NatClient?.Send(pack);
         }
     }
 }
Exemplo n.º 5
0
 static void SendHeart()
 {
     while (!IsStop)
     {
         Thread.Sleep(30000);
         if (NatClient.IsConnected)
         {
             //发送心跳包
             var packBytes = new List <byte>()
             {
                 0x1, 0x2
             };
             var lenBytes = BitConverter.GetBytes(RegPack.Length).Reverse();
             packBytes.AddRange(lenBytes);
             packBytes.AddRange(RegPack);
             NatClient.Send(packBytes.ToArray());
         }
     }
 }
Exemplo n.º 6
0
        public void CloseRemouteClient()
        {
            var pack = new PackJson()
            {
                Host   = PackJson.Host,
                UserId = PackJson.UserId
            };
            var json      = JsonHelper.Instance.Serialize(pack);
            var jsonBytes = Encoding.UTF8.GetBytes(json);
            //03 03 数据长度(4) 正文数据(n)   ---tcp连接关闭包
            var sendBytes = new List <byte>()
            {
                0x3, 0x3
            };

            sendBytes.AddRange(BitConverter.GetBytes(jsonBytes.Length).Reverse());
            sendBytes.AddRange(jsonBytes);
            //转发给服务器
            NatClient.Send(sendBytes.ToArray());
        }
Exemplo n.º 7
0
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <param name="e"></param>
        static void HandleRequest(PackageEventArgs <NatPackageInfo> e)
        {
            Task.Run(() =>
            {
                try
                {
                    var packJson    = JsonHelper.Instance.Deserialize <PackJson>(e.Package.BodyRaw);
                    var headers     = packJson.Headers;
                    var contentType = headers.ContainsKey("Content-Type") ? headers["Content-Type"] : null;
                    var data        = packJson.Content == null ? "" : Encoding.UTF8.GetString(packJson.Content);
                    if (!string.IsNullOrEmpty(contentType))
                    {
                        var index = contentType.IndexOf(";");
                        if (index > 0)
                        {
                            //去掉; charset=utf-8
                            contentType = contentType.Substring(0, index);
                        }
                    }
                    var map = MapList.Find(c => c.remote == packJson.Host);
                    if (map == null)
                    {
                        HandleLog.WriteLine($"映射不存在,外网访问地址:{packJson.Host}");
                        return;
                    }
                    var res = HttpHelper.Request(packJson.Method, $"{map.protocol}://{map.local}{packJson.Route}", data, headers: headers, contentType: contentType);
                    if (res == null)
                    {
                        HandleLog.WriteLine("服务器返回NULL");
                        return;
                    }
                    using (res)
                    {
                        using var stream   = res.Content.ReadAsStreamAsync().Result;
                        var result         = DataHelper.StreamToBytes(stream);
                        var rawResult      = Encoding.UTF8.GetString(result);
                        StringBuilder resp = new StringBuilder();
                        resp.Append($"{map.protocol.ToUpper()}/{res.Version} {(int)res.StatusCode} {res.StatusCode.ToString()}\r\n");
                        foreach (var item in res.Headers)
                        {
                            if (item.Key != "Transfer-Encoding")
                            {
                                resp.Append($"{item.Key}: {string.Join(";", item.Value)}\r\n");
                            }
                        }
                        foreach (var item in res.Content.Headers)
                        {
                            resp.Append($"{item.Key}: {string.Join(";", item.Value)}\r\n");
                        }
                        if (packJson.Method.ToUpper() == "OPTIONS")
                        {
                            resp.Append("Access-Control-Allow-Credentials: true\r\n");
                            if (packJson.Headers.ContainsKey("Access-Control-Request-Headers"))
                            {
                                resp.Append($"Access-Control-Allow-Headers: {packJson.Headers["Access-Control-Request-Headers"]}\r\n");
                            }
                            resp.Append("Access-Control-Allow-Methods: *\r\n");
                            resp.Append($"Access-Control-Allow-Origin: {packJson.Headers["Origin"]}\r\n");
                        }
                        if (!res.Content.Headers.Contains("Content-Length"))
                        {
                            resp.Append($"Content-Length: {result.Length}\r\n");
                        }
                        resp.Append($"Date: {DateTime.Now}\r\n");
                        resp.Append("Connection:close\r\n\r\n");

                        var response = Encoding.UTF8.GetBytes(resp.ToString()).ToList();
                        response.AddRange(result);

                        //先gzip压缩  再转为16进制字符串
                        var body = DataHelper.Compress(response.ToArray());
                        var pack = new PackJson()
                        {
                            Host         = packJson.Host,
                            UserId       = packJson.UserId,
                            Content      = body,
                            ResponseInfo = $"{map.name} {packJson.Method} {packJson.Route} {(int)res.StatusCode} {res.StatusCode.ToString()}"
                        };
                        var json      = JsonHelper.Instance.Serialize(pack);
                        var jsonBytes = Encoding.UTF8.GetBytes(json);
                        //请求头 01 03 长度(4)
                        var sendBytes = new List <byte>()
                        {
                            0x1, 0x3
                        };
                        sendBytes.AddRange(BitConverter.GetBytes(jsonBytes.Length).Reverse());
                        sendBytes.AddRange(jsonBytes);
                        NatClient.Send(sendBytes.ToArray());
                        HandleLog.WriteLine(pack.ResponseInfo);
                    }
                }
                catch (Exception ex)
                {
                    HandleLog.WriteLine($"处理请求异常:{ex}");
                }
            });
        }
Exemplo n.º 8
0
        public static async void ProcessData(NatClient natClient, NatPackageInfo packageInfo)
        {
            try
            {
                switch (packageInfo.Body.Action)
                {
                case (byte)HttpAction.Request:
                {
                    var httpModel = packageInfo.Body.Data.FromJson <HttpModel>();
                    var map       = natClient.Client.MapList.Find(c => c.remote_endpoint == httpModel.Host || (c.remote == httpModel.Host && c.remote_port == 80));
                    if (map == null)
                    {
                        HandleLog.WriteLine($"映射不存在,外网访问地址:{httpModel.Host}");
                        return;
                    }
                    using HttpRequestMessage httpRequest = new HttpRequestMessage()
                          {
                              Method     = new HttpMethod(httpModel.Method),
                              RequestUri = new Uri($"{map.protocol}://{map.local_endpoint}{httpModel.Path}")
                          };
                    HandleLog.WriteLine($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri} {httpModel.Headers.ToJson()}{Environment.NewLine}");
                    string bodyStr = string.Empty;
                    if (httpRequest.Method != HttpMethod.Get && httpModel.Content?.Length > 0)
                    {
                        var body = DataHelper.Decompress(httpModel.Content);        //解压
                        bodyStr             = body.ToUTF8String();
                        httpRequest.Content = new StringContent(bodyStr, Encoding.UTF8, httpModel.ContentType.Split(";")[0]);
                    }
                    HandleLog.WriteLine($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri}{Environment.NewLine}【Header】{httpModel.Headers.ToJson()}{$"{Environment.NewLine}【Body】{bodyStr}".If(httpModel.Content?.Length < 1024)}{Environment.NewLine}");
                    using HttpClient _httpClient = new HttpClient();
                    //替换Host 不然400 Bad Request
                    httpModel.Headers["Host"] = map.local_endpoint;
                    foreach (var item in httpModel.Headers)
                    {
                        if (!item.Key.EqualsWhithNoCase("Content-Type"))
                        {
                            if (!httpRequest.Content?.Headers.TryAddWithoutValidation(item.Key, item.Value) ?? true)
                            {
                                _httpClient.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value);
                            }
                        }
                    }
                    if (map.protocol == "https")
                    {
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                    }
                    var response = await _httpClient.SendAsync(httpRequest);

                    //回传给服务器
                    httpModel.HttpVersion   = $"{map.protocol.ToUpper()}/{response.Version.ToString()}";
                    httpModel.StatusCode    = (int)response.StatusCode;
                    httpModel.StatusMessage = response.StatusCode.ToString();
                    httpModel.Local         = map.local_endpoint;
                    httpModel.Headers       = response.Headers.ToDictionary();
                    httpModel.ResponseTime  = DateTime.Now;
                    foreach (var item in response.Content.Headers)
                    {
                        if (item.Key.EqualsWhithNoCase("Content-Type"))
                        {
                            httpModel.ContentType = string.Join(";", item.Value);
                        }
                        else
                        {
                            if (item.Key.EqualsWhithNoCase("Content-Length"))
                            {
                                continue;
                            }
                            httpModel.Headers.Add(item.Key, string.Join(";", item.Value));
                        }
                    }
                    httpModel.Headers.Remove("Transfer-Encoding");        //response收到的是完整的 这个响应头要去掉 不然浏览器解析出错
                    var returnContent = DataHelper.StreamToBytes(response.Content.ReadAsStreamAsync().Result);
                    if (returnContent.Length > 0)
                    {
                        httpModel.Content = DataHelper.Compress(returnContent);
                    }
                    var pack = PackHelper.CreatePack(new JsonData()
                        {
                            Type   = (int)JsonType.HTTP,
                            Action = (int)HttpAction.Response,
                            Data   = httpModel.ToJson()
                        });
                    natClient?.Send(pack);
                    HandleLog.WriteLine($"{map.name} {httpModel.Method} {httpRequest.RequestUri.AbsoluteUri}{$"{returnContent.ToUTF8String()}".If(returnContent.Length < 1024)} {httpModel.StatusCode} {httpModel.StatusMessage} {Math.Round(returnContent.Length * 1.00 / 1024, 1)}KB{Environment.NewLine}");
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                HandleLog.WriteLine($"处理请求异常:{ex}");

                var pack = PackHelper.CreatePack(new JsonData()
                {
                    Type   = (int)JsonType.HTTP,
                    Action = (int)HttpAction.Response,
                    Data   = new HttpModel()
                    {
                        StatusCode  = (int)HttpStatusCode.BadRequest,
                        ContentType = "text/html",
                        Content     = DataHelper.Compress(Encoding.UTF8.GetBytes($"server error"))
                    }.ToJson()
                });
                natClient?.Send(pack);
            }
        }