【问题标题】:Generating multipart boundary生成多部分边界
【发布时间】:2011-01-05 11:43:39
【问题描述】:

我正在编写一个脚本,将文件上传到需要多部分请求的 cgi 脚本,例如 HTML 页面上的表单。 boundary 是一个唯一标记,用于注释请求正文中的文件内容。这是一个示例正文:

--BOUNDARY
Content-Disposition: form-data; name="paramname"; filename="foo.txt"
Content-Type: text/plain

... file contents here ...
--BOUNDARY--

boundary 不能出现在文件内容中,原因很明显。

我应该怎么做才能创建一个独特的边界?我应该生成一个随机字符串,检查它是否在文件内容中,如果是,生成一个新的,冲洗并重复,直到我有一个唯一的字符串?或者“相当随机的令牌”(例如,时间戳、进程 ID 等的组合)就足够了吗?

【问题讨论】:

  • 您使用什么编程语言?通常这样的事情是由图书馆处理的。
  • 我正在使用 Ruby。它必须在标准库中,但不能使用 gems,因为脚本应该可以在任何安装了 ruby​​ 的系统上运行,而无需安装 gems。
  • BOUNDARY 可能没问题,但请务必使用 \r\n (DOS 行编码),因为只需 \n 它就会优雅地失败,并出现“标题部分超过 10240 字节”错误。

标签: multipart


【解决方案1】:

如果您使用足够随机的东西,例如 GUID,则不需要通过有效负载来检查边界的别名。类似的东西:-

----=NextPart_3676416B-9AD6-440C-B3C8-FC66DDC7DB45
标题:....

有效载荷
----=NextPart_3676416B-9AD6-440C-B3C8-FC66DDC7DB45--

【讨论】:

  • 谢谢!你的答案和标记的答案一样好,但他比你更需要代表;)
  • 这个答案更好,因为 GUID 专门设计为“全球唯一”。当您可以从一行代码中获取 GUID 时,为什么还要尝试提出自己的随机字符串?
  • 这个答案应该提到uuidgen
  • 永远不会迟到! 9 年后,您的答案现在是已标记的答案。 Tnx :)
【解决方案2】:

对于 Java 人:

protected String generateBoundary() {
             StringBuilder buffer = new StringBuilder();
             Random rand = new Random();
             int count = rand.nextInt(11) + 30; // a random size from 30 to 40
             for (int i = 0; i < count; i++) {
             buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
             }
             return buffer.toString();
        }

private final static char[] MULTIPART_CHARS =
             "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
                  .toCharArray();

参考网址:http://hc.apache.org/httpcomponents-client-ga/httpmime/xref/org/apache/http/entity/mime/MultipartEntity.html

【讨论】:

    【解决方案3】:

    对于 Swift 人来说(为了平衡 Java):

    func createBoundaryString() -> String {
        var str = ""
        let length = arc4random_uniform(11) + 30
        let charSet = [Character]("-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    
        for _ in 0..<length {
            str.append(charSet[Int(arc4random_uniform(UInt32(charSet.count)))])
        }
        return str
    }
    

    【讨论】:

      【解决方案4】:

      如果您感到偏执,您可以生成一个随机边界并在要发送的字符串中搜索它,在查找时附加随机字符(或重新创建),重复。但我的经验是,任何 10 个左右字符的任意非字典字符串几乎都不可能出现,因此选择 ---BOUNDARY---BOUNDARY---BOUNDARY--- 之类的内容就足够了。

      【讨论】:

      • 不,这还不够。因为您将无法使用您的程序发送您的程序源代码(或此评论)。
      • @stepancheg:您似乎感到偏执,在这种情况下,请使用我的答案第一段中的解决方案。不过,如果您精神健康,请使用 Content-Encoding: gzip 并不要担心那里的用户会试图吸引您。
      • 程序员有责任避免可预见的未来错误。
      • @BornToCode:如果用户故意试图使应用程序失败,您无法阻止他们 - 您只能限制对单个用户的影响。随机 compressed 内容在压缩到一个 39 个字符的特定字符串期间意外编码的可能性约为 1:2^47,这意味着它完全在可接受的范围内(UUID 并不好,它被认为足够.) - 需要有目的地构造一个压缩到边界代码的内容,然后我们可以拒绝它;这不是有效内容,而是恶意攻击。
      • 我认为很多用户会从这个答案中复制边界。以及在 stackoverflow 和其他教程中发现的许多其他边界。无论如何,这种漏洞并不是那么危险:D
      猜你喜欢
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 2021-02-27
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      相关资源
      最近更新 更多