0

Is it possible to upload two (or more) files in only one request??

I've been trying to do so with NSMutableURLRequest and NSURLConnection but no success so far, and I have found no convincing answers online.

It's easy to upload a single file (using code from here) but the HTML Specs mention that when uploading more than one file you have to embed a multipart/mixed header inside the multipart/form-data, and the files to be uploaded within that multipart/mixed header.

The problem with the code linked above is that the one file that is being uploaded has it's Content-Disposition set to "form-data" (I guess that means that the single file is "all" of the form's data?) which I think leaves "no room" to attach another file. Please correct me if i'm wrong.

Thanks.

Community
  • 1
  • 1
jere
  • 4,306
  • 2
  • 27
  • 38

1 Answers1

2

EDIT:

The file data you are uploading should be encoded using Base64; you can do that by means of NSData+Base64 and then use:

[body appendData:[imageData1 base64EncodedString];

to send the file data, whereby I assume that imageData1 was defined as:

NSData* imageData = UIImagePNGRepresentation(image);

and image is a UIImage.

OLD ANSWER:

This is an example coming from the HTML 4.0.1 standard (very end of the document):

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"
Content-Type: multipart/mixed; boundary=BbC04y

--BbC04y
Content-Disposition: file; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--BbC04y
Content-Disposition: file; filename="file2.gif"
Content-Type: image/gif
Content-Transfer-Encoding: binary

...contents of file2.gif...
--BbC04y--
--AaB03x--

Notice that the files are listed all together in a multipart/mixed list.

So you can try with the code:

//-- new part in multipart/form-data
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"files\" dataUsingEncoding:NSUTF8StringEncoding]];

//-- new multipart/mixed
[body appendData:[[NSString stringWithFormat:@"multipart/mixed; boundary=%@", mixedBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: file; filename=\"%@\"\r\n", FileParamConstant1] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData1];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];


[body appendData:[[NSString stringWithFormat:@"--%@\r\n", mixedBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: file; filename=\"%@\"\r\n", FileParamConstant2] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData2];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

Take care of changing the filename and name attributes and it should work.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • 1
    i already tried that and after inspecting the request using Charles web proxy i see only the first parameter getting attached. i tried tons of different ways to do this, and only the first parameter sent seems to get attached to the request. i also couldn't find any resource detailing about whether this can be done or not. – jere Jul 02 '12 at 16:00
  • thanks for your time sergio, but i already tried that code almost exactly as you posted it. inspecting the request with charles i found only one "files" parameter (which seems to be correct according to the spec) but no files inside it. the parameter included some of the request's body text, leading me to think there was some syntax error somewhere, but i couldn't find anything... maybe i'll just give it up and send two requests with an nsqueue or GCD – jere Jul 02 '12 at 16:32
  • you are welcome. have you checked also what data leaves you machine? `body` should arrive unchanged to the proxy (syntax should not make any difference before getting to the web server)... in the end it is just a big string you are sending out... just one thing, are you using Base64 for the file content encoding? – sergio Jul 02 '12 at 16:41
  • i don't really know but i guess it's using base64... should i set that somewhere?? i thought `[body appendData:imageData];` took care of all that encoding stuff – jere Jul 02 '12 at 17:01
  • then that's the reason why the file "breaks" the dataload... I am going to edit my answer right now... – sergio Jul 02 '12 at 17:02
  • great! will test this and let you know later on – jere Jul 02 '12 at 17:11
  • hey sergio, no luck sadly... here is the output of the request headers with base64 and with regular encoding (http://pastebin.com/HPhRFWzK, http://pastebin.com/82SAa7vt) everything seems to be ok in the headers... i guess this just isn't supported by nsurlrequest or nsurlconnection – jere Jul 02 '12 at 19:13
  • I don't think this depends on the client side library; in the end, you see that by using base64 everything is sent out correctly and received... would you try adding: `Content-Transfer-Encoding: base64` after Content-Type? – sergio Jul 02 '12 at 19:21
  • i couldn't waste anymore time on that particular issue so i ended up sending out two different requests using GCD... i'll mark your answer as accepted anyways, thanks for your time! – jere Jul 03 '12 at 14:00