使用Django 1.2.3,PyISAPIe v1.1.0-rc4和IIS 7.5时,我遇到了大型POST数据(> 16384字节)的问题。
例如,提交约。使用POST的60kB表单数据,发生以下情况:
有趣的是,使用content-type="multipart/form-data"
时,它可以正常工作。
使用此信息,我在django \ core \ handlers \ wsgi.py中跟踪了错误的可能位置到WSGIRequest._get_raw_post_data,它与默认(无内容类型)案例分开处理content-type="multipart/form-data"
。
这两个案例都从self.environ['wsgi.input']
读取,它被设置为PyISAPIe对象。区别在于默认情况似乎是以16kB的块读取,而多部分处理程序似乎以不到2GB的块读取。
我不太了解C和Python的Python界面以进一步挖掘,但我猜这个bug是在ReadWrite.cpp的ReadClient函数中的PyISAPIe中的某个地方。
我目前的解决方法是将content-type="multipart/form-data"
添加到可能产生超过16kB数据的表单中。
是否还有人遇到此问题,或者有人知道如何确定该错误是否实际上在PyISAPIe中?
谢谢!
答案 0 :(得分:3)
PyISAPIe作者。
这已在存储库中的revision 184中修复,但未在可下载版本中修复,如mailing list中所述。
它解决了previously documented错误,显然没有引起太多关注,因为许多用户正在检查源而不是下载包。或者,这是我最好的猜测;无论如何,我打算提供一个可下载的固定代码版本。
感谢您引起我的注意,以便提醒我将该项目的版本保持在正常运行状态。
答案 1 :(得分:1)
我挖得更深一些,我想我发现了这个问题。
在PyISAPIe \ Readwrite.cpp中:
PyISAPIe_Func(DWORD) ReadClient( Context &Ctx, DWORD Length, void *const Data )
{
if ( !Length )
Length = Ctx.ECB->cbTotalBytes;
if ( !Data )
// Return the size of the the data that would be read
return min(Length, Ctx.ECB->cbTotalBytes);
DWORD Ret, Total = 0;
if ( Length > Ctx.ECB->cbAvailable )
{
[...snip...]
}
else
{
memcpy(Data, Ctx.ECB->lpbData, Length);
Ctx.ECB->cbTotalBytes -= Length;
Ctx.ECB->cbAvailable -= Length;
return Length;
}
如果使用Length< = Ctx.ECB-> cbAvailable重复调用该方法,它似乎始终将Ctx.ECB-> lpbData缓冲区的开头复制到Data中,而不是从缓冲区中删除该数据或推进指针。只有当数据耗尽时(cbAvailable == 0),新数据才会在代码中稍后正确读入数据。
仍然不确定如何修复它,但至少我可以通过读取足够大的数据块来解决它,以便一个块可以读取它。