0

I'm trying to get a handler to be called for the site root request by the browser, i.e. http://my.example.com. Given the code below, if I call /Test, the handler works as expected, but without that, I get the HTTP Error 403.14 - Forbidden (directory browsing isn't allowed).

  • Windows Server 2012-R2 / IIS 8.5
  • There is no MVC involved
  • ScriptModule-4.0 module is inherited so extensionless works
  • Similar to this question from 2012 that was never properly answered
  • Generic handler is given as an example...could also be a Soap Web Service

I've tried various combinations of slashes and asterisks for the handler path without success.

Generic handler:

Public Class Test
    Implements IHttpHandler

    Public Sub ProcessRequest(Context As HttpContext) _
        Implements IHttpHandler.ProcessRequest

        With New StringBuilder
            .AppendLine("<html>")
            .AppendLine("<head>")
            .AppendLine("<title>Test</title>")
            .AppendLine("</head>")
            .AppendLine("<body>")
            .AppendLine("<p>Hello World</p>")
            .AppendLine("</body>")
            .AppendLine("</html>")

            Context.Response.Write(.ToString)
        End With
    End Sub
End Class

...and in web.config I have the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <compilation strict="false" explicit="true" debug="true" targetFramework="4.5.2" />
        <customErrors mode="Off" />
        <authentication mode="Windows" />
        <httpRuntime targetFramework="4.5.2" />
    </system.web>

    <system.webServer>
        <handlers>
            <add verb="*" name="Test" type="MyApp.Test" path="Test" />
        </handlers>

        <defaultDocument enabled="true">
            <files>
                <clear />
                <add value="Test" />
            </files>
        </defaultDocument>
    </system.webServer>
</configuration>
Community
  • 1
  • 1
MrGadget
  • 1,258
  • 1
  • 10
  • 19

1 Answers1

0

The solution I came up with, but I'm open to other ideas.

In web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <compilation strict="false" explicit="true" debug="true" targetFramework="4.5.2" />
        <customErrors mode="Off" />
        <authentication mode="Windows" />
        <httpRuntime targetFramework="4.5.2" />

        <!-- Required for Web Services via Handlers -->
        <webServices>
            <protocols>
                <add name="HttpGet" />
                <add name="HttpPost" />
            </protocols>
        </webServices>
    </system.web>

    <system.webServer>
        <handlers>
            <add verb="GET,POST" name="Test" type="MyApp.Test" path="Test" />
        </handlers>

        <modules>
            <add name="AppModule" type="MyApp.AppModule" />
        </modules>

        <defaultDocument enabled="false" />
        <directoryBrowse enabled="false" />
    </system.webServer>
</configuration>

And then added the AppModule class where I evaluate HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath and do a HttpContext.Current.RewritePath so the handler defined above will pick it up.

  • my.example.com
  • my.example.com/AnyFolder/MyApplication

Matching for "~/" works if the web app is at the site root in IIS or is set up as an app within a site:

Public Class AppModule
    Implements IHttpModule

    Friend WithEvents WebApp As HttpApplication

    Public Sub Init(ByVal HttpApplication As HttpApplication) _
        Implements IHttpModule.Init

        WebApp = HttpApplication
    End Sub

    Private Sub WebApp_BeginRequest(sender As Object, e As EventArgs) _
        Handles WebApp.BeginRequest

        With HttpContext.Current
            If .Request.AppRelativeCurrentExecutionFilePath = "~/" Then .RewritePath("~/Test")
        End With
    End Sub

    Public Sub Dispose() _
        Implements IHttpModule.Dispose

        Throw New NotImplementedException()
    End Sub
End Class
MrGadget
  • 1,258
  • 1
  • 10
  • 19