Comment créer un simple proxy en C#?
J'ai téléchargé Privoxy il y a quelques semaines et pour le plaisir j'étais curieux de savoir comment une version simple de celui-ci peut être fait.
je comprends que je dois configurer le navigateur (client) pour envoyer la requête au proxy. Le mandataire envoie la requête au web (disons que c'est un mandataire http). Le mandataire recevra la réponse... mais comment le mandataire peut-il renvoyer la requête au navigateur (client)?
j'ai une recherche sur le web pour C# et proxy http mais je n'ai pas trouvé quelque chose qui me permette de comprendre comment ça marche derrière la scène. (Je crois que je ne veux pas d'un reverse proxy, mais je ne suis pas sûr).
Ne vous avez quelques explications ou des informations qui me permettra de continuer ce petit projet?
mise à jour
c'est Ce que je comprends (voir graphique ci-dessous).
Étape 1 je configure le client (navigateur) pour tous demande à envoyer à 127.0.0.1 au port que le Proxy écoute. Ainsi, la demande ne sera pas envoyée directement sur Internet mais sera traitée par le mandataire.
Step2 le mandataire voit une nouvelle connexion, lit L'en-tête HTTP et voit la requête qu'il doit exécuter. Il exécute la requête.
Step3 le mandataire reçoit une réponse de la demande. Maintenant il doit envoyer la réponse du web au client mais comment???
lien utile
Mentalis Proxy : j'ai trouvé ce projet qui est un proxy (mais plus que je voudrais). Je pourrais vérifier la source mais je voulais vraiment quelque chose de base pour comprendre plus le concept.
ASP Proxy : je pourrais être en mesure d'obtenir quelques informations ici aussi.
réflecteur de requête : exemple simple.
voici un Git Hub Repository avec un simple Proxy Http .
10 réponses
vous pouvez en construire un avec la classe HttpListener
pour écouter les requêtes entrantes et la classe HttpWebRequest
pour relayer les requêtes.
Je n'utiliserais pas HttpListener ou quelque chose comme ça, de cette façon vous rencontrerez tant de problèmes.
le plus important, ce sera une énorme douleur à supporter:
- Mandataire
- SSL ne fonctionne pas (dans le bon sens, vous obtiendrez les pop-up)
- . les bibliothèques réseau suivent strictement les RFC qui provoquent l'échec de certaines requêtes (même si IE, FF et tout autre navigateur dans le monde fonctionneront.)
Ce que vous devez faire est:
- Écouter un port TCP
- analyse la demande du navigateur
- Extrait de l'Hôte connecter à l'hôte au niveau TCP
- faites suivre tout d'avant en arrière sauf si vous voulez ajouter des en-têtes personnalisés, etc.
j'ai écrit 2 mandataires HTTP différents dans .NET avec des exigences différentes et je peux vous dire que c'est le la meilleure façon de le faire.
Mentalis faisant cela, mais leur code est "spaghetti délégué", pire que GoTo:)
peut fonctionner de la manière suivante.
Step1, configurer le client pour qu'il utilise proxyHost:proxyPort.
Proxy est un serveur TCP qui écoute sur proxyHost:proxyPort. Le navigateur ouvre la connexion avec Proxy et envoie la requête Http. Proxy analyse cette requête et tente de détecter l'en-tête "Host". Cet en-tête indiquera à Proxy où ouvrir la connexion.
Étape 2: le mandataire ouvre la connexion à l'adresse spécifiée dans le " Host" tête. Puis il envoie la requête HTTP au serveur distant. Lit la réponse.
Étape 3: Après lecture de la réponse à partir du serveur HTTP distant, Proxy envoie la réponse via une connexion TCP ouverte précédemment avec le navigateur.
Schématiquement, il ressemblera à ceci:
Browser Proxy HTTP server
Open TCP connection
Send HTTP request ----------->
Read HTTP header
detect Host header
Send request to HTTP ----------->
Server
<-----------
Read response and send
<----------- it back to the browser
Render content
j'ai récemment écrit un mandataire poids léger dans C# .net en utilisant TcpListener et TcpClient .
https://github.com/titanium007/Titanium-Web-Proxy
il supporte HTTP sécurisé de la bonne façon, la machine client doit faire confiance au certificat racine utilisé par le mandataire. Prend également en charge le relais WebSockets. Toutes les fonctionnalités de HTTP 1.1 sont supportées sauf pipelining. Le Pipelining est pas utilisé par la plupart des navigateurs modernes, de toute façon. Prend également en charge l'authentification de windows (simple, digest).
vous pouvez brancher votre application en référençant le projet, puis voir et modifier tout le trafic. (Demande et réponse).
en ce qui concerne les performances, Je l'ai testé sur ma machine et travaille sans retard notable.
si vous cherchez juste à intercepter le trafic, vous pouvez utiliser le noyau fiddler pour créer un proxy...
http://fiddler.wikidot.com/fiddlercore
exécuter fiddler d'abord avec l'INTERFACE utilisateur pour voir ce qu'il fait, c'est un proxy qui permet de déboguer le trafic http/https. Il est écrit en c# et a un noyau que vous pouvez construire dans vos propres applications.
gardez à l'esprit que FiddlerCore n'est pas gratuit pour applications commerciales.
les choses sont devenues vraiment faciles avec OWIN et WebAPI. Dans ma recherche D'un serveur C # Proxy, je suis aussi tombé sur ce post http://blog.kloud.com.au/2013/11/24/do-it-yourself-web-api-proxy / . Ce sera la route que je vais prendre.
D'accord avec le dr evil si vous utilisez HTTPListener, vous aurez de nombreux problèmes, vous devez analyser les requêtes et serez engagé à headers et ...
- utiliser l'écouteur tcp pour écouter les requêtes du navigateur
- analyser uniquement la première ligne de la demande et obtenir le domaine hôte et le port pour se connecter
- envoyer l'exacte demande brute à l'hôte trouvé sur la première ligne de la demande de navigateur
- recevoir les données du site cible (j'ai un problème dans cette section)
- envoyer les données exactes reçues de l'hôte au navigateur
vous voyez que vous n'avez même pas besoin de savoir ce qui est dans la demande de navigateur et de l'analyser, seulement obtenir l'adresse du site cible à partir de la première ligne première ligne aime habituellement ce Obtenir http://google.com HTTP1.(1) ou Se CONNECTER facebook.com:443 (c'est pour les demandes ssl)
Socks4 est un protocole très simple à mettre en œuvre. Vous écoutez la connexion initiale, vous vous connectez à l'hôte/port qui a été demandé par le client, vous envoyez le code de succès au client puis vous transférez les flux entrants et sortants à travers les sockets.
si vous allez avec HTTP vous devrez lire et peut-être définir/supprimer certains en-têtes HTTP de sorte que ce soit un peu plus de travail.
si je me souviens bien, SSL fonctionnera sur les serveurs HTTP et Socks proxies. Pour un mandataire HTTP vous implémentez le verbe CONNECT, qui fonctionne un peu comme le socks4 décrit ci-dessus, puis le client ouvre la connexion SSL à travers le flux tcp mandaté.
le navigateur est connecté au proxy de sorte que les données que le proxy reçoit du serveur web sont simplement envoyées via la même connexion que celle initiée par le navigateur au proxy.
j'ai aussi écrit un mandataire inversé simple mais puissant pour asp.net / Web api.
Vous pouvez le trouver ici: https://github.com/SharpTools/SharpReverseProxy
il suffit d'ajouter à votre projet via nuget et vous êtes prêt à aller. Vous pouvez même modifier à la volée la requête, la réponse ou refuser une redirection en raison d'un échec d'authentification.
jetez un oeil au code source, il est vraiment facile à mettre en œuvre :)