是否可以调用 IIS 7+来自托管 HttpModule 的 setUrl API?

发布于 2024-09-30 10:15:36 字数 5230 浏览 0 评论 0原文

我基本上需要的是管理大量的 URL 重写和重定向。重定向很容易完成,但重写应该通过 IIS 中的 ARR 代理进行代理。据我所知,IIS 重写模块使用 IIS 中的本机 setUrl API 来获取 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 中签署和注册提供程序...这似乎比简单地能够操作就像您从本机 api 请求 url 一样。

What I basically need is to manage a large set of URL rewrites and redirects. The redirects are easy to do but the rewrites should be proxyed through the ARR proxy in IIS. As far as I can tell the IIS rewrite module uses the native setUrl API in IIS to get the ARR proxy to forward the request. I'm not up to the task of writing a native module so I thought it might be possible to write a managed module to do the same.

@CarlosAg: Just to expand my comment on your answer. Heres the rules and providers I need to set up to make the rewrite module do what I want. Is it just me or doesn't it seem a little like manipulating the rewrite module into doing something it wasn't supposed to do?

<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>

And the provider's code:

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;
        }
    }
}

Apart from that, you need to setup IIS to allow the custom server variable and you need to sign and register the providers in the gac... This seems just a little more complicated than simply to be able to manipulate the request url like you are from the native api.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

聽兲甴掵 2024-10-07 10:15:36

您是否考虑过使用 URL 重写扩展性?您可以轻松创建一个可以映射任何内容的提供程序,您可以通过参数向其传递任何信息(只有一个字符串,但您可以使用一些分隔符连接任意数量的它们),然后解析您需要的任何内容,无论是部分URL 的字符串,或整个 URL。

请参阅:http: //learn.iis.net/page.aspx/804/developing-a-custom-rewrite-provider-for-url-rewrite-module/

Have you considered using the URL Rewrite extensibility instead? You can easily create a provider that can map anything, you can pass any information to it through the parameters (only one string, but you could concatenate any number of them with some separator), and then resolve whatever you need, whether is a partial string for the URL, or the entire URL for that matter.

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

海螺姑娘 2024-10-07 10:15:36

我最终使用了 ManagedFusion 重写器。主要原因是该模块看起来相当可扩展,并且还具有内置代理。无论它是否有效,只有时间和一些测试才能证明。

I've ended up using the ManagedFusion rewriter. The main reason is that this module seems fairly extensible and it also sports a built-in proxy. Whether it performs or not, only time, and a couple of tests, will tell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文