Конечные точки в 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>
    <rules>
        <rule name="Trailing Dots" stopProcessing="true">
            <match url="\.+$" />
            <action type="Rewrite" url="/404.html" appendQueryString="false" />
        </rule>
    </rules>
</rewrite> 

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

2 ответа

Добавление этого атрибута в 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>

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

Другие вопросы по тегам