【问题标题】:Large POST data is corrupted when using Django/PyISAPIe/IIS使用 Django/PyISAPIe/IIS 时大型 POST 数据损坏
【发布时间】:2012-03-28 13:39:09
【问题描述】:

在使用 Django 1.2.3、PyISAPIe v1.1.0-rc4 和 IIS 7.5 时,我遇到了大型 POST 数据(>16384 字节)的问题。

例如,当提交大约。使用 POST 的 60kB 表单数据,会发生以下情况:

  • POST 数据的前 16kB 块是正确的
  • 下一个 16kB 块是第一个块的重复
  • 接下来的 16kB 是第一个块的另一个重复
  • 其余部分 (

有趣的是,当使用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 和 C 语言的 Python 接口知之甚少,无法进一步深入研究,但我猜这个 bug 可能在 PyISAPIe 中 ReadWrite.cpp 中 ReadClient 函数的某个地方。

我目前的解决方法是将content-type="multipart/form-data" 添加到可能产生超过 16kB 数据的表单中。

是否有人也遇到过这种情况,或者有人知道如何确定该错误是否确实存在于 PyISAPIe 中?

谢谢!

【问题讨论】:

    标签: python c django python-c-api pyisapie


    【解决方案1】:

    PyISAPIe 作者在这里。

    如mailing list 中所述,此问题已在存储库的revision 184 中修复,但在可下载版本中未修复。

    它解决了一个previously documented 错误,该错误显然没有受到太多关注,因为许多用户正在查看源代码而不是下载包。或者,无论如何,这是我最好的猜测;无论如何,我计划提供固定代码的可下载版本。

    感谢您提醒我注意这一点,以便提醒我保持该项目的发布处于正常运行状态。

    【讨论】:

    • 感谢您的回答!我会试试看是否可以从源代码重新编译它。
    【解决方案2】:

    我挖得更深了,我想我找到了问题。

    在 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 cbAvailable 重复调用该方法,它似乎总是将 Ctx.ECB->lpbData 缓冲区的开头复制到 Data 中,而不是从缓冲区中删除该数据或推进一个指针。只有当数据用完(cbAvailable == 0)时,新数据才能在后面的代码中正确读入Data。

    仍然不知道如何解决它,但至少我可以通过读取足够大的数据块来解决它,这样一个块就可以全部读取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-05
      • 2021-12-26
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 2016-12-22
      • 2011-10-02
      相关资源
      最近更新 更多