private HttpListener _httpListener;private HttpTunnelClient(ushort listenPort, Uri serverUri, NetworkCredential credential, IPEndPoint remoteEndPoint = null, SocksProxyType? runType = null) {_httpListener = new HttpListener(); _httpListener.Prefixes.Add(string.Format("http://*:{0}/", listenPort)); _httpListener.Start(); _httpListener.BeginGetContext(this.GetContextCallback, null);}private void GetContextCallback(IAsyncResult ar) { if (_httpListener == null) { return; } _httpListener.BeginGetContext(this.GetContextCallback, null); var context = _httpListener.EndGetContext(ar); this.DirectHttp(context); } private void DirectHttp(HttpListenerContext context) { var Request = context.Request; var Response = context.Response; string destUri = Request.RawUrl; try { var tunnel = this.CreateTunnel(ClientNull, TunnelCommand.HttpDirect); tunnel.Headers[xHttpHandler.AgentDirect] = destUri; tunnel.Headers[xHttpHandler.AgentCommand] = ((int)TunnelCommand.HttpDirect).ToString(); tunnel.Form.Remove(xHttpHandler.AgentCommand); //tunnel.SetProxy(xHttpHandler.GoAgent); using (var tResponse = tunnel.GetResponseWith(new HttpRequestWrapper(Request))) { Response.StatusCode = (int)tResponse.StatusCode; Response.StatusDescription = tResponse.StatusDescription; Response.KeepAlive = tResponse.Headers[HttpResponseHeader.Connection] != "close"; if (tResponse.ContentLength >= 0) { Response.ContentLength64 = tResponse.ContentLength; } Response.ContentType = tResponse.ContentType; foreach (string header in HttpRequestWrapper.SystemHeaders) { tResponse.Headers.Remove(header); } Response.Headers.Add(tResponse.Headers); var tStream = tResponse.GetResponseStream(); tStream.FixedCopyTo(Response.OutputStream); } this.OutWrite("{0} \"{1} {2}\" {3}\t{4}bytes.", Request.LocalEndPoint, Request.HttpMethod, destUri, Response.StatusCode, Response.ContentLength64); //如果写入未完成(异常等情况)就调用Close()则会抛“在写入所有字节之前不能关闭流”异常。 Response.Close(); } catch (WebException ex) { TunnelExceptionHandler.Handle(ex, string.Format("DirectHttp{0}={1}", Request.HttpMethod, destUri)); } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("DirectHttp{0}={1}", Request.HttpMethod, destUri)); } }
private void Direct2GoAgent(HttpContext context, Uri destUri) { context.Server.ScriptTimeout = Timeout; HttpRequest Request = context.Request; HttpResponse Response = context.Response; Request.Headers.Remove(HttpRequestHeader.Authorization.ToString()); Request.Headers.Remove(AgentSock); Request.Headers.Remove(AgentDirect); Request.Headers.Remove(AgentCommand); var client = new HttpClient(destUri); client.SetRequest(destUri); client.SetProxy(GoAgent); try { using (var cResponse = client.GetResponseWith(new System.Web.HttpRequestWrapper(Request))) { Response.StatusCode = (int)cResponse.StatusCode; Response.StatusDescription = cResponse.StatusDescription; Response.ContentType = cResponse.ContentType; Response.Headers.Add(cResponse.Headers); var cStream = cResponse.GetResponseStream(); cStream.FixedCopyTo(Response.OutputStream, (int)cResponse.ContentLength); if (Response.IsClientConnected) { Response.Flush(); } } } catch (WebException ex) { TunnelExceptionHandler.Handle(ex, string.Format("Direct2GoAgent={0}", destUri)); } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("Direct2GoAgent={0}", destUri)); } }