Можно ли изменить содержимое POST HttpRequest в HttpModule IIS? - PullRequest
7 голосов
/ 17 июня 2010

Мне нужно изменить содержимое определенных HttpRequests (строки подключения SSAS) в IIS. По сути, мне нужно добавить элемент в SOAP, содержащийся в запросе.

До сих пор мой подход заключался в добавлении фильтра в запрос HttpRequest и внесении изменений в метод чтения фильтра. Однако, насколько я могу судить, Read никогда не выполняется.

Насколько я понимаю, Request.Filter заключается в том, что он читается, когда IIS обрабатывает запрос, поэтому IIS должен видеть мой измененный запрос.

Возможно ли то, что я пытаюсь сделать, с помощью HttpModule и правильный ли мой подход к фильтру?

Если это так, что может привести к тому, что Read не ударится?

Вот упрощенная версия моего кода:


public class CustomHttpModule : IHttpModule {
    private HttpApplication app;
    public string 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
    }
}

Ответы [ 3 ]

2 голосов
/ 24 февраля 2016

На самом деле, возможно изменить содержимое POST HttpRequest в IIS через HttpModule в IIS 7.0+. У меня была эта проблема, и я смог ее решить. Я пишу для дальнейшего использования, потому что не так много постов, в которых подробно описано, когда / почему это будет или не будет работать.

Вот контрольный список для устранения неисправностей:

  1. Убедитесь, что ваш модуль и любые другие модули не обращаются к объекту запроса таким образом, чтобы он оценил входной поток ПРИЛОЖЕНИЕ для добавления вашего фильтра в фильтр запроса. Например, доступ к Request.Form["param"] вызовет оценку входного потока. Одним из симптомов этого является то, что ваш фильтр Read метод никогда не вызывается.

  2. Посмотрите на порядок событий в объединенном конвейере IIS. https://msdn.microsoft.com/en-us/library/bb470252.aspx.. Вы увидите, что событие PreRequestHandlerExecute происходит так же, как и 12-ое событие. Чтобы иметь наилучшие шансы установить фильтр запроса и применить его, вы должны сделать это в событии BeginRequest, это первое событие после проверки запроса и сопоставления URL-адреса (предоставляется в HttpModule, есть другие, представленные в расширении ISAPI или фильтр). Фильтры и расширения ISAPI имеют некоторые события, которые могут произойти до событий HttpModule, но с

  3. Учтите, что Request.Filter представляет собой цепочку потоков, они оцениваются последовательно, передавая выходные данные от одного к входу следующего, они также могут изменять запрос до того, как ваш модуль получит входные данные. Если есть какое-то странное поведение, рассмотрите возможность удаления некоторых других фильтров, чтобы изолировать проблему или изменить порядок их загрузки.

  4. Также обратите внимание, что методы чтения и записи вашего потокового фильтра вызываются порциями, поэтому их можно вызывать несколько раз с разными смещениями, поэтому убедитесь, что логика перезаписи работает правильно, особенно если вы заменяете контент, что приводит к различные общие размеры запросов или ответов см. ниже.

  5. Если вы выполняете поиск / замену в своих операциях чтения или записи, необходимо учитывать, что ваши данные могут охватывать несколько операций чтения / записи. В этом случае вы, вероятно, захотите рассмотреть возможность буферизации потока запросов или ответов в MemoryStream и использовать его вместо этого.

Если вы изолируете и упростите проблему до ее самого основного сценария, вы в конечном итоге определите, что заставляет ее не работать. Простой пример здесь демонстрирует https://msdn.microsoft.com/en-us/library/system.web.httprequest.filter.aspx, но не демонстрирует работу с буферизованным потоком.

Я собрал пример, демонстрирующий буферизованный запрос и переписанный ответ HttpModule для справки. https://github.com/snives/HttpModuleRewrite

1 голос
/ 09 мая 2014

Это возможно путем переопределения WorkerRequest. Вы можете получить текущий запрос работника, как показано ниже:

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

И вы можете реализовать производный рабочий запрос, ссылаясь на источник справочной информации IIS7WorkerRequest.cs .net.

Жесткая часть считывает все байты из входного потока и анализирует данные. Вы должны знать спецификацию данных HTTP Multipart-form.

0 голосов
/ 17 июня 2010

Я не верю, что можно изменить запрос с помощью модуля http, однако можно изменить ответ .Объект HttpRequest в основном доступен только для чтения, поэтому он обычно неизменен в любом контексте, а не только из модуля.

Если вы действительно впали в отчаяние, вы можете попробовать использовать отражение, чтобы получить доступ к большей части объекта http-запроса.Однако для доступа, изменения или вызова непубличных участников вашему процессу потребуются полное доверие разрешения, , что очень рискованно в веб-среде .

...