A Bug in Custom ISAPI Filter Related to Keep-Alive

I once implemented my own Basic authentication logic in a custom ISAPI filter on IIS 6 and IIS 7.5 (classic mode). I met a bug related to keep-alive.

The custom filter checked the credentials ( Authorization: Basic <Base64 encoded name:password>) in the request header within the  CHttpFilter::OnPreprocHeaders function which I had overwritten. My code would send a  401 response to the client and return  SF_STATUS_REQ_FINISHED_KEEP_CONN when the credentials were invalid. 

The bug was: IIS would close TCP connection when the custom filter sent a 401 response to the client even if keep-alive was enabled. I had a client-side application which was written with .NET HttpWebRequest and HttpWebResponse. The application always threw an exception which told the server had closed the connection while keep-alive was expected. So why did the server close the connection?

After some time of investigation, I found this bug was caused by the incorrect behavior of the ISAPI filter itself. As MSDN introduced, by returning SF_STATUS_REQ_FINISHED_KEEP_CONN in CHttpFilter::OnPreprocHeaders, IIS would finish request handling and keep the TCP connection open if keep-alive was enabled. However, Microsoft did not implement this logic! Therefore, returning SF_STATUS_REQ_FINISHED_KEEP_CONN was exactly the same as returning SF_STATUS_REQ_FINISHED. The TCP connection was always closed! This behavior broke HTTP keep-alive protocol so that the client application failed.

Then I had to use a workaround to resolve this problem: adding “Connection: close” in the response header to explicitly tell the client the TCP connection would be closed by the server when I sent the 401 response to the client. I did not worry about the performance because HttpWebRequest.PreAuthenticate was set to true in most cases. That meant the client would receive the 401 response only at the first request. Then keep-alive would still work well for all the following thousands of requests. Here I want to complain why Microsoft did not add credentials to the first request even whenPreAuthenticate is true.

Recently, I abandoned the custom ISAPI filter and started using a custom HTTP module in IIS 7.5 Integrated mode to do Basic authentication. Of course, the problem went away when the client directly connected to the web server. However, the problem came back again when I used some reverse proxy device between the web server and the client, for example, the BigIP device. I did not find the root cause yet. But anyway, the “ Connection: close” workaround still worked well.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值