Come creare un semplice proxy in C #?

Ho scaricato Privoxy poche settimane fa e per il divertimento ero curioso di sapere come si può fare una semplice versione di esso.

Capisco che ho bisogno di configurare il browser (client) per inviare la richiesta al proxy. Il proxy invia la richiesta al web (diciamo che è un proxy http). Il proxy riceverà la risposta … ma come può il proxy rimandare la richiesta al browser (client)?

Ho una ricerca sul web per C # e proxy http ma non ho trovato qualcosa che mi faccia capire come funziona correttamente dietro la scena. (Credo di non volere un proxy inverso ma non ne sono sicuro).

Qualcuno di voi ha qualche spiegazione o alcune informazioni che mi permetteranno di continuare questo piccolo progetto?

Aggiornare

Questo è ciò che capisco (vedi grafico sotto).

Passo 1 Configuro il client (browser) per tutte le richieste da inviare a 127.0.0.1 nella porta che il Proxy ascolta. In questo modo, la richiesta non verrà inviata direttamente a Internet ma verrà elaborata dal proxy.

Passaggio 2 Il proxy visualizza una nuova connessione, legge l’intestazione HTTP e visualizza la richiesta che deve eseguire. Esegue la richiesta.

Passaggio 3 Il proxy riceve una risposta dalla richiesta. Ora deve inviare la risposta dal web al cliente ma come ???

alt text

Collegamento utile

Mentalis Proxy : ho trovato questo progetto che è un proxy (ma più che vorrei). Potrei controllare la fonte ma volevo davvero qualcosa di basilare per capire di più il concetto.

Proxy ASP : potrei essere in grado di ottenere alcune informazioni anche qui.

Reflector di richiesta : questo è un semplice esempio.

Ecco un repository Git Hub con un semplice proxy Http .

È ansible HttpListener uno con la class HttpListener per ascoltare le richieste in arrivo e la class HttpWebRequest per inoltrare le richieste.

Non userei HttpListener o qualcosa del genere, in questo modo incontrerai così tanti problemi.

Ancora più importante sarà un enorme dolore da sostenere:

  • Proxy Keep-Alives
  • SSL non funzionerà (in modo corretto, riceverai popup)
  • Le librerie .NET seguono rigorosamente le RFC che fanno fallire alcune richieste (anche se IE, FF e qualsiasi altro browser nel mondo funzioneranno).

Quello che devi fare è:

  • Ascolta una porta TCP
  • Analizza la richiesta del browser
  • Estrai host si connettono a quell’host in livello TCP
  • Inoltra tutto avanti e indietro a meno che tu non voglia aggiungere intestazioni personalizzate, ecc.

Ho scritto 2 diversi proxy HTTP in .NET con requisiti diversi e posso dirvi che questo è il modo migliore per farlo.

Mentalis sta facendo questo, ma il loro codice è “delegate spaghetti”, peggio di GoTo 🙂

Proxy può funzionare nel modo seguente.

Passaggio 1, configurare il client per utilizzare proxyHost: proxyPort.

Proxy è un server TCP in ascolto su proxyHost: proxyPort. Il browser apre la connessione con Proxy e invia la richiesta Http. Il proxy analizza questa richiesta e tenta di rilevare l’intestazione “Host”. Questa intestazione indicherà a Proxy dove aprire la connessione.

Passaggio 2: Proxy apre la connessione all’indirizzo specificato nell’intestazione “Host”. Quindi invia la richiesta HTTP a quel server remoto. Legge la risposta.

Passo 3: Dopo la risposta viene letto dal server HTTP remoto, Proxy invia la risposta attraverso una connessione TCP aperta in precedenza con il browser.

Schematicamente sarà simile a questo:

 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 

Recentemente ho scritto un proxy leggero in c # .net usando TcpListener e TcpClient .

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

Supporta l’HTTP sicuro nel modo corretto, la macchina client deve avere fiducia nel certificato radice usato dal proxy. Supporta anche il relè WebSockets. Sono supportate tutte le funzionalità di HTTP 1.1 tranne il pipelining. Il pipelining non è comunque utilizzato dalla maggior parte dei browser moderni. Supporta anche l’autenticazione di Windows (plain, digest).

È ansible colbind l’applicazione facendo riferimento al progetto e quindi vedere e modificare tutto il traffico. (Richiesta e risposta).

Per quanto riguarda le prestazioni, l’ho testato sulla mia macchina e funziona senza alcun ritardo evidente.

Se stai solo cercando di intercettare il traffico, potresti usare il nucleo del violinista per creare un proxy …

http://fiddler.wikidot.com/fiddlercore

eseguire prima il violinista con l’interfaccia utente per vedere cosa fa, è un proxy che consente di eseguire il debug del traffico http / https. È scritto in C # e ha un core che puoi creare nelle tue applicazioni.

Ricorda che FiddlerCore non è gratuito per applicazioni commerciali.

Le cose sono diventate davvero facili con OWIN e WebAPI. Nella mia ricerca di un server proxy C #, ho anche trovato questo post http://blog.kloud.com.au/2013/11/24/do-it-yourself-web-api-proxy/ . Questa sarà la strada che sto percorrendo.

Accetta il dr male se usi HTTPListener avrai molti problemi, devi analizzare le richieste e sarai coinvolto nelle intestazioni e …

  1. Usa listener tcp per ascoltare le richieste del browser
  2. analizzare solo la prima riga della richiesta e ottenere il dominio host e la porta da connettere
  3. inviare la richiesta esatta esatta all’host trovato sulla prima riga della richiesta del browser
  4. ricevere i dati dal sito di destinazione (ho un problema in questa sezione)
  5. inviare i dati esatti ricevuti dall’host al browser

vedi che non devi nemmeno sapere cosa c’è nella richiesta del browser e analizzarlo, solo ottenere l’indirizzo del sito di destinazione dalla prima linea di solito la linea di solito piace GET http://google.com HTTP1.1 o CONNECT facebook.com: 443 (questo è per le richieste SSL)

Socks4 è un protocollo molto semplice da implementare. Si ascolta la connessione iniziale, si connette all’host / porta richiesto dal client, si invia il codice di successo al client, quindi si inoltrano i flussi in uscita e in entrata tra i socket.

Se vai con HTTP dovrai leggere e possibilmente impostare / rimuovere alcune intestazioni HTTP in modo che sia un po ‘più di lavoro.

Se ricordo male, SSL funzionerà su proxy HTTP e Socks. Per un proxy HTTP si implementa il verbo CONNECT, che funziona molto come il socks4 come descritto sopra, quindi il client apre la connessione SSL attraverso il stream tcp proxy.

Il browser è connesso al proxy in modo che i dati che il proxy ottiene dal server Web vengano inviati semplicemente tramite la stessa connessione avviata dal browser al proxy.

Ho anche scritto un proxy inverso semplice ma potente per asp.net / web api.

Puoi trovarlo qui: https://github.com/SharpTools/SharpReverseProxy

Basta aggiungere al tuo progetto via nuget e sei a posto. È anche ansible modificare al volo la richiesta, la risposta o negare un inoltro a causa di un errore di autenticazione.

Dai un’occhiata al codice sorgente, è davvero facile da implementare 🙂