/// <summary> /// 网页快照尺寸,Full Screenshot则设置Size.Empty /// </summary> /// <param name="size"></param> internal static void xSnapshot(WebBrowser browser, Size size, string saveFileDirectory, Guid?fileID = null) { browser.ScrollBarsEnabled = false; browser.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, 10240); var arg = (ScriptingContext)browser.ObjectForScripting; if (fileID == null) { fileID = CryptoManaged.MD5Hash(arg.RequestUrl.OriginalString); } string savePath = Path.Combine(saveFileDirectory, string.Format("{0}.png", fileID)); try { var js = new StringBuilder(); js.AppendFormat("document.body.setAttribute('_CurrentSnapshot', '{0}');", fileID); js.Append(@" window.addEventListener('load', function () { window.scrollTo(0, document.documentElement.offsetHeight); }); "); xInvoke(browser, js.ToString()); browser.Size = size == Size.Empty ? browser.Document.Body.ScrollRectangle.Size : size; using (var img = new Bitmap(browser.Width, browser.Height)) { NativeMethods.DrawTo(browser.ActiveXInstance, img, Color.White); img.Save(savePath, System.Drawing.Imaging.ImageFormat.Png); App.LogInfo("xSnapshot {0} {1}", browser.Url, savePath); } } catch (Exception ex) { App.LogError(ex, "xSnapshot {0} {1}", browser.Url, savePath); } }
public static void SetCookieSafety(HttpContext context, DateTime?expires = null) { var col = context.Items[CookieValueName] as SessionStateItemCollection; if (col == null || !col.Dirty) { return; } var cookieID = CookieID; cookieID.Value = Guid.NewGuid().ToString("N"); SetCookie(context, cookieID); col[CookieIDName] = cookieID.Value; var crypto = new CryptoManaged(CryptoKey, cookieID.Value); using (var stream = new MemoryStream()) using (var br = new BinaryWriter(stream, Encoding.UTF8)) { col.Serialize(br); stream.Position = 0L; SetCookie(context, new HttpCookie(CookieValueName) { HttpOnly = true, Value = Convert.ToBase64String(crypto.Encrypt(stream).ToArray()) }, expires: expires); } }
private Uri[] GetServerBalance(AgentHubConfig config) { var serverBalance = new List <Uri>(); if (config.AsServerNode) { //创建本地服务节点 Uri serverUrl; xHttpServer.Start(@"C:\Packages\azure", out serverUrl); Console.Out.WriteLine("服务端节点{0}开启...", serverUrl); serverBalance.Add(serverUrl); } else { if (config.EnableSsl) { //默认服务端 if (!this.CatchExec(() => CryptoManaged.TrustCert(App.GetResourceStream("System.Agent.Resource.XineV2.pfx"), "xineapp"), "导入证书")) { config.EnableSsl = false; Console.Out.WriteWarning("导入证书失败,将不启用加密通讯。"); } } //服务端分配域名 string domain = Configuration.ConfigurationManager.AppSettings["Agent-Server"] ?? "azure.xineapp.com"; var client = new HttpClient(new Uri(string.Format("http://{0}/Let.ashx", domain))); var res = client.GetResponse(); var q = from t in res.GetResponseText().Split('#') where !string.IsNullOrEmpty(t) select new Uri(string.Format("{0}://{1}/Go.ashx", config.EnableSsl ? Uri.UriSchemeHttps : Uri.UriSchemeHttp, t)); serverBalance.AddRange(q); Console.Out.WriteLine("连接服务器{0}...", q.First()); } return(serverBalance.ToArray()); }
/// <summary> /// 创建HttpTunnel /// </summary> /// <param name="proxyClient"></param> /// <param name="cmd"></param> /// <returns></returns> /// <exception cref="System.Net.TunnelStateMissingException"></exception> private HttpClient CreateTunnel(TunnelCommand cmd, TcpClient proxyClient) { var tunnel = new HttpClient((Uri)xHttpServer.GetRandom(this.ServerBalance)); switch (cmd) { case TunnelCommand.KeepAlive: tunnel.KeepAlive = false; break; default: tunnel.KeepAlive = true; break; } tunnel.SendReceiveTimeout = xHttpHandler.Timeout * 1000; var cred = this.Credential; tunnel.Headers[xHttpHandler.AgentAuth] = CryptoManaged.MD5Hex(string.Format("{0}:{1}", cred.UserName, cred.Password)); if (proxyClient != null) { var state = this.GetClientState(proxyClient); tunnel.Headers[xHttpHandler.AgentSock] = state.UniqueID.ToString("N"); tunnel.Headers[xHttpHandler.AgentDirect] = state.ToString(); } var rRemoteID = this.ReverseRemoteID; if (rRemoteID != null) { tunnel.Headers[xHttpHandler.AgentReverse] = string.Format("{0}#{1}", _clientID.ToString("N"), rRemoteID.Value.ToString("N")); } tunnel.Form[xHttpHandler.AgentCommand] = ((int)cmd).ToString(); return(tunnel); }
public void ChangePassword(ChangePasswordParameter param) { using (var context = base.CreateUserContext()) { EmailAuth emailAuth = null; MobileAuth mobileAuth = null; if (param.AuthCode != null) { Guid emailAuthCode; if (Guid.TryParse(param.AuthCode, out emailAuthCode)) { emailAuth = this.CheckUserEmailAuth(context, emailAuthCode); } else { string[] mobileAuthCode = param.AuthCode.Split(','); if (mobileAuthCode.Length != 2) { throw new InvalidInvokeException("参数错误"); } mobileAuth = this.CheckUserMobileAuth(context, mobileAuthCode[0], int.Parse(mobileAuthCode[1])); param.UserName = mobileAuth.UserName; } } var id = this.SignIn(new SignInParameter() { AppID = param.AppID, UserName = param.UserName, Password = param.OldPassword }); if (!id.IsAuthenticated) { throw new InvalidInvokeException("账户不存在或密码错误"); } using (var scope = DbScope.Create()) { scope.BeginTransaction(); param.NewPassword = CryptoManaged.MD5Hex(param.NewPassword); context.Accounts.Update(t => t.RowID == id.UserID, t => new Account() { Password = param.NewPassword }); if (emailAuth != null) { emailAuth.Status = (int)ActivationStatus.Activated; } if (mobileAuth != null) { mobileAuth.Status = (int)ActivationStatus.Activated; } context.SaveChanges(); scope.Complete(); } } }
public void UdpDirectSend(HttpContext context, UdpClient proxyClient, IPEndPoint remoteIpe) { context.Server.ScriptTimeout = Timeout; HttpRequest Request = context.Request; HttpResponse Response = context.Response; Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "keep-alive"); var httpFile = Request.Files[AgentDirect]; if (httpFile == null) { this.ResponseForbidden(context); } Stream inStream = httpFile.InputStream; #if DEBUG Guid checksum; if (!Guid.TryParse(Request.Form[AgentChecksum], out checksum)) { this.ResponseForbidden(context); } var mem = new MemoryStream(); inStream.FixedCopyTo(mem, httpFile.ContentLength); mem.Position = 0L; Guid checkKey = CryptoManaged.MD5Hash(mem); if (checksum != checkKey) { this.ResponseForbidden(context); } mem.Position = 0L; inStream = mem; #endif bool succeed = false; int length = (int)inStream.Length; try { var reader = new BinaryReader(inStream); proxyClient.Send(reader.ReadBytes(length), length, remoteIpe); succeed = true; App.LogInfo("UdpDirectSend to {0} {1}bytes.", remoteIpe, length); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif } catch (SocketException ex) { TunnelExceptionHandler.Handle(ex, proxyClient.Client, "UdpDirectSend"); } if (Response.IsClientConnected) { Response.Write(Convert.ToByte(succeed)); } }
private void DirectSend(HttpContext context, TcpClient proxyClient) { context.Server.ScriptTimeout = Timeout; HttpRequest Request = context.Request; HttpResponse Response = context.Response; //优化性能 Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "keep-alive"); var httpFile = Request.Files[AgentDirect]; if (httpFile == null) { this.ResponseForbidden(context); } Stream inStream = httpFile.InputStream; #if DEBUG Guid checksum; if (!Guid.TryParse(Request.Form[AgentChecksum], out checksum)) { this.ResponseForbidden(context); } var mem = new MemoryStream(); inStream.FixedCopyTo(mem, httpFile.ContentLength); mem.Position = 0L; Guid checkKey = CryptoManaged.MD5Hash(mem); if (checksum != checkKey) { this.ResponseForbidden(context); } mem.Position = 0L; inStream = mem; #endif bool succeed = false; if (proxyClient.Connected) { var proxyStream = proxyClient.GetStream(); int length = (int)inStream.Length; try { inStream.FixedCopyTo(proxyStream, length); succeed = true; #if DEBUG App.LogInfo("DirectSend to {0} {1}bytes.", proxyClient.Client.RemoteEndPoint, length); #endif } catch (IOException ex) { TunnelExceptionHandler.Handle(ex, proxyClient.Client, "DirectSend"); } } if (Response.IsClientConnected) { Response.Write(Convert.ToByte(succeed)); } }
private void ReverseDirectSend(HttpContext context, ref Guid agentSock) { context.Server.ScriptTimeout = Timeout; HttpRequest Request = context.Request; HttpResponse Response = context.Response; Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "keep-alive"); var httpFile = Request.Files[AgentDirect]; if (httpFile == null) { this.ResponseForbidden(context); } Stream inStream = httpFile.InputStream; #if DEBUG Guid checksum; if (!Guid.TryParse(Request.Form[AgentChecksum], out checksum)) { this.ResponseForbidden(context); } var mem = new MemoryStream(); inStream.FixedCopyTo(mem, httpFile.ContentLength); mem.Position = 0L; Guid checkKey = CryptoManaged.MD5Hash(mem); if (checksum != checkKey) { this.ResponseForbidden(context); } mem.Position = 0L; inStream = mem; #endif bool succeed = false; var dataQueue = OnlineUsers.GetReverseQueue(agentSock, true); if (dataQueue.Connected) { int length = (int)inStream.Length; if (length > 0) { dataQueue.Push(inStream); } dataQueue.WaitHandle.Set(); succeed = true; #if DEBUG App.LogInfo("ReverseDirectSend to {0} {1}bytes.", dataQueue.RemoteEndPoint, length); #endif } if (Response.IsClientConnected) { Response.Write(Convert.ToByte(succeed)); } }
public Guid Send(string fileName, byte[] fileData) { using (var svc = new InfrastructureServiceClient()) { svc.Invoke(t => t.SaveFile(new SaveFileParameter() { AppID = this.AppID, FileName = fileName, FileData = fileData })); } return(CryptoManaged.MD5Hash(new MemoryStream(fileData))); }
/// <summary> /// 注册 /// </summary> /// <param name="param"></param> public void SignUp(SignUpParameter param) { string orgPwd = param.Password; param.Password = CryptoManaged.MD5Hex(param.Password); using (var scope = DbScope.Create()) using (var context = base.CreateUserContext()) { scope.BeginTransaction(); if (this.IsUserNameExists(new IsUserNameExistsParameter() { AppID = param.AppID, UserName = param.UserName })) { throw new InvalidInvokeException(SignUpErrorCode.AccountExist.ToDescription()); } var dataObj = new Account(); EntityMapper.Map <SignUpParameter, Account>(param, dataObj); dataObj.RowID = Guid.NewGuid(); dataObj.CreateDate = DateTime.Now; context.Accounts.Add(dataObj); context.SaveChanges(); if (param.SmsCode != default(int)) { VerifyMobile(new VerifyMobileParameter() { Mobile = param.Mobile, SmsCode = param.SmsCode }); } scope.Complete(); if (!string.IsNullOrEmpty(param.Email)) { this.SendAuthEmail(new SendAuthEmailParameter() { AppID = param.AppID, UserID = dataObj.RowID, Email = param.Email, Kind = AuthEmailKind.SignUp }); } } }
static void _transfer_Completed(object sender, TransferEventArgs e) { var trans = (FileTransfer)sender; var header = JsonConvert.DeserializeObject <JsonHeader>(e.Config.State.ToString()); string sourceFilePath = string.Format(@"{0}{1}\{2}{3}", InfrastructureRepository.RootPath, trans.DirectoryPath, header.FileKey, Path.GetExtension(e.Config.FileName)); if (header.FileKey != CryptoManaged.MD5HashFile(sourceFilePath).ToString()) { File.Delete(sourceFilePath); return; } var repository = new InfrastructureRepository(); repository.SaveFile(header.FileKey, e.Config.FileName, sourceFilePath); }
static xHttpHandler() { ushort.TryParse(ConfigurationManager.AppSettings["Agent-MaxDevice"], out MaxDevice); Host = ConfigurationManager.AppSettings["Agent-Host"]; var q = from t in (ConfigurationManager.AppSettings["Agent-BlockPorts"] ?? string.Empty).Split(',') where !string.IsNullOrEmpty(t) select ushort.Parse(t); BlockPorts = q.ToArray(); CryptoKey = ConfigurationManager.AppSettings["Agent-CryptoKey"]; var q2 = from t in (ConfigurationManager.AppSettings["Agent-Credentials"] ?? string.Empty).Split(',') where !string.IsNullOrEmpty(t) select CryptoManaged.MD5Hex(t); OnlineUsers = new xUserManager(q2.ToArray()); }
public override void OnEntry(MethodExecutionArgs args) { string hashKey = args.Arguments.Count > 0 ? CryptoManaged.MD5Hex(JsonConvert.SerializeObject(args.Arguments, Formatting.None)) : string.Empty; string key = string.Format("{0}.{1}{2}", args.Method.DeclaringType.Name, args.Method.Name, hashKey); object result = Cache[key]; if (result != null) { args.FlowBehavior = FlowBehavior.Return; args.ReturnValue = result; } else { args.MethodExecutionTag = key; } base.OnEntry(args); }
private static bool TryGetPath(SaveFileParameter param, out Guid checksum, out string path) { checksum = CryptoManaged.MD5Hash(new MemoryStream(param.FileData)); path = string.Format(@"{0}{1}\{2}{3}", InfrastructureRepository.RootPath, param.AppID.ToString("N"), checksum, Path.GetExtension(param.FileName)); var file = new FileInfo(path); FileStream x = null; try { return(!(file.Exists && CryptoManaged.MD5Hash(x = file.OpenRead()) == checksum)); } finally { if (x != null) { x.Close(); } } }
void IHttpClient.DownloadFile(Uri fileUrl, out string fileName) { var client = (IHttpClient)this; fileName = fileUrl.OriginalString; int i = fileName.LastIndexOf("?"); if (i != -1) { fileName = fileName.Remove(i); } fileName = CryptoManaged.MD5Hex(fileUrl.OriginalString) + Path.GetExtension(fileName); string localPath = client.SaveFileDirectory + fileName; var waitDuration = client.RetryWaitDuration; try { if (!App.Retry(() => { this.SetRequest(fileUrl); this.DownloadFile(localPath); var file = new FileInfo(localPath); return(file.Exists && file.Length > 0L); }, client.RetryCount.GetValueOrDefault(1), waitDuration.HasValue ? (int)waitDuration.Value.TotalMilliseconds : 0)) { throw new DownloadException(string.Empty) { RemoteUrl = fileUrl, LocalPath = localPath }; } ; } catch (Exception ex) { throw new DownloadException(string.Empty, ex) { RemoteUrl = fileUrl, LocalPath = localPath }; } }
public TransferConfig(string filePath, uint chunkLength = 0) { Contract.Requires(!string.IsNullOrEmpty(filePath)); var file = new FileInfo(filePath); if (!file.Exists) { throw new FileNotFoundException(string.Empty, filePath); } this.FilePath = file.FullName; this.FileLength = file.Length; using (var stream = file.OpenRead()) { this.Checksum = CryptoManaged.MD5Hash(stream); } ushort chunkSize = (ushort)(this.FileLength / Math.Max(MinChunkLength, chunkLength)); this.ChunkCount = chunkSize; this.FileName = file.Name; }
/// <summary> /// 登录 /// </summary> /// <param name="param"></param> /// <returns></returns> public SSOIdentity SignIn(SignInParameter param) { if (param.Password.Length < 32) { param.Password = CryptoManaged.MD5Hex(param.Password); } using (var context = base.CreateUserContext()) { var q = from t in context.Accounts where t.AppID == param.AppID && t.UserName == param.UserName && t.Password == param.Password select new SSOIdentity { UserID = t.RowID, UserName = t.UserName, Token = Guid.NewGuid().ToString("N"), IssueDate = DateTime.Now, IsAuthenticated = true }; var result = q.DefaultIfEmpty(new SSOIdentity() { UserName = param.UserName, IsAuthenticated = false }).Single(); if (param.LogSignIn) { var log = new SignInLog(); log.UserName = param.UserName; log.ClientIP = param.ClientIP; log.Platform = param.Platform; log.SignInDate = DateTime.Now; log.IsSuccess = result.IsAuthenticated; context.SignInLogs.Add(log); context.SaveChanges(); } return(result); } }
public static void UploadFile(HttpContext context, string savePath) { HttpRequest Request = context.Request; HttpResponse Response = context.Response; var httpFile = Request.Files[0]; if (httpFile == null) { Response.StatusCode = 400; //Bad Request Response.End(); } string rangeFilename = CryptoManaged.MD5Hex(httpFile.FileName + httpFile.ContentLength); var file = new FileInfo(Path.Combine(Path.GetDirectoryName(savePath), rangeFilename)); Response.AddHeader("Content-Length", (file.Exists ? file.Length : 0L).ToString()); long offset; if (!long.TryParse(Request.Headers["Range"], out offset) || file.Length != offset) { Response.StatusCode = 416; //Requested range not satisfiable Response.End(); } using (var stream = file.Open(file.Exists ? FileMode.Append : FileMode.CreateNew, FileAccess.Write, FileShare.Write)) { int length = httpFile.ContentLength; Response.AddHeader("Content-Range", "bytes " + offset.ToString() + "-" + length.ToString() + "/" + length.ToString()); Response.StatusCode = 206; stream.Position = offset; httpFile.InputStream.FixedCopyTo(stream, length, per => { stream.Flush(); return(Response.IsClientConnected); }); } Response.End(); }
public object DoEntry(object arg) { this.CatchExec(() => SecurityPolicy.App2Fw("Agent", App.CombinePath("Agent.exe")), "防火墙例外"); if (!this.CatchExec(() => CryptoManaged.TrustCert(App.GetResourceStream("System.Agent.Resource.CA.crt")), "导入Http证书")) { Console.Out.WriteWarning("导入Http证书失败。"); } try { var config = AgentHubConfig.AppConfig; Console.Out.WriteLine("加载配置{0}成功...", AgentHubConfig.AppConfigPath); //创建隧道客户端 foreach (var tunnel in config.TunnelList) { string remoteMsg = string.Empty; Guid? remoteID = null; string mode = tunnel.Item2; int i = mode.LastIndexOf(@"\"); if (i != -1) { string sRemoteID = mode.Substring(i + 1); remoteMsg = string.Format("ReverseTo={0}", sRemoteID); remoteID = Guid.Parse(sRemoteID); mode = mode.Substring(0, i); } try { SocksProxyType runType; if (Enum.TryParse(mode, out runType)) { var client = CreateTunnelClient(tunnel.Item1, runType, null, remoteID); Console.Out.WriteTip("隧道 {0}:{1} RunMode={2} {3}\t开启...", client.AgentHost, tunnel.Item1, runType, remoteMsg); } else { var directTo = SocketHelper.ParseEndPoint(mode); var client = CreateTunnelClient(tunnel.Item1, runType, directTo, remoteID); Console.Out.WriteTip("隧道 {0}:{1} DirectTo={2} {3}\t开启...", client.AgentHost, tunnel.Item1, directTo, remoteMsg); } } catch (Exception ex) { App.LogError(ex, "CreateTunnelClient"); Console.Out.WriteError("创建隧道失败,{0}...", ex.Message); } } } catch (WebException ex) { Console.Out.WriteError("凭证验证失败:{0}", ex.Message); } catch (Exception ex) { Console.Out.WriteError(ex.Message); App.LogError(ex, "Agent"); } finally { ConsoleNotify.Visible = false; Console.ReadLine(); } return(null); }
internal string HexPassword(string password) { return(CryptoManaged.MD5Hex(password)); }
private string CreateNewUserName(string openID, OAuthKind kind) { string userName = kind.ToString() + "_" + CryptoManaged.MD5Hash(openID); return(userName); }
public SSOIdentity OAuth(OAuthParameter param) { int kind = EnumToValue(param.OAuthKind); using (var context = base.CreateUserContext()) { var q = from t in context.OpenOAuths where t.OpenID == param.OpenID && t.OAuthKind == kind select t; var entity = q.SingleOrDefault(); Guid userID = Guid.Empty; // 验证OAuth返回 if (string.IsNullOrEmpty(param.UserName)) { if (entity == null) { return(null); } var q2 = from t in context.Accounts join t2 in context.OpenOAuths on t.RowID equals t2.UserID where t2.OpenID == param.OpenID && t2.OAuthKind == kind select new string[] { t.UserName, t.Password }; var args = q2.SingleOrDefault(); if (args == null) { throw new InvalidInvokeException("用户不存在"); } param.UserName = args[0]; param.Password = args[1]; } else { // 没有帐号,绑定新帐号 if (param.UserName == param.OpenID) { param.UserName = CreateNewUserName(param.OpenID, param.OAuthKind); if (!context.Accounts.Any(t => t.AppID == param.AppID && t.UserName == param.UserName)) { this.SignUp(new SignUpParameter() { AppID = param.AppID, UserName = param.UserName, Password = param.Password }); Thread.Sleep(200); } goto signIn; } param.Password = CryptoManaged.MD5Hex(param.Password); var q2 = from t in context.Accounts where t.AppID == param.AppID && t.UserName == param.UserName && t.Password == param.Password select t.RowID; userID = q2.SingleOrDefault(); if (userID == Guid.Empty) { throw new InvalidInvokeException("帐号或密码错误"); } var q3 = from t in context.OpenOAuths where t.UserID == userID && t.OAuthKind == kind select t; if (q3.Any()) { throw new InvalidInvokeException("已经绑定过其它账户"); } } signIn: var id = this.SignIn(param); if (entity == null) { if (id.IsAuthenticated) { userID = id.UserID; } if (userID == Guid.Empty) { throw new InvalidInvokeException("UserID's null"); } entity = new OpenOAuth(); EntityMapper.Map <OAuthParameter, OpenOAuth>(param, entity); entity.UserID = userID; entity.CreateDate = DateTime.Now; context.OpenOAuths.Add(entity); context.SaveChanges(); } return(id); } }
private void UdpDirectSend(object state) { var controlClient = (TcpClient)state; if (!controlClient.Connected) { return; } string destIpe = null; try { var currentState = this.GetUdpClientState(controlClient); while (controlClient.Connected) { try { var localIpe = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort); byte[] data = currentState.Client.Receive(ref localIpe); if (!controlClient.Connected) { break; } if (data.IsNullOrEmpty() || !(data[0] == 0 && data[1] == 0 && data[2] == 0)) { this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length); App.LogInfo("Udp Send Discard 非法数据包."); continue; } else if (!currentState.LocalEndPoint.Equals(localIpe)) { this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length); App.LogInfo("Udp Send Discard 非法本地端点."); continue; } int offset = 4; if (data[3] == 3) { DnsEndPoint de; Socks4Request.PackOut(data, ref offset, out de); currentState.AddRemoteEndPoint(de); destIpe = string.Format("{0}:{1}", de.Host, de.Port); } else { IPEndPoint ipe; Socks4Request.PackOut(data, ref offset, out ipe); currentState.AddRemoteEndPoint(ipe); destIpe = ipe.ToString(); } var tunnel = this.CreateTunnel(TunnelCommand.UdpSend, controlClient); tunnel.Headers[xHttpHandler.AgentDirect] = destIpe; var outStream = new MemoryStream(data, offset, data.Length - offset); #if DEBUG tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString(); outStream.Position = 0L; #endif tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream)); var response = tunnel.GetResponse(); if (response.GetResponseText() != "1") { this.OutWrite("Udp {0} Send {1}\t{2}bytes failure.", currentState.LocalEndPoint, destIpe, outStream.Length); return; } this.OutWrite("Udp {0} Send {1}\t{2}bytes.", currentState.LocalEndPoint, destIpe, outStream.Length); //开始接收数据 currentState.SetOnce(); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif } catch (WebException ex) { bool isRejected; if (TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe), _output, out isRejected)) { controlClient.Client.Close(); } if (isRejected) { this.OnServerRejected(); } } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.Interrupted) { #if DEBUG App.LogInfo(string.Format("Predictable interrupted exception: {0}", ex.Message)); #endif return; } TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectSend={0}", destIpe)); } } } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe)); } }
private void DirectSend(object state) { var args = (object[])state; var proxyClient = (TcpClient)args[0]; Guid?localAgentSock = null; if (args.Length == 2) { localAgentSock = (Guid)args[1]; } if (!proxyClient.Connected) { return; } string destIpe = null; try { var localIpe = (IPEndPoint)proxyClient.Client.LocalEndPoint; destIpe = this.GetClientState(proxyClient).ToString(); var proxyStream = proxyClient.GetStream(); var outStream = new MemoryStream(); while (proxyClient.Connected) { try { proxyStream.Read(xHttpHandler.EmptyBuffer, 0, 0); int length; //阻塞解除后做第2道检查,先判断连接状态否则proxyClient.Available会引发ObjectDisposedException if (!proxyClient.Connected || (length = proxyClient.Available) == 0) { //客户端主动关闭 this.OutWrite("{0} Passive disconnect {1}.", localIpe, destIpe); proxyClient.Close(); break; } outStream.Position = 0L; outStream.SetLength(length); proxyStream.FixedCopyTo(outStream, length); outStream.Position = 0L; var tunnel = this.CreateTunnel(TunnelCommand.Send, proxyClient); if (localAgentSock != null) { tunnel.Headers[xHttpHandler.AgentReverse] = localAgentSock.Value.ToString("N"); } #if DEBUG tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString(); outStream.Position = 0L; #endif tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream)); var response = tunnel.GetResponse(); if (response.GetResponseText() != "1") { this.OutWrite("{0} Send {1}\t{2}bytes failure.", localIpe, destIpe, length); continue; } this.OutWrite("{0} Send {1}\t{2}bytes.", localIpe, destIpe, length); } catch (WebException ex) { bool isReject; if (TunnelExceptionHandler.Handle(ex, string.Format("DirectSend={0}", destIpe), _output, out isReject)) { proxyClient.Client.Close(); } if (isReject) { this.OnServerRejected(); } } catch (IOException ex) { var sockEx = ex.InnerException as SocketException; if (sockEx != null) { //由于serverPush关闭后,无法将服务端主动关闭信号转发过来,因此proxyStream.Read()会引发Interrupted的异常; //也就是说错误的原因在于调用Close()后,线程恰好继续向网络缓冲区中读取数据,所以引发SocketException。 if (sockEx.SocketErrorCode == SocketError.Interrupted) { #if DEBUG App.LogInfo(string.Format("Predictable interrupted exception: {0}", sockEx.Message)); #endif return; } } TunnelExceptionHandler.Handle(ex, proxyClient.Client, string.Format("DirectSend={0}", destIpe)); } catch (SocketException ex) { TunnelExceptionHandler.Handle(ex, proxyClient.Client, string.Format("DirectSend={0}", destIpe)); } } } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("DirectSend={0}", destIpe)); } }