mxcl/OMGHTTPURLRQ

Extra "/r/n" in multipart requests

syzdykov opened this issue · 5 comments

Adding /r/n in the end of every part produces extra end of line for the last parameter.
In my case, I uploaded user profile data and my nickname was changed from "Nickname" to "Nickname/r/n" and this was the reason of some problems in my UI later.
Multipart request shouldn't end with end of line.
I think the proper way to fix this is to change method

- (void)add:(NSData *)payload :(NSString *)name :(NSString *)filename :(NSString *)contentType {
    id ln1 = [NSString stringWithFormat:@"--%@\r\n", boundary];
    id ln2 = ({
        id s = [NSMutableString stringWithString:@"Content-Disposition: form-data; "];
        [s appendFormat:@"name=\"%@\"", name];
        if (filename.length)
            [s appendFormat:@"; filename=\"%@\"", filename];
        [s appendString:@"\r\n"];
        if (contentType.length)
            [s appendFormat:@"Content-Type: %@\r\n", contentType];
        [s appendString:@"\r\n"];
        s;
    });

    [body appendData:[ln1 dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[ln2 dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:payload];
    [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}

like this

- (void)add:(NSData *)payload :(NSString *)name :(NSString *)filename :(NSString *)contentType {
    if (body.length) {
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }    

    id ln1 = [NSString stringWithFormat:@"--%@\r\n", boundary];
    id ln2 = ({
        id s = [NSMutableString stringWithString:@"Content-Disposition: form-data; "];
        [s appendFormat:@"name=\"%@\"", name];
        if (filename.length)
            [s appendFormat:@"; filename=\"%@\"", filename];
        [s appendString:@"\r\n"];
        if (contentType.length)
            [s appendFormat:@"Content-Type: %@\r\n", contentType];
        [s appendString:@"\r\n"];
        s;
    });

    [body appendData:[ln1 dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[ln2 dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:payload];    
}

I notice that this change caused issues for an ASP.NET web service we use internally, where it was accessing the multipart/form-data with statements like the following:

HttpContext.Current.Request.Form["feedbackNo"]

Without that \r\n prior to the boundary string it is failing to parse the parts correctly, so the above "feedbackNo" get returned as everything in the request following that first part.

Not super critical as our app has simple requirements and can use 3.1.2, however thought I'd bring it to your attention.

mxcl commented

Grr. I knew this would probably be a bad “fix”.

Server was refusing my POSTs for last week >_<
Thanks God, this project has low priority.
So, "\r\n", huh? Got it.

Removing the following code will cause error in the HTTP POST request.
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

OMGMultipartFormData *multipartFormData = [OMGMultipartFormData new];
[multipartFormData addFile:data parameterName:@"file" filename:@"img.png" contentType:@"image/png"];
[multipartFormData addText:token parameterName:@"token"];

PHP script on the server can't get the token parameter.

echo json_encode($_POST);

The solution of syzdykov is right.

    if (body.length) {
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }
mxcl commented

Fixed by be3018d