Можно ли вызвать API IIS 7+ setUrl из управляемого HttpModule? - PullRequest
0 голосов
/ 02 ноября 2010

Что мне в основном нужно, так это управлять большим набором переписываний и перенаправлений URL.Перенаправление легко сделать, но перезапись должна осуществляться через прокси-сервер ARR в IIS.Насколько я могу судить, модуль перезаписи IIS использует собственный API setUrl в IIS, чтобы прокси-сервер ARR переадресовал запрос.У меня нет задачи по написанию собственного модуля, поэтому я подумал, что возможно написать управляемый модуль для того же самого.

@ CarlosAg: Просто чтобы расширить мой комментарий к вашему ответу.Вот правила и провайдеры, которые мне нужно настроить, чтобы заставить модуль перезаписи делать то, что я хочу.Это только я или не похоже на манипулирование модулем перезаписи, чтобы сделать что-то, чего он не должен был делать?

<rewrite>
  <providers>
    <provider name="CustomRewrite" type="MyRewriteProviders.RewriteProvider, MyRewriteProviders, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e72501f8a0edfe78" />
    <provider name="CustomRedirectTemporary" type="MyRewriteProviders.RedirectTemporaryProvider, MyRewriteProviders, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e72501f8a0edfe78" />
    <provider name="CustomRedirectPermanent" type="MyRewriteProviders.RedirectPermanentProvider, MyRewriteProviders, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e72501f8a0edfe78" />
  </providers>
  <rules>
    <clear />
    <rule name="Set Http">
      <match url="." />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
      <serverVariables>
        <set name="RequestProtocol" value="http" />
      </serverVariables>
      <action type="None" />
    </rule>
    <rule name="Set Https">
      <match url="." />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTPS}" pattern="ON" />
      </conditions>
      <serverVariables>
        <set name="RequestProtocol" value="https" />
      </serverVariables>
      <action type="None" />
    </rule>
    <rule name="Custom Rewrite">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{CustomRewrite:{RequestProtocol}://{HTTP_HOST}/{URL}}" pattern="(.+)" />
      </conditions>
      <action type="Rewrite" url="{C:1}" logRewrittenUrl="true" />
    </rule>
    <rule name="Custom Redirect (Temporary)" stopProcessing="true">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{CustomRedirectTemporary:{RequestProtocol}://{HTTP_HOST}/{URL}}" pattern="(.+)" />
      </conditions>
      <action type="Redirect" url="{C:1}" redirectType="Found" appendQueryString="false" />
    </rule>
    <rule name="Custom Redirect (Permanent)" stopProcessing="true">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{CustomRedirectPermanent:{RequestProtocol}://{HTTP_HOST}/{URL}}" pattern="(.+)" />
      </conditions>
      <action type="Redirect" url="{C:1}" appendQueryString="false" />
    </rule>
  </rules>
</rewrite>

И код провайдера:

using System;
using System.Collections.Generic;
using Microsoft.Web.Iis.Rewrite;

namespace MyRewriteProviders
{
    public enum ActionType
    {
        Rewrite,
        RedirectPermanent,
        RedirectTemporary
    }

    public abstract class BaseProvider : IRewriteProvider
    {
        protected abstract ActionType Action { get; }

        public void Initialize(IDictionary<string, string> settings, IRewriteContext rewriteContext) {}

        public string Rewrite(string value)
        {
            return RewriteEngine.RewriteUri(value, ActionType.Rewrite);
        }
    }

    public class RewriteProvider : BaseProvider
    {
        protected override ActionType Action
        {
            get { return ActionType.Rewrite; }
        }
    }

    public class RedirectTemporaryProvider : BaseProvider
    {
        protected override ActionType Action
        {
            get { return ActionType.RedirectTemporary; }
        }
    }

    public class RedirectPermanentProvider : BaseProvider
    {
        protected override ActionType Action
        {
            get { return ActionType.RedirectPermanent; }
        }
    }

    public static class RewriteEngine
    {
        public static string RewriteUri(string uri, ActionType action)
        {
            // Not actual rule engine implementation... just to demonstrate what it would do.
            var ub = new UriBuilder(uri);

            // Simulate a match on a rewrite rule
            if (string.Equals(ub.Host, "rewrite.com", StringComparison.InvariantCultureIgnoreCase) && action == ActionType.Rewrite)
            {
                ub.Host = "rewrite-rewritten.com";
                return ub.ToString();
            }

            // Simulate a match on a temporary redirect rule
            if (string.Equals(ub.Host, "redirect.com", StringComparison.InvariantCultureIgnoreCase) && action == ActionType.RedirectTemporary)
            {
                ub.Host = "redirect-rewritten.com";
                return ub.ToString();
            }

            // No rules matched. This will make the condition in the rewrite rule not match.
            return string.Empty;
        }
    }
}

Кроме того, вам нужно настроить IIS, чтобы разрешить пользовательскую переменную сервера, и вам нужно подписать и зарегистрировать провайдеров в gac ... Это кажется немного сложнее, чем просто иметь возможность манипулировать URL-адресом запроса, как выродом из API.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2010

Я использовал ManagedFusion rewriter .Основная причина в том, что этот модуль выглядит достаточно расширяемым, а также имеет встроенный прокси.Будет ли он выполняться или нет, покажет время и пара тестов.

0 голосов
/ 02 ноября 2010

Рассматривали ли вы вместо этого использование расширяемости URL Rewrite?Вы можете легко создать провайдера, который может сопоставить что угодно, вы можете передать ему любую информацию через параметры (только одну строку, но вы можете объединить любое количество из них с некоторым разделителем), а затем решить все, что вам нужно, является ли этострока для URL или весь URL по этому вопросу.

См .: http://learn.iis.net/page.aspx/804/developing-a-custom-rewrite-provider-for-url-rewrite-module/

...