private static ServerInfo sendHTTPSRequest(int count, String host, int port, String payload, String request, int timeout, String encoding, Boolean foward_302, Boolean redirectDoGet) { Interlocked.Increment(ref HTTP.index); String index = Thread.CurrentThread.Name + Interlocked.Read(ref HTTP.index); Stopwatch sw = new Stopwatch(); sw.Start(); ServerInfo server = new ServerInfo(); Boolean isupdateEncoding = false; int sum = 0; Proxy cproxy = null;//当前使用代理 TcpClient clientSocket = null;; MemoryStream body_data = new MemoryStream(); try { if (port > 0 && port <= 65556) { request = request.Replace(Main.setInjectStr, payload); //编码处理 request = StringReplace.strReplaceCenter(main.config, request, main.replaceList); TimeOutSocket tos = new TimeOutSocket(); if (main.config.proxy_mode == 1 || main.config.proxy_mode == 2) { if (main.config.proxy_mode == 1) { //随机代理 cproxy = getRandProxy(); } else { cproxy = main.proxy; } //为空,没有代理资源 if (cproxy == null) { //不使用代理 try { clientSocket = tos.Connect(host, port, timeout); } catch (Exception) { Tools.SysLog(host + ":" + port + "无法连接!"); } } else { if (Socks5ProxyType.Equals(cproxy.proxyType)) { SocketProxy sp = new SocketProxy(); bool isok = false; clientSocket = sp.creatProxySocket(cproxy.host, cproxy.port, timeout); if (clientSocket != null) { isok = sp.ConnectProxyServer(host, port, clientSocket, cproxy.username, cproxy.password, timeout); } if (!isok) { throw new Exception("代理连接失败!"); } tos.useTime = sp.ConectProxyUseTime; } else { //直接替换IP和端口即可 clientSocket = tos.Connect(cproxy.host, cproxy.port, timeout); } } } else { try { clientSocket = tos.Connect(host, port, timeout); } catch (Exception) { Tools.SysLog(host + ":" + port + "无法连接!"); } } if (sw.ElapsedMilliseconds >= timeout) { return(server); } SslStream ssl = null; if (clientSocket != null && clientSocket.Connected) { clientSocket.SendTimeout = timeout - tos.useTime; ssl = new SslStream(clientSocket.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate)); //增加支持TLS1.1和TLS1.2支持3072,768 SslProtocols protocol = (SslProtocols)3072 | (SslProtocols)768 | SslProtocols.Tls | SslProtocols.Ssl3; ssl.AuthenticateAsClient(host, null, protocol, false); if (ssl.IsAuthenticated) { checkContentLength(ref server, ref request); server.request = request; //分开发送header和body,可以绕过某些情况下的安全防护Connection: close,不能使用这种方式 if (!server.reuqestHeader.ToLower().Contains(ConnectionClose)) { String[] reqs = Regex.Split(request, "\r\n\r\n"); server.reuqestHeader = reqs[0]; server.reuqestBody = reqs[1]; ssl.Write(Encoding.UTF8.GetBytes(server.reuqestHeader + "\r\n\r\n")); ssl.Write(Encoding.UTF8.GetBytes(server.reuqestBody)); } else { ssl.Write(Encoding.UTF8.GetBytes(request)); } ssl.Flush(); } } server.request = request; int len = 0; //获取header头 String tmp = ""; StringBuilder sb = new StringBuilder(); clientSocket.ReceiveTimeout = timeout - (int)sw.ElapsedMilliseconds; do { byte[] responseHeader = new byte[1]; int read = ssl.ReadByte(); if (read <= 0) { Thread.Sleep(WaitTime); } char c = (char)read; sb.Append(c); if (c.Equals(T)) { tmp = String.Concat(sb[sb.Length - 4], sb[sb.Length - 3], sb[sb.Length - 2], c); } } while (!tmp.Equals(CTRL) && sw.ElapsedMilliseconds <= timeout); server.header = sb.ToString().Replace(CTRL, ""); String[] headers = Regex.Split(server.header, CT); //处理header doHeader(ref server, ref headers, ref encoding); //302 301跳转 if ((server.code == 302 || server.code == 301) && foward_302) { StringBuilder rsb = new StringBuilder(server.request); int urlStart = server.request.IndexOf(" ") + 1; int urlEnd = server.request.IndexOf(" HTTP"); if (urlStart != -1 && urlEnd != -1) { String url = server.request.Substring(urlStart, urlEnd - urlStart); rsb.Remove(urlStart, url.Length); String location = server.headers["location"]; if (!server.headers["location"].StartsWith("/") && !server.headers["location"].StartsWith("http")) { location = Tools.getCurrentPath(url) + location; } location = location.Replace(" ", "%20"); rsb.Insert(urlStart, location); String newReuqest = rsb.ToString(); if (rsb.ToString().StartsWith("POST") && redirectDoGet) { rsb.Remove(0, 4); rsb.Insert(0, "GET"); } return(sendHTTPSRequest(count, host, port, payload, rsb.ToString(), timeout, encoding, false, redirectDoGet)); } } //根据请求头解析 if (server.headers.ContainsKey(Content_Length) && server.header.IndexOf(Content_Length_Zero) == -1) { int length = int.Parse(server.headers[Content_Length]); while (sum < length && sw.ElapsedMilliseconds <= timeout) { int read = length - sum; if (read > 1024) { read = 1024; } byte[] response_data = new byte[read]; len = ssl.Read(response_data, 0, read); if (len > 0) { sum += len; body_data.Write(response_data, 0, len); } if (len <= 0 && sum < length) { Thread.Sleep(WaitTime); } } } //解析chunked传输 else if (server.headers.ContainsKey(Transfer_Encoding)) { //读取长度 int chunkedSize = 0; byte[] chunkedByte = new byte[1]; //读取总长度 sum = 0; do { String ctmp = ""; do { len = ssl.Read(chunkedByte, 0, 1); if (len <= 0) { Thread.Sleep(WaitTime); } ctmp += Encoding.UTF8.GetString(chunkedByte); } while (ctmp.IndexOf(CT) == -1 && sw.ElapsedMilliseconds <= timeout); chunkedSize = Tools.convertToIntBy16(ctmp.Replace(CT, "")); //chunked的结束0\r\n\r\n是结束标志,单个chunked块\r\n结束 if (ctmp.Equals(CT)) { continue; } if (chunkedSize == 0) { //结束了 break; } int onechunkLen = 0; while (onechunkLen < chunkedSize && sw.ElapsedMilliseconds <= timeout) { int read = chunkedSize - onechunkLen; if (read > 1024) { read = 1024; } byte[] response_data = new byte[read]; len = ssl.Read(response_data, 0, read); if (len > 0) { onechunkLen += len; sum += len; body_data.Write(response_data, 0, len); } if (len <= 0 && onechunkLen < chunkedSize) { Thread.Sleep(WaitTime); } } //判断 } while (sw.ElapsedMilliseconds <= timeout); } //connection close方式或未知body长度 else { while (sw.ElapsedMilliseconds <= timeout) { bool isok = clientSocket.Client.Poll(timeout, SelectMode.SelectRead); if (!isok || clientSocket.Available <= 0) { break; } else { int read = clientSocket.Available; if (read > 0) { byte[] response_data = new byte[read]; len = ssl.Read(response_data, 0, read); if (len > 0) { sum += len; body_data.Write(response_data, 0, len); } } else { Thread.Sleep(WaitTime); } } } } //自动识别编码 if (AutoGetEncoding.Equals(encoding)) { if (!String.IsNullOrEmpty(server.encoding)) { encoding = server.encoding;//header找到编码 } else { encoding = DefaultEncoding; //默认一个编码 isupdateEncoding = true; //body找编码 } Encoding encod = Encoding.GetEncoding(encoding); getBody(ref server, ref body_data, ref encod, ref index); //修正编码 if (isupdateEncoding) { String cEncoding = getHTMLEncoding("", server.body); if (!String.IsNullOrEmpty(cEncoding)) { server.encoding = cEncoding;//body找到编码 getBody(ref server, ref body_data, ref encod, ref index); } } } else { //指定编码 Encoding encod = Encoding.GetEncoding(encoding); getBody(ref server, ref body_data, ref encod, ref index); } } }catch (Exception e) { Exception ee = new Exception("HTTPS发包错误!错误消息:" + e.Message + "----发包编号:" + index); throw ee; } finally { sw.Stop(); server.length = sum; server.runTime = sw.ElapsedMilliseconds; body_data.Close(); if (clientSocket != null) { clientSocket.Close(); } if (main.config.isOpenHTTPLog) { server.sleepTime = main.config.sendHTTPSleepTime; Tools.sysHTTPLog(index, server); String proxyInfo = ""; if (cproxy != null) { proxyInfo = cproxy.host + ":" + cproxy.port; } main.showHTTPLog(index, server, payload, proxyInfo); } if (main.config.sendHTTPSleepTime > 0) { Thread.Sleep(main.config.sendHTTPSleepTime); } } return(server); }