Назад | Перейти на главную страницу

Конечные точки в URL-адресе приводят к пустой странице 404 в IIS

У меня есть сайт ASP.NET на IIS8, но IIS7.5 ведет себя точно так же. Когда я ввожу такой URL-адрес:

mysite.com/foo/bar..

Я получаю следующую ошибку с кодом состояния «500 Internal Server Error»:

хотя у меня есть настраиваемые страницы ошибок для 500 и 404, и я не вижу ничего плохого в моей настраиваемой странице ошибок.

В моем узле web.config system.web у меня есть следующее:

<customErrors mode="On">
  <error statusCode="404" redirect="/404.aspx" />
</customErrors>

Если я удалю этот раздел, я получу ответ 404.0, но сама страница будет пустой.

В web.config system.webServer у меня есть:

<httpErrors errorMode="DetailedLocalOnly">
  <remove statusCode="404" subStatusCode="-1" />
  <error statusCode="404" prefixLanguageFilePath="" path="404.html" responseMode="File" />
</httpErrors>

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

Итак, прежде всего, почему обработчик asp.net принимает запрос на '..' (также работает с одной или несколькими конечными точками)

Если я удалю из applicationacationHost.config следующий обработчик:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />

Я получаю свою ожидаемую пользовательскую страницу 404, но, конечно, удаление этого обработчика, помимо прочего, нарушает маршрутизацию в asp.net.

Глядя на трассировку отказа, я вижу:

Проверка подлинности Windows отключена для сайта, почему этот модуль даже находится в конвейере запросов?

На данный момент я решил использовать модуль URL Rewrite со следующим правилом:

<rewrite>
    <rules>
        <rule name="Trailing Dots" stopProcessing="true">
            <match url="\.+$" />
            <action type="Rewrite" url="/404.html" appendQueryString="false" />
        </rule>
    </rules>
</rewrite> 

Это работает нормально, но мне интересно, почему IIS / ASP.NET так себя ведут?

Добавление этого атрибута в httpRuntime Раздел может помочь вам:

<configuration>
  <system.web>
    <httpRuntime ... relaxedUrlToFileSystemMapping="true" .../>
  </system.web>
</configuration>

Возвращает или задает значение, указывающее, должен ли URL-адрес в HTTP-запросе быть допустимым путем к файлу Windows.

Больше информации о RelaxedUrlToFileSystemMapping

Об этом есть КБ: http://support.microsoft.com/kb/2520479

В результате возникает проблема с порядком операций, при которой обработчики .NET для различных функций путаются и неверно направляют действия. Некоторые обработчики .NET переписывают URL-адрес в форму без расширений, и они могут испугать другие вещи.

Краткое временное решение - переместить все обработчики ExtensionlessUrlHandler в самый конец списка после любых добавленных вами настраиваемых обработчиков, которые могут касаться данных PathInfo.

Возможно, это не ваша точная ошибка, но стоит попробовать. И стоит помнить, что порядок обработчиков настраивается порядком ADD в ApplicationHost.Config и связанных файлах конфигурации!

Я не могу дать вам ответ о том, почему структура dotnet демонстрирует такое раздражающее поведение. Это почти так, как если бы он рассматривал 404 как обработанный 404 и пропускал страницу IIS 404 по умолчанию. Возможно, он устанавливает:

Response.IisTrySkipIisCustomErrors

Документы Microsoft

В любом случае, когда я реализовал ваше правило, я настроил ваше регулярное выражение для поддержки конечного . за которым следует необязательный /.

например

https://localhost/investing./

Я обновил его для поддержки необязательной косой черты.

<rule name="Trailing Dots" stopProcessing="true">
    <match url="\.+/?$" />
    <action type="Rewrite" url="/404.html" appendQueryString="false" />
  </rule>

Я бы добавил это в качестве комментария, но у меня нет ранга для этого.