title: Node.js writing jpeg file in multipart/form-data form on HTTP POST using express
body: <p>I have a node.js server that is receiving content from an iOS application. The content is in two parts: 1. json and 2. jpeg. I am trying to write the jpeg to a file that I can then pull up in a browser. It seems pretty straight-forward, but when I write the buffer from the req.body.imagedata to a file, it is a corrupt file.</p>
  
  <p>Here is the first part of the jpeg from hexdump on the iPhone</p>
  
  <pre><code>0000000 **ff d8 ff e0 00 10 4a 46 49** 46 00 01 01 00 00 01
  0000010 00 01 00 00 ff e1 00 58 45 78 69 66 00 00 4d 4d
  0000020 00 2a 00 00 00 08 00 02 01 12 00 03 00 00 00 01
  </code></pre>
  
  <p>Here is the Charles Proxy output from the iPhone Simulator. So, it is being transmitted from the iPhone correctly.</p>
  
  <pre><code>00000060  69 6e 61 72 79 0d 0a 0d 0a **ff d8 ff e0 00 10 4a**   inary          J
  00000070  **46 49** 46 00 01 01 00 00 01 00 01 00 00 ff e1 00   FIF             
  00000080  58 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00   XExif  MM *     
  </code></pre>
  
  <p>Here is the tcpdump output on the server running node.</p>
  
  <pre><code>0000370 **d8ff e0ff 1000 464a 4649** 0100 0001 0100
  0000380 0100 0000 e1ff 5800 7845 6669 0000 4d4d
  0000390 2a00 0000 0800 0200 1201 0300 0000 0100
  </code></pre>
  
  <p>The server-side node tcpdump shows the correct header information coming across to the node.js server.</p>
  
  <pre><code>?ò?
  ?u???????
  8?8w
  ?u??????????%? ??
  8?8??L?|?Q??
  ?u??????????%? O|
  8?8??L?POST /screenw/ HTTP/1.1
  Host: ec2-103-22-8-3.compute-1.amazonaws.com:4914
  Accept-Encoding: gzip, deflate
  Content-Type: multipart/form-data; boundary=01947848929231
  Cookie: connect.sid=s%3A3i1td3wlRo8dqrFETNTcbUBV.h4EPihMhJTOdlSBmIog3xm3C%2FvTWVyD4eBBw2Fige6o
  Accept-Language: en-us
  Accept: */*
  Content-Length: 37297
  Connection: keep-alive
  User-Agent: Teachbits/1.0 CFNetwork/609.1.4 Darwin/12.2.0
  
  |?Q??
  ?u???????%? ??
  8?8??L?--01947848929231
  Content-Disposition: form-data; name="imagedata"
  Content-Transfer-Encoding: binary
  ....IMAGE DATA HERE.....
  </code></pre>
  
  <p>But the hexdump of the jpg that is written on the node.js side is wrong:</p>
  
  <pre><code>0000000 bfef efbd bdbf bfef efbd bdbf 1000 464a
  0000010 4649 0100 0001 0100 0100 0000 bfef efbd
  0000020 bdbf 5800 7845 6669 0000 4d4d 2a00 0000
  </code></pre>
  
  <p>Here is the code that receives the POST request and writes to a jpeg file.</p>
  
  <pre><code>app.post('/screenw/', function (req, res, next) {
  
      require("fs").writeFile("./http_image_64.jpg", req.body.imagedata, function (err) {
                  if (err) throw err;
                  console.log('It\'s saved!');
              });
  </code></pre>
  
  <p>And when I print out the size of the buffer on both the iPhone simulator and the node server, the sizes do not match:</p>
  
  <p>iPhone: image content is <strong>32661</strong> long</p>
  
  <p>node.js req.body.imagedata raw image - <strong>31679</strong></p>
  
  <p>I believe the problem lies in one of 2 areas:</p>
  
  <ol>
  <li><p>how Connect is parsing the jpeg section of the http body and handing it back to my server.js. i.e., I am providing the wrong Content-Type or other header information</p></li>
  <li><p>how I am taking the req.body.imagedata writing it to the jpg file. i.e., I have the encoding and associated logic incorrect.</p></li>
  </ol>
  
  <p>Any ideas on how to get this to work? I am stuck.</p>
  
  <p>[EDITED]</p>
  
  <p>Here is the objective-c code that constructs the http request:</p>
  
  <pre><code>//creating the url request:
  tbImgUrl = [NSURL URLWithString:@"screenw/" relativeToURL:[cts web_service]];
  NSMutableURLRequest *tbImgReq2 = [NSMutableURLRequest requestWithURL:tbImgUrl];
  [tbImgReq2 setHTTPMethod:@"POST"];
  NSString *boundary = @"01947848929231";
  NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
  [tbImgReq2 setValue:contentType forHTTPHeaderField:@"Content-Type"];
  [tbImgReq2 setValue:@"multipart/form-data" forHTTPHeaderField:@"enctype"];
  NSData *imageData = UIImageJPEGRepresentation([imgVector screenImage], 1.0); // 0.0 - 1.0 l to h
  
  // setting up the body
  NSMutableData *body = [NSMutableData data];
  
  // append the photo image
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"imagedata\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", @"image/jpeg"] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Transfer-Encoding: binary\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:imageData];
  
  // append the json data
  [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"jsondata\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
  NSData *reqData = [NSJSONSerialization dataWithJSONObject:sendPayload
                                                    options:0
                                                      error:nil];
  [body appendData:[NSData dataWithData:reqData]];
  [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
  
  
  [tbImgReq2 setHTTPBody:body];
  tbImgConnection = [[NSURLConnection alloc] initWithRequest:tbImgReq2
                                                    delegate:self
                                            startImmediately:YES];
  </code></pre>