Est-il possible de modifier le contenu de HttpRequest POST dans un module IIS HttpModule?

J’ai besoin de modifier le contenu de certaines HttpRequests (chaînes de connexion SSAS) dans IIS. Fondamentalement, je dois append un élément au SOAP contenu dans la demande.

Mon approche a jusqu’ici consisté à append un filtre à la requête HttpRequest et à effectuer le changement dans la méthode de lecture du filtre. Autant que je sache, Read n’est jamais exécuté.

D’après ce que je comprends de Request.Filter, il est lu à partir du moment où IIS traite la demande. IIS doit donc voir ma demande modifiée.

Est-ce que ce que j’essaie de faire est réellement possible avec un HttpModule et mon approche de filtre est-elle correcte?

Si oui, qu’est-ce qui ferait que Read ne soit pas touché?

Voici une version simplifiée de mon code:

public class CustomHttpModule : IHttpModule { private HttpApplication app; public ssortingng ModuleName { get { return "CustomHttpModule"; } } public void Init(HttpApplication context) { app = context; context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); } void context_PreRequestHandlerExecute(object sender, EventArgs e) { var request = app.Context.Request; request.Filter = new CustomHttpFilter(request.Filter); } } public class CustomHttpFilter : Stream { private Stream outputStream; public CustomHttpFilter(Stream outputFilter) { outputStream = outputFilter; } public override int Read(byte[] buffer, int offset, int count) { // read and make the necessary changes } } 

Je ne crois pas qu’il soit possible de modifier la demande avec un module http, mais il est possible de modifier la réponse . L’object HttpRequest est principalement en lecture seule, il est donc généralement immuable dans n’importe quel contexte, pas seulement depuis un module.

Si vous êtes vraiment désespéré, vous pouvez utiliser la reflection pour accéder à davantage d’objects de la requête http. Pour accéder à, modifier ou invoquer des membres non publics, votre processus aurait besoin d’permissions de confiance totale , ce qui présente des risques élevés dans un environnement Web .

En fait, il est possible de modifier le contenu de HttpRequest POST dans IIS via un HttpModule dans IIS 7.0+. J’ai eu ce problème et j’ai pu le résoudre. Je poste pour référence future, car peu de messages décrivent en détail quand / pourquoi cela fonctionnera ou ne fonctionnera pas.

Voici une liste de contrôle pour le dépannage:

  1. Assurez-vous que votre module et tous les autres modules n’accèdent pas à l’object Requête de manière à ce qu’il évalue le stream d’entrée AVANT d’append votre filtre au filtre Requête. Accéder à Request.Form["param"] par exemple déclencherait l’évaluation du stream d’entrée. Un symptôme de ceci est que votre méthode Read filtres n’est jamais appelée.

  2. Examinez l’ordre des événements dans le pipeline IIS unifié https://msdn.microsoft.com/en-us/library/bb470252.aspx . Vous verrez que l’événement PreRequestHandlerExecute se produit comme le 12ème événement PreRequestHandlerExecute . Pour avoir les meilleures chances de définir un filtre de requête et de le faire appliquer, vous devez le faire dans l’événement BeginRequest . Il s’agit du premier événement après la validation de la requête et le mappage d’URL (exposés dans un HttpModule, il en existe d’autres exposés dans une extension ou un filtre ISAPI). . Les filtres et les extensions ISAPI ont certains événements qui peuvent se produire avant les événements HttpModule, mais depuis

  3. Considérez que Request.Filter est une chaîne de stream, ils sont évalués successivement en passant la sortie de l’un à l’entrée du suivant, ils peuvent également modifier la requête avant que votre module ne reçoive l’entrée. En cas de comportement étrange, envisagez de supprimer d’autres filtres pour isoler le problème ou modifier l’ordre de chargement.

  4. Considérez également que les méthodes de lecture et d’écriture de votre filtre de stream sont appelées en morceaux, de sorte qu’elles puissent être appelées plusieurs fois, avec différents décalages. Veillez donc à ce que votre logique de réécriture se comporte correctement, en particulier si vous remplacez du contenu entraînant des tailles de demande ou de réponse globales différentes voir ci-dessous.

  5. Si vous effectuez une recherche / remplacement dans votre lecture ou écriture, vous devez tenir compte du fait que vos données peuvent couvrir plusieurs lectures / écritures. Dans ce cas, vous souhaiterez probablement envisager de mettre en mémoire tampon le stream de demandes ou de réponses dans un MemoryStream et d’opérer à la place.

Si vous isolez et simplifiez le problème jusqu’au scénario le plus élémentaire, vous identifierez éventuellement ce qui le gêne. L’exemple simple présenté ici montre https://msdn.microsoft.com/en-us/library/system.web.httprequest.filter.aspx, mais il ne montre pas qu’il fonctionne sur un stream mis en mémoire tampon.

J’ai mis en place un exemple de démonstration d’une demande et d’une réponse en mémoire tampon, qui réécrit HttpModule à titre de référence. https://github.com/snives/HttpModuleRewrite

C’est possible en remplaçant WorkerRequest. Vous pouvez obtenir la demande de travailleur actuelle comme ci-dessous:

 (HttpWorkerRequest)context.GetService(typeof(HttpWorkerRequest)) 

Et vous pouvez implémenter une demande de travail dérivée en référençant la source de référence IIS7WorkerRequest.cs .net

La partie la plus difficile consiste à lire tous les octets du stream d’entrée et à parsingr les données. Vous devez connaître la spécification de données HTTP Multipart-Form.