【发布时间】:2012-01-10 05:16:05
【问题描述】:
我正在使用在我自己的服务器上编译的 Apache mod_dav。我的客户端是用 Java 从头开始构建的自定义 HTTP 解析代码。我多年来一直在使用这个服务器和代码库,在服务器上同步千兆字节的数据。
今天我遇到了一个以前从未出现过的问题:可怕的 SAX“尾部不允许内容”错误。在整个服务器资源树中执行 WebDAV PROPFIND 时,我总是在同一位置收到此错误。
我已经测试并重新测试了我的 HTTP 解析代码,但它非常简单:Apache 正在发回分块内容,并且块指示要消耗的字节数。
失败的地方是恰好使用 110 个块的 XML 响应——比大多数其他响应大得多(这是一个非常大的目录)。但是,在我的日志中,我可以看到没有“尾随内容”——每个 XML 响应(产生错误和不产生错误的响应)都以一个简单的换行符结尾。
但更令人苦恼的是:我有一个输入流,它解析 HTTP 分块内容并返回一个简单的字节串。当我将此输入流直接传递给 XML 解析器时,我收到以下错误。但是:如果我采用 相同的输入流 并从中提取所有字节,将它们放入 ByteArrayInputStream,然后将 ByteArrayInputStream(应该包含完全相同的数据!)提供给解析器,不发生错误!直接从导致错误的传入数据中解析是什么?
我的 XML 解析器非常简单:
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false);
有人见过这个吗? (我搜索了“mod_dav XML bug”——刚刚得到了五年前提交的不相关的bug。)
这是堆栈跟踪的相关部分:
Cause:org.xml.sax.SAXParseException: Content is not allowed in trailing section.
com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
com.globalmentor.net.http.HTTPClientTCPConnection.readResponseBodyXML(HTTPClientTCPConnection.java:666)
com.globalmentor.net.http.webdav.WebDAVResource.propFind(WebDAVResource.java:453)
更新:我一遍又一遍地完成了这个测试。最后我添加了代码来遍历堆栈跟踪并打印出我得到的 SAX 解析信息:
Public Id: null System Id: null Line# 21937 Column# 1
我从日志文件中复制了XML,果然,第21937行是文件的结尾---但是那里什么都没有!!
【问题讨论】: