2011-01-20 2 views
4

Я пытаюсь опубликовать файл, используя тип содержимого multipart/form-data, и у меня возник вопрос:
Не следует ли мне удалять CRLF, когда Я пишу содержимое файла? Я получил кусок кода в Интернете, и я думаю, что это может быть неправильно:escaping CRLF в типе содержимого HTTP multipart/form-data (iOS)

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 может содержать \ г \ п последовательностей, верно? Если да, существует ли способ избежать CRLF в необработанных данных? Или я чего-то не хватает?

Заранее благодарен!

ответ

3

Это интересный вопрос. Глядя на multipart media type RFC, выяснилось, что агент компоновки должен убедиться, что граница не отображается в инкапсулированных данных. Кроме того, в нем говорится следующее:

ПРИМЕЧАНИЯ: Поскольку граничные разделители не должны появляться в частях тела инкапсулируются, агент пользователя должен проявлять осторожность, чтобы выбрать уникальное значение параметра граничного. Значение граничного параметра в приведенном выше примере могло быть результатом алгоритма, разработанного для , для получения граничных разделителей с очень низкой вероятностью уже существующих , которые должны быть инкапсулированы без необходимости предварительного сканирования данных .

Я интерпретирую это так, чтобы убедиться, что граничное значение не отображается в инкапсулированных данных, вам придется сканировать данные для граничного значения. Поскольку в большинстве случаев это неприемлемо дорогостоящая операция, ожидается, что пользовательские агенты просто выберут значение, которое имеет очень низкую вероятность появления в данных.

Рассмотрите вероятность того, что граница в вашем примере встречается в случайной строке байтов (что для аргумента мы предположим, представляет собой изображение в формате JPEG). Полная строка, которую нужно будет сопоставить для раннего раннего ранжирования ваших изображений, будет «\ r \ n - AaB03x» - 10 байт или 80 бит. Начиная с любого бита, вероятность того, что следующие 10 байтов - это последовательность, равна 2^80. В файле 1 МБ JPEG есть 2^23 бит. Это означает, что вероятность того, что файл JPEG, содержащий последовательность, будет меньше 2^23/2^80, или один из 2^57 (более сотни квадриллионов).

Итак, я думаю, что ответ должен быть на 100% уверенным, вам нужно будет проверить данные для пограничной последовательности, а затем использовать другую, если эта граница существует в данных. Но на практике шансы на появление пограничной последовательности достаточно малы, чтобы этого не стоило.