当前位置:  开发笔记 > 运维 > 正文

在WebException之后避免ProtocolViolationException

如何解决《在WebException之后避免ProtocolViolationException》经验,为你挑选了1个好方法。



1> Sam Harwell..:

问:为什么我会观察到这种行为?

答:.NET框架对HTTP服务器连接的支持基于ServicePointManager提供ServicePoint实例.每个ServicePoint实例都假定它基于端点地址连接到单个"逻辑"服务.此对象在另一端缓存有关服务的某些信息,其中一条信息是服务是否支持HTTP/1.1.如果对服务的任何请求指示该服务仅支持HTTP/1.0,则ServicePoint "锁存"到该状态,并且如果/当垃圾收集器清除指向该实例时,ServicePointManager将仅重新创建ServicePoint不处于该状态的新鲜状态WeakReference.

由于以下原因,此行为可能被视为不是问题:

    通常,单个端点由单个服务提供服务,该服务支持或不支持HTTP/1.1.

    如果端点实际上是一个负载均衡器,它将请求分派给多个后备HTTP实现(通常跨多个节点),那么这些节点代表同一整体服务安装的多个实例,并且所有节点都支持HTTP/1.1或者没有任何节点支持.

    在上述情况不成立的极少数情况下,缺乏HTTP/1.0功能通常不会妨碍服务.部署一个或多个HTTP/1.0服务器的端点不太可能要求客户端使用HTTP/1.1功能发送请求.

问:是否有一种解决问题的非黑客方式?

答:肯定有解决办法,但一个或多个选项可能不适合特定环境.以下列出了其中一些选项.

    更新服务以满足上面列出的条件.如果您提供的服务不符合上述条件,则应考虑在某些情况下.NET客户端可能无法与您的服务通信的情况下更新服务.如果您无法控制服务,显然这不是一个可行的解决方案.

    考虑使用分块编码来上传文件的替代方案.如果您知道流的大小,则可能不需要使用分块编码,这样可以避免对HTTP/1.1的依赖.对于问题中提到的SDK的情况,底层的SimpleRESTServices库实际上需要事先知道流大小,因此分块编码实际上并未用于其预期目的.相反,当预先知道内容长度时,库应该使用缓冲传输,并且当Stream.Size属性抛出时,仅依赖于分块编码NotSupportedException.

    考虑设置HttpWebRequest.AllowWriteStreamBufferingtrue.虽然我没有测试过这个解决方案,但是在浏览参考源时收集的信息表明,在不支持分块传输的情况下,此属性允许实现回退到缓冲,而不是简单地抛出ProtocolViolationException.

    强制将ServicePoint我的设置超时ServicePoint.MaxIdleTime为0.这仍然是hacky,但不依赖于反射,仍应继续使用Mono.修改后的代码如下所示.

    public void TestProtocolViolation()
    {
        try
        {
            TestTempUrlWithSpecialCharactersInObjectName();
        }
        catch (WebException ex)
        {
            ServicePoint servicePoint = ServicePointManager.FindServicePoint(ex.Response.ResponseUri);
            if (servicePoint.ProtocolVersion < HttpVersion.Version11)
            {
                int maxIdleTime = servicePoint.MaxIdleTime;
                servicePoint.MaxIdleTime = 0;
                Thread.Sleep(1);
                servicePoint.MaxIdleTime = maxIdleTime;
            }
        }
    
        TestTempUrlExpired();
    }
    

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有