Конечные точки в 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
Во всяком случае, когда я реализовал ваше правило, я настроил ваше регулярное выражение, чтобы поддержать трейлинг .
с последующим необязательным /
,
например
https://localhost/investing./
Я обновил его для поддержки необязательного слэша.
<rule name="Trailing Dots" stopProcessing="true">
<match url="\.+/?$" />
<action type="Rewrite" url="/404.html" appendQueryString="false" />
</rule>
Я бы добавил это в качестве комментария, но не имею права делать это.