我正在尝试使用multipart / form-data内容类型发布文件,我得到了这个问题:
在写文件内容时,我不应该逃避CRLF吗?我在网上得到了一个代码片段,我认为这可能是错的:
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL: url];
[req setHTTPMethod: @"POST"];
NSString* contentType = @"multipart/form-data, boundary=AaB03x";
[req setValue:contentType forHTTPHeaderField: @"Content-type"];
NSData* boundary = [@"\r\n--AaB03x\r\n" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *postBody = [NSMutableData data];
[postBody appendData: boundary];
[postBody appendData: [@"Content-Disposition: form-data; name=\"datafile\"; filename=\"t.jpg\"" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: imageData];
[postBody appendData: boundary];
[req setHTTPBody:postBody];
这是错误的,因为imageData可能包含\ r \ n序列,对吧?如果是这样,有没有办法逃避原始数据中的CRLF?或者我错过了什么?
提前致谢!
答案 0 :(得分:3)
这是一个有趣的问题。看multipart media type RFC,似乎由编写代理确保边界不会出现在封装数据中。此外,它还说明了以下内容:
注意:因为边界分隔符不得出现在身体部位 被封装后,用户代理必须谨慎选择 唯一的边界参数值。中的边界参数值 上面的例子可能是设计的算法的结果 产生边界分隔符的概率非常低 存在于要封装的数据中而不必预先扫描 数据
我将此解释为意味着为了确保边界值不会出现在封装数据中,您必须扫描数据以获取边界值。因为在大多数情况下这是一个令人无法接受的昂贵操作,所以预计用户代理只会选择一个在数据中出现概率很低的值。
考虑您的示例中的边界发生在随机字节串中的概率(为了参数,我们假设代表JPEG图像)。为了提前结束图像数据,需要匹配的完整字符串将是“\ r \ n - AaB03x” - 10个字节或80位。从任何位开始,接下来的10个字节是该序列的机会是2 ^ 80中的一个。在1MB JPEG文件中,有2 ^ 23位。这意味着包含序列的JPEG文件的概率小于2 ^ 23/2 ^ 80,或者2 ^ 57(超过一百万亿)中的一个。
所以,我认为答案是100%确定,你必须检查边界序列的数据,然后如果数据中存在边界序列则使用不同的数据。但实际上,边界序列发生的可能性很小,不值得。
答案 1 :(得分:0)
从技术上讲,这是错误的,因为结尾的\r\n
不应是RFC2046中所述的边界的一部分。尾随的\r\n
应该是transport-padding
的一部分,但是实际上,这没关系,因为您还是要把它放在边界之后。
我也认为应该避免整个序列,而不是子序列。