Utiliser WebClient avec le proxy chaussettes

Est-il possible d’utiliser un proxy socks avec WebClient ? Spécifiquement avec la méthode DownloadSsortingng qu’il fournit?

Je ne veux pas utiliser de contenu tiers comme privoxy, freecap ou quoi que ce soit et je ne peux pas utiliser de bibliothèques commerciales comme celles de Chilkat. J’ai essayé d’utiliser des éléments de http://www.mentalis.org/. En fait, j’ai utilisé leur implémentation WebRequest mais ils ne semblent pas avoir quelque chose de similaire pour WebClient.

SOCKS n’est pas directement pris en charge par les classes WebRequest / WebResponse et, par extension, par la classe WebClient (il repose sur WebRequest pour effectuer son travail).

Cela ne peut vraiment pas, car cela fonctionne sur la couche de transport (TCP / IP) et non par une simple redirection vers un serveur qui transfère les demandes HTTP (qui correspond au niveau sur lequel les classes WebRequest / WebResponse fonctionnent).

Vous pouvez créer une dérivation spécialisée de WebRequest / WebResponse (qui utilise ensuite ProxySocket pour gérer le ProxySocket de bas niveau), puis créer une classe WebClient spécialisée qui remplace les méthodes GetWebRequest et GetWebResponse .

Une fois cette classe substituée à vos instances WebClient , elle devrait fonctionner normalement (vous devrez peut-être configurer le proxy dans chaque cas d’utilisation).

Voici comment j’ai fini par le faire, merci casperOne pour la réponse

 public class SocksWebClient : WebClient { public IProxyDetails ProxyDetails { get; set; } public ssortingng UserAgent { get; set; } protected override WebRequest GetWebRequest(Uri address) { WebRequest result = null; if (ProxyDetails != null) { if (ProxyDetails.ProxyType == ProxyType.Proxy) { result = (HttpWebRequest)WebRequest.Create(address); result.Proxy = new WebProxy(ProxyDetails.FullProxyAddress); if (!ssortingng.IsNullOrEmpty(UserAgent)) ((HttpWebRequest)result).UserAgent = UserAgent; } else if (ProxyDetails.ProxyType == ProxyType.Socks) { result = SocksHttpWebRequest.Create(address); result.Proxy = new WebProxy(ProxyDetails.FullProxyAddress); //TODO: implement user and password } else if (ProxyDetails.ProxyType == ProxyType.None) { result = (HttpWebRequest)WebRequest.Create(address); if (!ssortingng.IsNullOrEmpty(UserAgent)) ((HttpWebRequest)result).UserAgent = UserAgent; } } else { result = (HttpWebRequest)WebRequest.Create(address); if (!ssortingng.IsNullOrEmpty(UserAgent)) ((HttpWebRequest)result).UserAgent = UserAgent; } return result; } } 

La classe SocksHttpWebRequest est extraite du blog lié à @casperOne, dont le code est le suivant:

 using System; using System.Collections.Specialized; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using Org.Mentalis.Network.ProxySocket; namespace Ditrans { public class SocksHttpWebRequest : WebRequest { #region Member Variables private readonly Uri _requestUri; private WebHeaderCollection _requestHeaders; private ssortingng _method; private SocksHttpWebResponse _response; private ssortingng _requestMessage; private byte[] _requestContentBuffer; // darn MS for making everything internal (yeah, I'm talking about you, System.net.KnownHttpVerb) static readonly SsortingngCollection validHttpVerbs = new SsortingngCollection { "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "OPTIONS" }; #endregion #region Constructor private SocksHttpWebRequest(Uri requestUri) { _requestUri = requestUri; } #endregion #region WebRequest Members public override WebResponse GetResponse() { if (Proxy == null) { throw new InvalidOperationException("Proxy property cannot be null."); } if (Ssortingng.IsNullOrEmpty(Method)) { throw new InvalidOperationException("Method has not been set."); } if (RequestSubmitted) { return _response; } _response = InternalGetResponse(); RequestSubmitted = true; return _response; } public override Uri RequestUri { get { return _requestUri; } } public override IWebProxy Proxy { get; set; } public override WebHeaderCollection Headers { get { if (_requestHeaders == null) { _requestHeaders = new WebHeaderCollection(); } return _requestHeaders; } set { if (RequestSubmitted) { throw new InvalidOperationException("This operation cannot be performed after the request has been submitted."); } _requestHeaders = value; } } public bool RequestSubmitted { get; private set; } public override ssortingng Method { get { return _method ?? "GET"; } set { if (validHttpVerbs.Contains(value)) { _method = value; } else { throw new ArgumentOutOfRangeException("value", ssortingng.Format("'{0}' is not a known HTTP verb.", value)); } } } public override long ContentLength { get; set; } public override ssortingng ContentType { get; set; } public override Stream GetRequestStream() { if (RequestSubmitted) { throw new InvalidOperationException("This operation cannot be performed after the request has been submitted."); } if (_requestContentBuffer == null) { _requestContentBuffer = new byte[ContentLength]; } else if (ContentLength == default(long)) { _requestContentBuffer = new byte[int.MaxValue]; } else if (_requestContentBuffer.Length != ContentLength) { Array.Resize(ref _requestContentBuffer, (int) ContentLength); } return new MemoryStream(_requestContentBuffer); } #endregion #region Methods public static new WebRequest Create(ssortingng requestUri) { return new SocksHttpWebRequest(new Uri(requestUri)); } public static new WebRequest Create(Uri requestUri) { return new SocksHttpWebRequest(requestUri); } private ssortingng BuildHttpRequestMessage() { if (RequestSubmitted) { throw new InvalidOperationException("This operation cannot be performed after the request has been submitted."); } var message = new SsortingngBuilder(); message.AppendFormat("{0} {1} HTTP/1.0\r\nHost: {2}\r\n", Method, RequestUri.PathAndQuery, RequestUri.Host); // add the headers foreach (var key in Headers.Keys) { message.AppendFormat("{0}: {1}\r\n", key, Headers[key.ToSsortingng()]); } if (!ssortingng.IsNullOrEmpty(ContentType)) { message.AppendFormat("Content-Type: {0}\r\n", ContentType); } if (ContentLength > 0) { message.AppendFormat("Content-Length: {0}\r\n", ContentLength); } // add a blank line to indicate the end of the headers message.Append("\r\n"); // add content if(_requestContentBuffer != null && _requestContentBuffer.Length > 0) { using (var stream = new MemoryStream(_requestContentBuffer, false)) { using (var reader = new StreamReader(stream)) { message.Append(reader.ReadToEnd()); } } } return message.ToSsortingng(); } private SocksHttpWebResponse InternalGetResponse() { var response = new SsortingngBuilder(); using (var _socksConnection = new ProxySocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { var proxyUri = Proxy.GetProxy(RequestUri); var ipAddress = GetProxyIpAddress(proxyUri); _socksConnection.ProxyEndPoint = new IPEndPoint(ipAddress, proxyUri.Port); _socksConnection.ProxyType = ProxyTypes.Socks5; // open connection _socksConnection.Connect(RequestUri.Host, 80); // send an HTTP request _socksConnection.Send(Encoding.ASCII.GetBytes(RequestMessage)); // read the HTTP reply var buffer = new byte[1024]; var bytesReceived = _socksConnection.Receive(buffer); while (bytesReceived > 0) { response.Append(Encoding.ASCII.GetSsortingng(buffer, 0, bytesReceived)); bytesReceived = _socksConnection.Receive(buffer); } } return new SocksHttpWebResponse(response.ToSsortingng()); } private static IPAddress GetProxyIpAddress(Uri proxyUri) { IPAddress ipAddress; if (!IPAddress.TryParse(proxyUri.Host, out ipAddress)) { try { return Dns.GetHostEntry(proxyUri.Host).AddressList[0]; } catch (Exception e) { throw new InvalidOperationException( ssortingng.Format("Unable to resolve proxy hostname '{0}' to a valid IP address.", proxyUri.Host), e); } } return ipAddress; } #endregion #region Properties public ssortingng RequestMessage { get { if (ssortingng.IsNullOrEmpty(_requestMessage)) { _requestMessage = BuildHttpRequestMessage(); } return _requestMessage; } } #endregion } } 

Notez que, comme @casperOne l’a souligné, cela utilise une bibliothèque tierce (gratuite) appelée ProxySocket .

Je suis tombé sur cet aswell et j’ai trouvé le meilleur BetterHttpClient

Il dérive de WebClient et vous permet de spécifier un proxy socks:

 BetterHttpClient.HttpClient client = new BetterHttpClient.HttpClient(new BetterHttpClient.Proxy("IP address", port, BetterHttpClient.ProxyTypeEnum.Socks)); 

Voici comment j’ai fini par le faire, merci casperOne pour la réponse

 public class SocksWebClient : WebClient { public IProxyDetails ProxyDetails { get; set; } public ssortingng UserAgent { get; set; } protected override WebRequest GetWebRequest(Uri address) { WebRequest result = null; if (ProxyDetails != null) { if (ProxyDetails.ProxyType == ProxyType.Proxy) { result = (HttpWebRequest)WebRequest.Create(address); result.Proxy = new WebProxy(ProxyDetails.FullProxyAddress); if (!ssortingng.IsNullOrEmpty(UserAgent)) ((HttpWebRequest)result).UserAgent = UserAgent; } else if (ProxyDetails.ProxyType == ProxyType.Socks) { result = SocksHttpWebRequest.Create(address); result.Proxy = new WebProxy(ProxyDetails.FullProxyAddress); //TODO: implement user and password } else if (ProxyDetails.ProxyType == ProxyType.None) { result = (HttpWebRequest)WebRequest.Create(address); if (!ssortingng.IsNullOrEmpty(UserAgent)) ((HttpWebRequest)result).UserAgent = UserAgent; } } else { result = (HttpWebRequest)WebRequest.Create(address); if (!ssortingng.IsNullOrEmpty(UserAgent)) ((HttpWebRequest)result).UserAgent = UserAgent; } return result; } } 

Je cherche le même code mais ça ne marche pas vraiment pour moi. Je me demande où vous avez l’ IProxyDetails -Object. Il semble ne pas être implémenté dans le blog et pas dans les fichiers que j’ai obtenus à partir de là