Blog Stats
  • Posts - 7
  • Articles - 0
  • Comments - 319
  • Trackbacks - 5

 

lunedì 27 giugno 2005

Richieste Http e Proxy

In questo post vediamo come poter scrivere del codice C# per effettuare richieste Http da un'applicazione.
I problemi che si possono incontrare in queste richieste Http possono essere soprattutto relativi al Proxy, in quanto non
permette all'applicazione di effettuare richieste internet.

Per prima cosa vediamo quali sono le classi che verranno utilizzate:

using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Text;

Nel mio progetto ho inserito un oggetto Button e quando questo viene premuto viene richiamato l'evento click che effettua la richiesta Http. Questo è il codice:

private void button2_Click(object sender, System.EventArgs e)
{
string valVerifica= "";
try
{
//Indirizzo dell'url Http o Https
string urlRegistro = @http://www......;

HttpWebRequest wrInfoCam =(HttpWebRequest) HttpWebRequest.Create(urlRegistro);
wrInfoCam.KeepAlive = false;

//La proprietà KeepAlive a false permette di NON impostare connessione persistenti ai server che
//le supportano.

//IMPOSTAZIONI PROXY.
//questa parte di codice può essere omessa nel caso non si utilizzi un proxy

//Definizione credenziali
NetworkCredential cred = new NetworkCredential("sara", "xxx");

CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri("
http://master.lan.xxxx.it:8080/"), "Basic", cred);

WebProxy _proxy = new WebProxy();
_proxy = (WebProxy)(wrInfoCam.Proxy);

Uri _uri = new Uri("http://master.lan.xxxx.it:8080/");
_proxy.Address = _uri;
_proxy.Credentials = myCache;

wrInfoCam.Proxy = _proxy;
//FINE IMPOSTAZIONE PROXY

RequestStateHttp reqState = new RequestStateHttp();
reqState.request = wrInfoCam;

reqState.request.Method="POST";
wrInfoCam.ContentType= "application/x-www-form-urlencoded";

IAsyncResult result =(IAsyncResult) (wrInfoCam.BeginGetRequestStream(new AsyncCallback(ReadCallbackHttp), reqState));

//Attendo la risposta del sito http o https mediante l'oggetto HttpWebResponse.
HttpWebResponse myHttpWebResponse=(HttpWebResponse) (wrInfoCam.GetResponse());

Stream streamResponse=myHttpWebResponse.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
char [] readBuff = new Char[256];
int count = streamRead.Read(readBuff, 0, 256);

while (count > 0)
{
valVerifica = new String(readBuff, 0, count);
count = streamRead.Read(readBuff, 0, 256);
}
streamResponse.Close();
streamRead.Close();
myHttpWebResponse.Close();

MessageBox.Show(valVerifica);

}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

A questo punto manca da definire la nostra classe RequestStateHttp, che consente di passare i dati su chiamate asincrone:

public class RequestStateHttp
{
 static int BUFFER_SIZE = 1024;

 public StringBuilder requestData;
 public Byte [] bufferRead;
 public HttpWebRequest  request;
 public HttpWebResponse  response;
 public Stream responseStream;

 public RequestStateHttp()
 {
  bufferRead = new Byte[BUFFER_SIZE];
  requestData = new StringBuilder("");
  request = null;
  responseStream = null;
 }
}

E rimane da definire il metodo ReadCallbackHttp che consente di implementare il metodo di callback asincrono per la lettura del flusso di risposta. I dati ricevuti dalla risorsa Internet vengono trasferiti nella proprietà ResponseData dell'istanza di RequestStateHttp, quindi si inizia un'altra lettura asincrona del flusso di risposta finché non viene più restituito alcun dato.

void ReadCallbackHttp(IAsyncResult async)
{
 try
 {
  RequestStateHttp myRequestState=(RequestStateHttp)(async.AsyncState);
  HttpWebRequest myHttpWebRequest2=(HttpWebRequest)(myRequestState.request);
    
  Stream postStream=myHttpWebRequest2.EndGetRequestStream(async);

  ASCIIEncoding encoder = new ASCIIEncoding();

  string parametriUrl = "...eventuali parametri da passare all'url...";
  //se ci sono più parametri richiesti da passare all'url allora è necessario utilizzare l'&, ovvero:
  //"USer=xx&Password=yy"

  Byte [] byteArray = encoder.GetBytes(parametriUrl);

  postStream.Write(byteArray,0,parametriUrl.Length);
  postStream.Close();
 }
 catch (Exception ex)
 {
  MessageBox.Show(ex.ToString());
 }
}

Tutto il codice qui inserito è testato e funzionante.
Se avete un proxy impostato sulla vostra rete e durante l'esecuzione del codice nel metodo ReadCallBackHttp, nel metodo EndGetRequestStream si genera un'eccezione del tipo "Connessione sottostate chiusa. Errore 407: Autenticazione Proxy mancante" ci possono essere due tipo di errori principalmente:
1. i dati relativi all'indirizzo del proxy o le credenziali sono errate. Per es. l'indirizzo del proxy deve essere scritto come:
http://master.lan.xxxx.it, mentre l'uri dev'essere nel formato: http://master.lan.xxxx.it:PORTA/.

2. Il proxy utilizza due tipi di autenticazione, quella Basic e quella NTLM ovvero autenticazione windows. Ho potuto notare che la sola autenticazione Basic settata, la richiesta all'indirizzo http/https funziona correttamente, mentre se è settata anche l'autenticazione NTLM ci possono essere dei problemi con le credenziali, che possono non venire riconosciute.

 

P.S: Questo post l'ho potuto scrivere anche grazie all'aiuto di Gabriele Gaggi che mi ha aiutato nella risoluzione del problema. Quindi un doveroso grazie va anche a lui!!!

 

 

Copyright © Sara Fabris