web-dev-qa-db-fra.com

Comment créer un proxy simple en C #?

J'ai téléchargé Privoxy il y a quelques semaines et, pour le plaisir, j'étais curieux de savoir comment en faire une version simple.

Je comprends que je dois configurer le navigateur (client) pour envoyer une demande au proxy. Le proxy envoie la demande au Web (disons que c'est un proxy http). Le proxy recevra la réponse ... mais comment le proxy peut-il renvoyer la demande au navigateur (client)?

J'ai cherché sur le Web des proxy C # et http, mais je n'ai pas trouvé quelque chose qui me permette de comprendre comment cela fonctionne correctement dans les coulisses. (Je crois que je ne veux pas de proxy inverse mais je ne suis pas sûr).

Est-ce que certains d'entre vous ont des explications ou des informations qui me permettront 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 que toute demande soit envoyée à 127.0.0.1 sur le port que le proxy écoute. De cette façon, la demande ne sera pas envoyée directement à Internet, mais sera traitée par le proxy.

Step2 Le proxy 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.

Etape 3 Le proxy reçoit une réponse de la demande. Maintenant, il doit envoyer la réponse du Web au client, mais comment ???

alt text

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 fondamental pour mieux comprendre le concept.

Proxy ASP : Je pourrais peut-être obtenir des informations ici aussi.

Demande de réflecteur : Ceci est un exemple simple.

Voici un référentiel Git Hub avec un proxy HTTP simple .

137
Patrick Desjardins

Vous pouvez en créer un avec la classe HttpListener pour écouter les demandes entrantes et la classe HttpWebRequest pour relayer les demandes.

33
Mark Cidade

Je ne voudrais pas utiliser HttpListener ou quelque chose comme ça, de cette façon vous rencontrerez tellement de problèmes.

Plus important encore, ce sera une douleur énorme à supporter:

  • Proxy Keep-Alives
  • SSL ne fonctionnera pas (de manière correcte, vous obtiendrez des popups)
  • Les bibliothèques .NET suivent strictement les RFC, ce qui entraîne l’échec de certaines demandes (même si IE, FF et tout autre navigateur dans le monde fonctionneront.)

Ce que vous devez faire c'est:

  • Écoutez un TCP port
  • Analyser la requête du navigateur
  • Extraire l'hôte se connecter à cet hôte dans TCP niveau
  • Tout transférer en avant sauf si vous souhaitez ajouter des en-têtes personnalisés, etc.

J'ai écrit 2 proxy HTTP différents dans .NET avec des exigences différentes et je peux vous dire que c'est la meilleure façon de le faire.

Mentalis le fait, mais leur code est "délégué spaghetti", pire que GoTo :)

86
dr. evil

J'ai récemment écrit un proxy léger en c # .net en utilisant TcpListener et TcpClient .

https://github.com/titanium007/Titanium-Web-Proxy

Il prend correctement en charge le protocole HTTP sécurisé. La machine cliente doit approuver le certificat racine utilisé par le proxy. Prend également en charge le relais WebSockets. Toutes les fonctionnalités de HTTP 1.1 sont prises en charge sauf le traitement en pipeline. Le pipelining n'est de toute façon pas utilisé par la plupart des navigateurs modernes. Prend également en charge l'authentification Windows (plain, digest).

Vous pouvez connecter 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 fonctionne sans retard notable.

22
justcoding121

Le proxy peut fonctionner de la manière suivante.

Étape 1, configurez le client pour utiliser proxyHost: proxyPort.

Le proxy est un serveur TCP qui écoute sur proxyHost: proxyPort. Le navigateur ouvre la connexion avec le proxy et envoie une requête HTTP. Le proxy analyse cette requête et essaie de détecter l'en-tête "Host". Cet en-tête indiquera au proxy où ouvrir la connexion.

Étape 2: Le proxy ouvre la connexion à l'adresse spécifiée dans l'en-tête "Host". Ensuite, il envoie une requête HTTP à ce serveur distant. Lit la réponse.

Étape 3: une fois que la réponse est lue à partir du serveur HTTP distant, le proxy envoie la réponse via une connexion TCP précédemment ouverte avec le navigateur.

Schématiquement, cela 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
19
Vadym Stetsiak

Si vous souhaitez simplement intercepter le trafic, vous pouvez utiliser le noyau de violoniste pour créer un proxy ...

http://fiddler.wikidot.com/fiddlercore

lancer fiddler d’abord avec l’interface utilisateur pour voir ce qu’il fait, c’est un proxy qui vous permet de déboguer le trafic http/https. Il est écrit en c # et comporte un noyau que vous pouvez intégrer à vos propres applications.

Gardez à l'esprit que FiddlerCore n'est pas gratuit pour les applications commerciales.

14
Dean North

Les choses sont devenues vraiment faciles avec OWIN et WebAPI. Dans ma recherche d'un serveur proxy C #, je suis également tombé sur ce message http://blog.kloud.com.au/2013/11/24/do-it-yourself-web-api-proxy/ . Ce sera la route que je prends.

6
Jochen van Wylick

Acceptez dr dr si vous utilisez HTTPListener vous aurez beaucoup de problèmes, vous devrez analyser les requêtes et vous serez engagé dans les en-têtes et ...

  1. Utilisez tcp listener pour écouter les requêtes du navigateur
  2. analyser uniquement la première ligne de la demande et obtenir le domaine et le port de l'hôte pour se connecter
  3. envoie la requête brute exacte à l'hôte trouvé sur la première ligne de la requête du navigateur
  4. recevoir les données du site cible (j'ai un problème dans cette section)
  5. 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 se trouve dans la requête du navigateur et de l'analyser; vous devez uniquement obtenir l'adresse du site cible à partir de la première ligne. La première ligne aime généralement ceci GET http://google.com HTTP1. 1 ou CONNECT facebook.com:443 (il s’agit de demandes SSL)

5
Alireza Rinan

Socks4 est un protocole très simple à mettre en œuvre. Vous écoutez la connexion initiale, connectez-vous à l'hôte/port demandé par le client, envoyez le code de réussite au client, puis transférez les flux sortant et entrant sur des sockets.

Si vous utilisez HTTP, vous devrez lire et éventuellement définir/supprimer certains en-têtes HTTP, ce qui représente un peu plus de travail.

Si je me souviens bien, SSL fonctionnera sur les proxys HTTP et Socks. Pour un proxy HTTP, vous implémentez le verbe CONNECT, qui fonctionne de la même manière que socks4, comme décrit ci-dessus, puis le client ouvre la connexion SSL via le flux TCP proxy.

4
C.M.

Le navigateur est connecté au proxy afin que les données qu'il récupère du serveur Web soient simplement envoyées via la même connexion que celle que le navigateur a initialisée au proxy.

2
Stephen Caldwell