Почему HttpWorkerRequest терпит неудачу во время HttpRuntime.ProcessRequest после a.NET 2.0 to.NET обновление 4.0?
Я обновляю наше приложение, которое имеет внутренний веб-сервер, с .NET 2.0 до .NET 4.0.
я обрабатываю запрос с объектом HttpListenerWorkerRequest
, который расширяет HttpWorkerRequest
класса, и создает запрос, который GetRawUrl()
возвращает URL-адрес в формате http://localhost:82/Default.aspx
.
в .NET 2.0, отправив это в HttpRuntime.ProcessRequest(httpListenerWorkerRequest)
работает без проблем, однако в .NET 4.0 я получаю веб-страницу с ничего, кроме текста "плохой запрос" на нем.
открытых трещин HttpRuntime
, Я видно, что плохие запросы выбрасываются из ProcessRequestInternal(HttpWorkerRequest wr)
, частный метод, который пытается построить HttpContext.
я попробовал это сам:
try
{
//what's going on?
hcontext = new HttpContext(workerRequest);
}
catch(Exception e)
{
//Debugging break point here
}
Pre-update (.NET 2.0), он отлично строит, post-update (.NET 4.0), я получаю систему.Исключение ArgumentException о том, что
The relative virtual path 'http:/localhost:82/Default.aspx' is not allowed here
, брошены на
at System.Web.VirtualPath.Create(String virtualPath, VirtualPathOptions options)
at System.Web.HttpRequest.get_ClientFilePath()
at System.Web.Security.CookielessHelperClass.RemoveCookielessValuesFromPath()
at System.Web.HttpContext.Init(HttpRequest request, HttpResponse response)
at System.Web.HttpContext..ctor(HttpWorkerRequest wr)
at Talcasoft.Web.Hosting.HttpWorkerThread.Run(Object request) in
C:[OurLibrary].WebHostingHttpWorkerThread.cs:line 51
что изменилось в .NET, чтобы вызвать это, и что я могу сделать, чтобы обойти это?
редактировать я только что заметил, что за запрещенным http: следует одна косая черта, а не двойная, хотя GetRawUrl() в запросе, безусловно, возвращает double.
2 ответов
я не 100% уверен, что это точный ответ, но выглядит довольно близко ко мне - и есть еще кое-что написать...
кажется breaking change
рода внутри VirtualPath
класс-и это подтверждается тем, как они проверяют illegal characters
. (кстати. вы можете google "источник VirtualPath" для того, что кажется версией .NET 4).
внутри VirtualPath.Create
проверка вызывается для "незаконных символов виртуального пути".
это первый заходит в реестр ("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET", "VerificationCompatibility") - чтобы увидеть, если compatibility
следует использовать режим "незаконные символы".
основываясь на этом-я предполагаю (у меня нет способа проверить это прямо сейчас) - это если вы установите вышеуказанное значение реестра (int) в
1
- вы должны заставить свои методы работатьthe old way
и W/O любой дополнительное усилие. Примечание: в IIS (или хост-процесс) перезагрузка может потребоваться как указано в одной из ссылок
а затем на основе этого флага реестра он использовал любой из этих двух...
':', '?', '*', '' // .NET 4.0 - the default
'' // the 'compatibility' mode
это, кажется, на самом деле описывает вашу историю довольно хорошо, так как ваш путь с обозначением "порт" на самом деле illegal
по новому умолчанию.
ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ / ОБЪЯСНЕНИЕ:
(обновление на основе комментариев и решения, которое решено)
Вот мое понимание того, что происходит внутри:--21-->
1) решение для до .NET 4.0 было VerificationCompatibility
ключ (см. выше).
2) с .NET 4.0 внутренняя обработка и фиксация url-путей сделаны более надежными. И работает отлично в большинстве случаев. Короче говоря,все пути фиксированы и нормализованы перед входом the VirtualPath.Create
- и ваш http://...
становится ожидаемым абсолютным путем /Default.aspx
.
однако, когда вы поставляете HttpWorkerRequest
(вместо запроса / ответа и т. д.)- the raw Url
С worker
- и ответственность за предоставление правильных и нормализованных путей лежит на вашем рабочем запросе. (это все еще немного сомнительно и выглядит как ошибка или плохое обращение внутри).
воспроизвести проблему:
internal class MyRequest : SimpleWorkerRequest
{
public MyRequest() : base("", "", String.Empty, String.Empty, null) { }
public override String GetRawUrl() { return "http://localhost:82/Default.aspx"; }
}
// ...
var wr = new MyRequest();
var context1 = new HttpContext(wr);
выдает ошибку The relative virtual path 'http:/localhost:82/Default.aspx' is not allowed here.
исправления:
public override String GetRawUrl()
{ return new Uri(url, UriKind.RelativeOrAbsolute).AbsolutePath; }
И некоторые исследования по этому вопросу основаны на этом
VerificationCompatibility
ключевое слово в реестре, которое кажется ключом к нему.
амперсанд в URL filename = плохой запрос
настройте IIS для приема URL-адреса со специальными символами...
для 32 против 64 разница в реестре
и вот аналогичная вещь от Microsoft-но то, что кажется "исправление" для "2.0", т. е. не относится к вам, но просто прикрепляет его как нечто официальное в этой строке.
исправить: сообщение об ошибке" HTTP 400 - плохой запрос " в .NET Framework 1.1
FIX: сообщение об ошибке при попытке посетить ASP.NET веб-страница на основе 2.0: "HttpException (0x80004005): '/HandlerTest/WebForm1.aspx/a:b 'не является допустимым виртуальным путем"
ASP.NET 2.0 x64 – вы можете получить http 400 плохой запрос или ошибку, как указано в КБ 932552 или 826437
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET
Имя Значения DWord: Данные Значения VerificationCompatibility: 1
вот мой взгляд на это. Он все еще содержит некоторые догадки, но я включу тест, который вы можете сделать, чтобы доказать или опровергнуть эту гипотезу.
трассировка стека показывает ClientFilePath.get
как источник исключения. Выглядит это так:
if (this._clientFilePath == null)
{
string rawUrl = this.RawUrl;
int index = rawUrl.IndexOf('?');
if (index > -1)
{
rawUrl = rawUrl.Substring(0, index);
}
this._clientFilePath
= VirtualPath.Create(rawUrl, VirtualPathOptions.AllowAbsolutePath); //here!
}
return this._clientFilePath;
создает VirtualPath
и допускает только абсолютные значения. http://localhost:82/Default.aspx
является относительным путем, потому что он не начинается с косой черты. Это не URL в этом контексте, потому что он не интерпретируется как такие.
так VirtualPath.Create
по понятным причинам отрицает этот путь. Я не знаю, почему .NET 2.0 разрешил это, но .NET 4.0 требует абсолютного пути, и в соответствии с кодом это не настраивается.
на самом деле, я никогда не видел HttpRequest.RawUrl
верните URL раньше. По моему опыту, он должен вернуться абсолютным путем, как /Default.aspx
. Если вы хотите установить хост и порт, вы должны найти другие способы сделать это.
таким образом, исправление не использовать http://localhost:82/Default.aspx
но /Default.aspx
. Это работать на тебя?