如何通过python的httplib2.Http请求方法发送超过64K的数据?

-1 投票
2 回答
586 浏览
提问于 2025-04-16 19:48

如果我这样做:

h = httplib2.Http(timeout=60)

resp, content = h.request(uri, method=method, body=body, headers=headers,
                          redirections=redirections,
                          connection_type=connection_type)

如果内容超过64K,数据似乎会被截断。

这是在32位的Python运行环境下(我觉得在64位的环境下不会出现这个问题)。

我该怎么做才能解决这个问题呢?

这是我遇到的问题:

https://svn.macports.org/ticket/18376

2 个回答

1

这个问题和一个未修复的2.6.6版本有关。简单来说,就是有一个已知的错误,后来被修复了。显然,我用的这个Python版本没有包含这个修复。

想了解更多这个问题的信息,可以查看这个帖子:https://svn.macports.org/ticket/18376

修复后的版本设置了HAVE_POLL=0,这样就强制Python使用select方法。确保你使用的Python版本包含这个修复,否则在发送较大数据块时可能会卡住。

另一个解决办法是重写httplib.py中的send方法,以捕捉到'35'这个异常,并重新发送数据。

下面是一些示例代码:

            blen = len(str)
            bleft = len(str)
            bpos = 0
            bsize = 1024*8
            while bleft > 0:
                bend = bpos + bsize
                if bend >= blen:
                    bend = blen
                try:
                    slen = self.sock.send(str[bpos:bend])
                except socket.error, v:
                    if v.args[0] == 35:      # unavailable
                        #print('socket unavailable')
                        slen = 0
                        time.sleep(.5)
                    else:
                        raise
                bleft -= slen
                bpos += slen

替换掉self.sock.sendall

1

这是我第一次听说这个。这里有一个简单的程序,展示了对我来说这个是有效的。请注意,我运行的 full.cgi 脚本只是把请求的头信息和请求的内容返回到响应中。当我运行这个时,完整的64K+内容,包括“结束”这句话,都会完整返回。

import httplib2

h = httplib2.Http(timeout=60)
body = "x"* (64*1024) + " the end"
uri="http://bitworking.org/projects/httplib2/test/reflector/full.cgi"
resp, content = h.request(uri, method="POST", body=body)
print content

你确定你在wireshark中看到的不是TCP分段吗?那些可能会被截断到不到64K,但并不代表完整的HTTP请求。

撰写回答