Apache Abdera 的分块传输编码问题
我正在使用 Apache Abdera 将原子多部分数据发布到我的服务器,但遇到了一些我无法确定的奇怪问题。
它看起来像是分块传输编码的问题,但我的经验不足,无法确定。该问题表现为服务器抛出错误,表明我发送的请求仅包含一个 mime 部分,而不是所需的两个部分。我将 Wireshark 连接到界面并捕获对话,它是这样的:
POST /sss/col-uri/2ee98ea1-f9ad-4f01-9b1c-cfa3c4a6dc3c HTTP/1.1
Host: localhost
Expect: 100-continue
Transfer-Encoding: chunked
Content-Type: multipart/related; boundary="1306399868259";type="application/atom+xml;type=entry"
服务器的响应:
HTTP/1.1 100 Continue
我的客户端继续:
198
--1306399868259
Content-Type: application/atom+xml;type=entry
Content-Disposition: attachment; name="atom"
<entry xmlns="http://www.w3.org/2005/Atom"><title xmlns="http://purl.org/dc/terms/">Richard Woz Ere</title><bibliographicCitation xmlns="http://purl.org/dc/terms/">this is my citation</bibliographicCitation><content type="application/zip" src="cid:48bd9436-e8b6-4f68-aa83-5c88eda52fd4" /></entry>
0
b0e9
--1306399868259
Content-Type: application/zip
Content-Disposition: attachment; name="payload"; filename="example.zip"
Content-ID: <48bd9436-e8b6-4f68-aa83-5c88eda52fd4>
Packaging: http://purl.org/net/sword/package/SimpleZip
此时服务器响应:
HTTP/1.1 400 Bad Request
Date: Thu, 26 May 2011 08:51:08 GMT
Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8l DAV/2 mod_wsgi/3.3 Python/2.6.1
Connection: close
Transfer-Encoding: chunked
Content-Type: text/xml
指示错误(这是很好理解的)。我的服务器继续将一堆 Base64 编码位流式传输到输出流上,但同时服务器没有监听,它已经确定请求是错误的。
不幸的是,我不负责 HTTP 层 - 这一切都是由 Abdera 使用 Apache httpclient 处理的。我执行此操作的代码如下所示:
client.execute("POST", url.toString(), new SWORDMultipartRequestEntity(deposit), options);
这里,SWORDMultipartRequestEntity 是标准 Abdera MultipartRequestEntity 类的副本,其中添加了一些额外的标头(例如,请参阅上面代码片段中的打包); “deposit”参数只是一个保存原子部分和输入流的对象。
当附加调试器时,我很好地得到了这行代码,然后它消失在老鼠洞中,然后我又得到了这个错误。
有什么提示或技巧吗?我几乎用尽了我的攻击角度!
对我来说唯一突出的是,紧接着atom:entry文档之后,有一个带有“0”的换行符,它似乎是分块传输编码,代表“我完成了”。不确定它是如何到达那里的,或者它是否真的有任何影响。非常感谢帮助。
干杯,
理查德
I'm using Apache Abdera to POST atom multipart data to my server, and am having some odd problems that I can't pin down.
It looks like an issue with chunked transfer encoding, but I'm insufficiently experienced to be certain. The problem manifests as the server throwing an error indicating that the request I sent it contains only one mime part, not two as required. I attached Wireshark to the interface and captured the conversation, and it went like this:
POST /sss/col-uri/2ee98ea1-f9ad-4f01-9b1c-cfa3c4a6dc3c HTTP/1.1
Host: localhost
Expect: 100-continue
Transfer-Encoding: chunked
Content-Type: multipart/related; boundary="1306399868259";type="application/atom+xml;type=entry"
The server's response:
HTTP/1.1 100 Continue
My client continues:
198
--1306399868259
Content-Type: application/atom+xml;type=entry
Content-Disposition: attachment; name="atom"
<entry xmlns="http://www.w3.org/2005/Atom"><title xmlns="http://purl.org/dc/terms/">Richard Woz Ere</title><bibliographicCitation xmlns="http://purl.org/dc/terms/">this is my citation</bibliographicCitation><content type="application/zip" src="cid:48bd9436-e8b6-4f68-aa83-5c88eda52fd4" /></entry>
0
b0e9
--1306399868259
Content-Type: application/zip
Content-Disposition: attachment; name="payload"; filename="example.zip"
Content-ID: <48bd9436-e8b6-4f68-aa83-5c88eda52fd4>
Packaging: http://purl.org/net/sword/package/SimpleZip
And at this point the server responds with:
HTTP/1.1 400 Bad Request
Date: Thu, 26 May 2011 08:51:08 GMT
Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8l DAV/2 mod_wsgi/3.3 Python/2.6.1
Connection: close
Transfer-Encoding: chunked
Content-Type: text/xml
Indicating the error (which is well understood). My server goes on to stream a pile of base64 encoded bits onto the output stream, but in the mean time the server is not listening, it has already decided that the request was erroneous.
Unfortunately, I'm not in charge of the HTTP layer - this is all handled by Abdera using Apache httpclient. My code that does this looks like this:
client.execute("POST", url.toString(), new SWORDMultipartRequestEntity(deposit), options);
Here, the SWORDMultipartRequestEntity is a copy of the standard Abdera MultipartRequestEntity class, with a few extra headers thrown in (see, for example, Packaging in the above snippet); the "deposit" argument is just an object holding the atom part and the inputstream.
When attaching a debugger I get to this line of code fine, and then it disappears into a rat hole and then I get this error back.
Any hints or tips? I've pretty much exhausted my angles of attack!
The only thing that stands out for me is that immediately after the atom:entry document, there is a newline with "0" on it alone, which appears to be chunked transfer encoding speak for "I'm finished". Not sure how it got there, or whether it really has any effect. Help much appreciated.
Cheers,
Richard
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
孤独的
0
可能确实是一个问题。我不知情的猜测是,它是由对flush()
的某些调用引起的,然后该调用将整个缓冲区写入另一个 HTTP 块。不幸的是,在调用flush
时,缓冲区已经被刷新,因此其大小为零。因此,应该教导HttpChunkedOutputFilter
(或者无论如何调用它),空缓冲区不需要被刷新。[更新:] 您应该在
ChunkedOutputStream
类中设置断点,尤其是flush
方法。我只是看了它的代码,似乎没问题,但也许我错过了一些东西。The lonely
0
may indeed be a problem. My uninformed guess is that it results from some call toflush()
, which then writes the whole buffer as another HTTP chunk. Unfortunately at the point whereflush
is called, the buffer had already been flushed and its size is therefore zero. So theHttpChunkedOutputFilter
(or however it is called) should be taught than an empty buffer does not need to be flushed.[update:] You should set a breakpoint in the
ChunkedOutputStream
class, especially theflush
method. I just looked at its code and it seems to be ok, but maybe I missed something.