为啥 HttpListener 在侦听强通配符 (http://+:port) http.sys/urlacl 绑定时“与现有注册冲突”?

Posted

技术标签:

【中文标题】为啥 HttpListener 在侦听强通配符 (http://+:port) http.sys/urlacl 绑定时“与现有注册冲突”?【英文标题】:Why does HttpListener "conflict with an existing registration" when listening to a Strong Wildcard (http://+:port) http.sys/urlacl binding?为什么 HttpListener 在侦听强通配符 (http://+:port) http.sys/urlacl 绑定时“与现有注册冲突”? 【发布时间】:2017-10-21 00:43:09 【问题描述】:

假设提升的用户(例如安装程序)配置 URL 保留:

 netsh http add urlacl url="https://+:8105/" user="SVCACCOUNT" listen=yes

现在当 Owin 启动时(在 SVCACCOUNT 下运行),出现以下错误:

System.Net.HttpListenerException: Failed to listen on prefix 'http://+:8105/' because it conflicts with an existing registration on the machine.
   at System.Net.HttpListener.AddAllPrefixes()
   at System.Net.HttpListener.Start()
   at Microsoft.Owin.Host.HttpListener.OwinHttpListener.Start(..)
   at Microsoft.Owin.Host.HttpListener.OwinServerFactory.Create(..)
...
at Microsoft.Owin.Hosting.Engine.HostingEngine.Start(StartContext context)

还有 Owin 的“入口”点:

WebApp.Start("http://+:8105", ..)

在创建问题期间,我发现http://*:8105 的注册和相同“工作”的 Owin / HttpListener URL。

是什么阻止了 HttpListener(以及 Owin)使用以前使用强通配符进行的注册?

为什么在注册和绑定中使用*(“弱通配符”)允许监听器启动?(使用“强通配符”会引发上述错误;由于帐户访问受限,完全删除注册将导致侦听器失败并显示“访问被拒绝”。)

这在哪里记录,以及从强通配符切换到弱通配符的修复有什么“后果”?为什么这个修复甚至有效?从多次提出相关问题(通常没有很好的答案)来看,+ 似乎在过去和/或在不同的系统或配置上“可能工作”:发生了什么变化?

(我发现了有关 http.sys 配置的零散文档,例如 Host-Specifier Categories 虽然仍然没有明确解释“冲突注册”。)


如果根据System.Net.HttpListenerException: Failed to listen on prefix 'http://localhost:8080 删除注册,Owin 服务将成功启动。但是我相信这需要更高的海拔来监听端口。

不是与“Owin self-host - Failed to listen on prefix 'http://localhost:12345/' because it conflicts with an existing registration on the machine”的重复,因为只有在 定义了 URL 预留时才会出现问题:此外,没有其他进程在监听,通过 netstat 确认。

Self hosted OWIN and urlacl 之类的问题让我相信这是权限问题或无关紧要的问题。例如,http://+:porthttp://*:port 有何不同? (不,使用 'EVERYONE' 作为 urlacl 并不能解决问题。)

“Running self-hosted OWIN Web API under non-admin account”中的评论可能是相关的 - 与 +* 相关......并且普遍缺乏澄清。

【问题讨论】:

【参考方案1】:

- What prevents HttpListener (and thus Owin) from using the registrations previously taken with a Strong Wildcard?

也许问题是您正在注册HTTPS 协议:

netsh http add urlacl url="https://+:8105/" user="SVCACCOUNT" listen=yes

然后你在代码中使用HTTP 协议:

WebApp.Start("http://+:8105", ..)
-Why does using * (a "weak wildcard") in both registration and binding allow a listener to start?

*+ 通配符之间的区别在于 * 包含 void 元素,而 + 强制至少存在 1 个字符。我不知道执行上的差异,但可能是一个几乎无法察觉的微小差异。

【讨论】:

以上是关于为啥 HttpListener 在侦听强通配符 (http://+:port) http.sys/urlacl 绑定时“与现有注册冲突”?的主要内容,如果未能解决你的问题,请参考以下文章

C# HttpListener 和 Windows 防火墙

为啥我在尝试使用 HttpListener 时会收到“AccessDenied”? [复制]

使用 HttpListener 访问键/值对

支持 HTTPS 的 Httplistener

如何在 C# 中的随机端口上创建 HttpListener 类?

C#-WebSocket协议通讯_Net5