title: Error: parser error, 0 of 1448 bytes parsed occurring when posting from iPhone app to node.js server
body: <p>I'm trying post an image and accompanying meta data from an iPhone app to a server running Nodejs and Express.  My server code works fine when I execute the post from a browser using a REST client.  However, the same post performed from the Objective C code results in the following error on the server.  Can someone spot what I've done wrong? My research suggests that the Formidable library in Express is finicky about the encoding and boundary.  I tried the work-arounds (such as not using UTF8) but still the problem persists.  My research furthermore suggests that this problem can occur if you forget to name one of the fields in the request.  That does not to appear to be the issue either.</p>
  
  <pre><code>Error: parser error, 0 of 1448 bytes parsed
  at IncomingForm.write (/home/ec2-user/babel-match-server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js:145:17)
  at IncomingMessage.&lt;anonymous&gt; (/home/ec2-user/babel-match-server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js:95:12)
  at IncomingMessage.emit (events.js:67:17)
  at HTTPParser.onBody (http.js:115:23)
  at Socket.ondata (http.js:1387:22)
  at TCP.onread (net.js:354:27)
  </code></pre>
  
  <p>This is my Objective C code that performs the HTTP Post:</p>
  
  <pre><code>-(void) postImageToServer:(NSString *)imageFileName andImage:(NSData *)image {
  
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  
  NSString *user = [defaults objectForKey:@"babelMatchUser"];
  NSString *lang = [defaults objectForKey:@"learnLanguage"];
  
  NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://myserver.compute-1.amazonaws.com:3000/image?"]];
  [request setHTTPMethod:@"POST"];
  NSString *boundary = [[NSProcessInfo processInfo] globallyUniqueString];
  NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
  [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
  
  NSMutableData *body = [NSMutableData data];
  
  // file
  [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n", imageFileName] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[NSData dataWithData:image]];
  [body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
  
  // length
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"size\"\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"%i",image.length] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
  
  // image name
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"imageFileName\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[[NSString stringWithString:imageFileName] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
  
  
  // language
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userLanguagePref\"\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithString:lang] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
  
  // user
  [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"user\"\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
  [body appendData:[[NSString stringWithString:user] dataUsingEncoding:NSUTF8StringEncoding]];
  [body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
  
  // close form
  [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
  
  // set request body
  [request setHTTPBody:body];
  
  //bon voyage
  [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  }
  </code></pre>
  
  <p>On the server I handle the post with the following code:</p>
  
  <pre><code>    } else if (req.method == 'POST') {
      // Check body.length for flood attack or faulty client
      var imageFileName = req.body.imageFileName; //imageFileName must match actual file name or app will crash
      var user = req.body.user;
      var usrLanguagePref = req.body.userLanguagePref;
      //model.saveImageMetaData(imageFileName, user, usrLanguagePref);
      if (req.files) {
  
          var image = req.files.image;
          var tempPath = image.path;
          var originalImage = image.name;
          var newImage = originalImage.split('.', 1) + '_150x150.' + originalImage.split('.')[1];
          var s3Headers = {
              'Content-Type': image.type,
                  'x-amz-acl': 'public-read'
          };
          var dst;
  
          model.saveImageData(tempPath, originalImage, s3Headers, function () {
              var src = tempPath;
              dst = path.dirname(tempPath) + "/" + newImage;
              model.resizeImage(src, dst, function () {
                  model.saveImageData(dst, newImage, s3Headers, function () {
                      res.send(200);
                  });
              });
          });
  
      }
  }
  </code></pre>