2009-08-06 8 views
6

J'essaie d'utiliser la classe System.Net.HttpWebRequest pour exécuter une requête HTTP GET sur un serveur Web spécifique pour des applications Web dont la charge est équilibrée sur de nombreux serveurs. Pour y parvenir, je dois pouvoir définir la valeur de l'en-tête Host pour la requête, et j'ai pu y parvenir en utilisant la classe System.Net.WebProxy.Comment définir une valeur d'en-tête Host pour les demandes SSL à l'aide de HttpWebRequest

Cependant, tout cela se décompose lorsque j'essaie d'effectuer un GET en utilisant le protocole SSL. Lorsque j'essaie de faire cela, l'appel à HttpWebRequest.GetResponse génère une exception System.Net.WebException, avec un code d'état HTTP de 400 (demande incorrecte).

Est ce que j'essaye de réaliser avec HttpWebRequest, ou devrais-je chercher une manière alternative d'exécuter ce que je veux?

Voici le code que je l'ai utilisé pour essayer d'obtenir tout cela au travail: -

using System; 
using System.Web; 
using System.Net; 
using System.IO; 

namespace UrlPollTest 
{ 
    class Program 
    { 
     private static int suffix = 1; 
     static void Main(string[] args) 
     { 
      PerformRequest("http://www.microsoft.com/en/us/default.aspx", "www.microsoft.com"); 
      PerformRequest("https://www.microsoft.com/en/us/default.aspx", ""); 
      PerformRequest("https://www.microsoft.com/en/us/default.aspx", "www.microsoft.com"); 

      Console.WriteLine("Press any key to continue"); 
      Console.ReadKey(); 
     } 

     static void PerformRequest(string AUrl, string AProxy) 
     { 
      Console.WriteLine("Fetching from {0}", AUrl); 
      try 
      { 
       HttpWebRequest request = WebRequest.Create(AUrl) as HttpWebRequest; 
       if (AProxy != "") 
       { 
        Console.WriteLine("Proxy = {0}", AProxy); 
        request.Proxy = new WebProxy(AProxy); 
       } 

       WebResponse response = request.GetResponse(); 
       using (Stream httpStream = response.GetResponseStream()) 
       { 
        using (StreamReader reader = new StreamReader(httpStream)) 
        { 
         string s = reader.ReadToEnd(); 
         File.WriteAllText(string.Format("D:\\Temp\\Response{0}.html", suffix++), s); 
        } 
       } 
       Console.WriteLine(" Success"); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(" " + e.Message); 
      } 
     } 
    } 
} 
+0

Véritable question: Comment savez-vous que vous avez besoin d'un en-tête d'hôte? "Les en-têtes d'hôte HTTP 1.1 ne sont pas pris en charge lorsque vous utilisez SSL" http://support.microsoft.com/kb/187504. – russau

+0

Deuxième réflexion: pouvez-vous obtenir le fichier sur SSL dans un navigateur? – russau

+1

Je dois définir un en-tête Host afin que je puisse spécifier le serveur exact à atteindre si l'application Web est équilibrée sur plusieurs serveurs. Ce code fait partie d'un cadre de surveillance et de test Web que j'écris. Et oui, les requêtes SSL que j'essaie de faire fonctionnent dans le navigateur, donc le problème réside quelque part dans la façon dont j'essaie d'implémenter des fonctionnalités similaires dans le code. L'article que vous avez lié suggère que la prise en charge de l'en-tête Host pour les demandes SSL a été rendue disponible dans Windows Server 2003 SP1 et que tous nos serveurs doivent être entièrement corrigés. – Cleggy

Répondre

2

Je l'ai utilisé une approche hacky avant - d'avoir un exe de test qui modifie mes « hôtes » fichier, en injectant une entrée pour le nom de la ferme à l'adresse du serveur spécifique (et en émettant un ipconfig /flushdns). Après cela, les requêtes devraient être routées vers le bon serveur comme si c'était le seul.

Évidemment, cela nécessite un accès administrateur ... Je l'utilise dans le cadre d'un test de fumée automatisé pour frapper la ferme comme s'il s'agissait de machines individuelles.

L'autre chose que vous pouvez essayer est quelque chose sur le NLB, peut-être dans TCL (dans le cas de F5) - peut-être ajouter un en-tête personnalisé que le NLB comprend? (en supposant qu'il fait une nouvelle signature SSL).

+0

Merci pour la suggestion, mais cela ne fonctionnera pas pour nous. Nous exécuterons plusieurs threads en même temps, et il pourrait certainement y avoir des conflits d'entrée HOSTS dans ce scénario. –

0

Dans .NET 4.0, l'en-tête Host peut être défini indépendamment de l'URL vers laquelle la requête va, aussi je vous recommande d'utiliser HttpwebRequest.Host pour résoudre votre problème. Cela (je pense) sera livré dans le cadre de .NET 4.0 beta2. Il n'y a AUCUN moyen de réécrire l'en-tête de l'hôte pour être différent sous les versions précédentes de .Net sans implémenter votre propre sous-classe personnalisée de WebRequest (croyez-moi, ça a été essayé).

Questions connexes