IIS7.5 尝试使用 DELETE 动词时出现 500 内部服务器错误

问题描述 投票:0回答:4

我正在尝试向 IIS7.5 资源发出

DELETE

DELETE http://198.252.206.16:48251/Test/foo.ashx HTTP/1.1
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Host: 198.252.206.16:48251
Content-Length: 0
Connection: Keep-Alive
Pragma: no-cache

服务器响应:

HTTP/1.1 500 Internal Server Error
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 12 Feb 2014 01:01:30 GMT
Content-Length: 0

最可恶的是:

  • 它在 Cassini(Visual Studio 使用的基于 .NET 的 Web 服务器)中运行良好
  • Windows 事件日志中未记录任何内容
  • 站点中的自定义错误已关闭
    web.config
  • 没有动词被过滤(或所有动词都被包含)
  • WebDAV 模块已禁用
  • LiveStreamingHandler 模块未安装

为什么 IIS 不工作?

重现步骤

使用通用处理程序创建一个网站:

Foo.ashx

<%@ WebHandler Language="C#" Class="Foo" %>

using System;
using System.Web;

public class Foo : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
    }

    public bool IsReusable { get { return false; } }
}

然后向资源发出

DELETE
动词。如果您愿意,您可以使用 Fiddler 来编写请求:

enter image description here

你问的其他动词呢?

您没有尝试重现它,是吗?好吧,我会在这里向您展示结果:

  • GET
    有效
  • POST
    有效
  • PUT
    有效
  • HEAD
    有效
  • TRACE
    501 Not Implemented
  • DELETE
    500 Internal Server Error
  • SEARCH
    405 Method Not Allowed
  • PROPFIND
    500 Internal Server Error
  • PROPPATCH
    500 Internal Server Error
  • PATCH
    405 Method Not Allowed
  • MKCOL
    405 Method Not Allowed
  • COPY
    500 Internal Server Error
  • MOVE
    500 Internal Server Error
  • LOCK
    500 Internal Server Error
  • UNLOCK
    500 Internal Server Error
  • OPTIONS
    200 OK
  • IISUCKSFOO
    405 Method Not Allowed

为了保持肛门保留,相关部分的片段来自

web.config

<?xml version="1.0"?>
<configuration>
    <system.web>
        <httpRuntime/>
        <!-- IISFIX: By default IIS hides errors-->
        <customErrors mode="Off"/>
        <!-- IISFIX: By default IIS ignores the browser's culture -->
        <globalization culture="auto" uiCulture="auto"/>
        <!--Doesn't work for ASP.net web-sites, only ASP.net applications-->
        <trace enabled="true" requestLimit="40" localOnly="false" />

        <compilation debug="true" targetFramework="4.0">
            <assemblies>
                <add assembly="System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
                <add assembly="System.DirectoryServices.AccountManagement, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            </assemblies>
        </compilation>
    </system.web>

    <!-- ASP.net web-sites do not support WebPageTraceListener (only ASP.net web-applications) 
  So this section doesn't work; and does nothing. 
  But if Microsoft ever fixes IIS, we will start working automagically. -->
    <system.diagnostics>
        <trace>
            <listeners>
                <add name="WebPageTraceListener" type="System.Web.WebPageTraceListener, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
            </listeners>
        </trace>
    </system.diagnostics>

    <system.webServer>
        <!-- IISFIX: By default IIS ignores custom error pages -->
        <httpErrors existingResponse="PassThrough"/>
        <defaultDocument>
            <files>
                <clear/>
                <add value="Default.htm"/>
                <add value="Default.asp"/>
                <add value="index.htm"/>
                <add value="index.html"/>
                <add value="iisstart.htm"/>
                <add value="default.aspx"/>
                <add value="test.htm"/>
            </files>
        </defaultDocument>

        <!--IISFIX: By default IIS doesn't understand HTTP protocol-->
        <security>
            <requestFiltering>
                <verbs>
                    <add verb="OPTIONS" allowed="true" />
                    <add verb="GET" allowed="true" />
                    <add verb="HEAD" allowed="true" />
                    <add verb="POST" allowed="true" />
                    <add verb="PUT" allowed="true" />
                    <add verb="TRACE" allowed="true" />
                    <add verb="DELETE" allowed="true" />
                </verbs>
            </requestFiltering>
        </security>

        <modules runAllManagedModulesForAllRequests="true">
            <!--IISFIX: Whatever this is, it causes 405 Method Not Allowed errors on IIS when using PUT. (Microsoft's broken by defult)-->
            <remove name="WebDAVModule"/>
        </modules>

    </system.webServer>
</configuration>

编辑 - 忘记了动词的屏幕截图:

enter image description here

标题中已经充分提出了这个问题。这篇文章的其余部分只是填充内容,让它看起来像是在展示研究成果;这意味着您必须投票 - 投票箭头上的工具提示是这样说的!

rest iis iis-7.5 http-delete
4个回答
9
投票

答案原来是由更多微软的默认破坏政策引起的。

ASP.net 默认情况下决定忽略大多数请求,而不是充当 Web 服务器,接受请求并处理它们,因为它认为用户不应该执行这些请求。

解决方案是从 IIS 中删除与 ASP.net 相关的所有内容,然后正确地重新添加:

web.config

<?xml version="1.0"?>
<configuration>
</system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <!--IISFIX: Whatever this is, it causes 405 Method Not Allowed errors on IIS when using PUT. (Microsoft's broken by defult)-->
      <remove name="WebDAVModule"/>
    </modules>
    <handlers>
         <!--IISFIX: ASP.net is broken by default. By default they will not accept verbs from the client.
         First we have to rip out everything related to ASP.net-->
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"/>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"/>
      <remove name="SimpleHandlerFactory-ISAPI-2.0-64"/>
      <remove name="SimpleHandlerFactory-ISAPI-2.0"/>
      <remove name="SimpleHandlerFactory-Integrated"/>
      <remove name="SimpleHandlerFactory-Integrated-4.0"/>
      <remove name="SimpleHandlerFactory-ISAPI-4.0_64bit"/>
      <remove name="SimpleHandlerFactory-ISAPI-4.0_32bit"/>
         <!-- IISFIX: Now that we're ripped out everything related to ASP.net, put them back correctly.-->
      <add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0"/>
      <add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0"/>
      <add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0"/>
      <add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode"/>
      <add name="SimpleHandlerFactory-ISAPI-2.0" path="*.ashx" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0"/>
      <add name="SimpleHandlerFactory-ISAPI-2.0-64" path="*.ashx" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0"/>
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0"/>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0"/>
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0"/>

      <!--IISFIX: WebDAV is also buggy, and interferes with client requests-->
      <remove name="WebDAV"/>

    </handlers>
  </system.webServer>
</configuration>

现在的问题是该网站无法在其他人的机器上运行; web.config 中现在有硬编码的文件路径。

为什么,哦为什么,微软不能把事情做好。

为了完整性

作为我自己的参考,以下是我每次都需要添加到

web.config
的其他内容,因为默认值是错误的:

  <system.web>
    <httpRuntime/>
    <!-- IISFIX: By default IIS hides errors-->
    <customErrors mode="Off"/>
    <!-- IISFIX: By default IIS ignores the browser's culture -->
    <globalization culture="auto" uiCulture="auto"/>
  </system.web>

  <!-- ASP.net web-sites do not support WebPageTraceListener (only ASP.net web-applications) 
  So this section doesn't work; and does nothing. 
  But if Microsoft ever fixes IIS, we will start working automagically. -->
  <system.diagnostics>
    <trace>
      <listeners>
        <add name="WebPageTraceListener" type="System.Web.WebPageTraceListener, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      </listeners>
    </trace>
  </system.diagnostics>

  <system.webServer>
    <!-- IISFIX: By default IIS ignores custom error pages -->
    <httpErrors existingResponse="PassThrough"/>
  </system.webServer>

3
投票

我发现从上述解决方案中的处理程序和模块中删除 webDav 引用仍然会导致 IIS 7.5、IIS 7 Windows server 2008 r2(我从未测试过 IIS 8)的 http 方法 PUT、DELETE

HTTP 错误 500.21 - 内部服务器错误 处理程序“ExtensionlessUrlHandler-Integrated-4.0”有一个错误的模块“ManagedPipelineHandler”

此服务器错误具有误导性,也是由于 .net 安装不当(缺少处理程序)而导致的,可以通过重新安装 .Net 来修复,但这可能不是一个解决方案,如果它只影响对扩展的 PUT 或 DELETE 请求 -更少的路由处理程序(GET、POST 和 OPTIONS 都可以)。我读了很多关于在 MVC 和 Web api 中启用 put 和 delete 方法的文章,这些文章似乎声称这是一个修复,所以我尝试了几次,重新启动 IIS 等,错误没有改变。

直到我向 module 元素添加 runManagedModulesForWebDavRequests="true" 属性后,问题才消失。

< modules runAllManagedModulesForAllRequests="true" runManagedModulesForWebDavRequests="true" >

http://www.iis.net/configreference/system.webserver/modules

默认情况下 runManagedModulesForWebDavRequests ="false" 这意味着任何 webDav 请求都会路由到 WebDav。据我可以推断,就 IIS 而言,webdav 请求是所有 http PUT 或 DELETE 请求,即使您已从 Web 配置中删除了 webdav 处理程序并且您的请求正文不符合 webdav 请求。卸载 webDav 也可能会解决该问题,但我从未尝试过;我在同一服务器上运行依赖于它的其他站点。


2
投票

我在这里找到了答案:

带有 IIS 的 ASP.NET Core - 不允许使用 HTTP 动词

这是web.config

<configuration>
<!-- To customize the asp.net core module uncomment and edit the following section. 
     For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="aspNetCore" />
        <remove name="WebDAV" />
        <!-- I removed the following handlers too, but these
             can probably be ignored for most installations -->
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="TRACEVerbHandler" />

        <add name="aspNetCore" 
             path="*" 
             verb="*" 
             modules="AspNetCoreModule" 
             resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" 
                arguments="%LAUNCHER_ARGS%" 
                stdoutLogEnabled="false"
                stdoutLogFile=".\logs\stdout" />
</system.webServer>


0
投票

将来需要注意的是,当您将代码部署到非本地的任何内容时,您可以将可能的硬编码凭据更改为通用访问帐户。我整整一天半都遇到了这个问题,发现与

DELETE
一起使用的
LDAP
.net 请求正在使用前雇员的硬编码员工 ID 作为
UserPrincipalName
。一切都很好,直到他的 ID 最终从我们的系统中删除,然后一切都变坏了。一天半后,我们再次找到了用于测试目的的硬编码凭据。简单的示例来说明不同测试环境中必须考虑的不同事项。

© www.soinside.com 2019 - 2024. All rights reserved.