2009-11-05 4 views
4

J'essaie de trouver le moyen le plus approprié pour établir une connexion bidirectionnelle via un proxy HTTP - disons qu'il s'agit d'un protocole de type telnet. Malheureusement, je dois également prendre en charge l'authentification NTLM (avec le proxy) ainsi que Basic et Digest, en plus de tous les autres mécanismes d'authentification futurs que je ne peux pas prévoir.Communication bidirectionnelle via un proxy HTTP

Si c'était juste basique et que je digérerais, je gérerais la connexion moi-même, mais je ne veux vraiment pas rester coincé dans la fange qu'est NTLM. En regardant l'API AuthenticationManager sous-jacente, il semble très lié à HttpWebRequest, donc je ne peux pas tirer parti de cette fonctionnalité si j'utilise un socket/tcpclient/whatever ou même écrire une nouvelle dérivation WebRequest.

Jouer avec HttpWebResponse génère un flux qui ne peut pas être écrit, en utilisant le RequestStream après que le flux de réponse a été récupéré donne une exception io simultanée.

Après avoir couru à travers toutes les possibilités que je peux penser, je suis venu avec un code méchant qui sort NetworkStream associé à un HttpWebRequest qui permet une communication bidirectionnelle:

..... 
    HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); 
    Stream str = resp.GetResponseStream(); 

    System.Type type = str.GetType(); 
    PropertyInfo info = type.GetProperty("Connection", BindingFlags.NonPublic|BindingFlags.Instance| BindingFlags.Public); 
    object obj = info.GetValue(str, null); 
    type = obj.GetType(); 
    info = type.GetProperty("NetworkStream", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); 
    object obj2 = info.GetValue(obj, null); 
    NetworkStream networkStream = obj2 as NetworkStream; 

Ce que je suis assez repoussé par (cela ne marchera pas avec Mono pour commencer), je me demande s'il y a une meilleure façon d'utiliser les API publiques, ce qui me permettra de tirer parti de la fonctionnalité d'exécution intégrée de l'authentification proxy.

Répondre

2

HTTP est bidirectionnel. Les clients peuvent envoyer une requête sans données à l'aide de HTTP GET (même si les données peuvent être placées dans l'URL ou les en-têtes) ou envoyer des données via HTTP POST et envoyer une réponse avec des en-têtes et des données.

Si vous dites «bidirectionnel», vous pensiez plutôt à un simple socket TCP où le client et le serveur lisent et écrivent à volonté, alors désolé, mais ce n'est pas ce que fait le protocole HTTP. Le client envoie une requête et le serveur détecte une réponse. C'est tout. Techniquement, si vous n'aviez pas une API côté client qui gênait les contraintes de HTTP, et que vous pouviez créer votre propre serveur non-standard, vous pouviez avoir plusieurs échanges de serveurs < -> dans un seul HTTP demande, mais à ce stade ce ne serait plus vraiment HTTP, ce serait une connexion TCP avec une poignée de main comme HTTP, et votre proxy pourrait même ne pas l'autoriser. Cela dit, il semble que vous n'ayez pas vraiment besoin d'écrire dans le flux de réponse, soit vous êtes assez confus et vous avez juste besoin de faire un POST (voir GetRequestStream), ou vous êtes juste un peu confus et vous pouvez simplement envoyer une nouvelle demande après avoir traité la réponse. Vous pouvez même réutiliser la même instance HttpWebRequest une fois que vous avez appelé la méthode .Close sur WebResponse. Et tout cela arrivera sur le même socket TCP (si votre serveur et votre proxy le supportent).

Bon, j'espère que tout a un sens. S'il n'a pas répondu à votre question d'une façon ou d'une autre, donnez simplement un peu plus de détails sur ce que vous essayez d'accomplir en ce qui concerne la communication «bidirectionnelle». Je comprends que vous avez la contrainte de passer par un proxy HTTP avec des exigences d'authentification HTTP ce qui limite beaucoup les choses.