title: Sending multipart POST from iOS and reading parameters in PHP $_POST?
body: <p>I'm trying to send a multi-line post from an iPhone/iPad to a php service, the problem is that for some reason, the POST Content-Type seems to be application/x-www-form-urlenconded, ( I found out this using Wireshark )</p>
  
  <p>This is actually a snippet of the Wireshark POST packet capture:</p>
  
  <pre><code>    **Content-Type: application/x-www-form-urlencoded\r\n**
      Content-Length: 324\r\n
          [Content length: 324]
      Connection: keep-alive\r\n
      \r\n
      [Full request URI: http://my.server.com/mobile/tools/authentication]
  Line-based text data: application/x-www-form-urlencoded
      --0xKhTmLbOuNdArY\r\n
      Content-Disposition: form-data; name="login"\r\n
      \r\n
      hello@hello.com\r\n
      --0xKhTmLbOuNdArY\r\n
      Content-Disposition: form-data; name="password"\r\n
      \r\n
      somepassword\r\n
      --0xKhTmLbOuNdArY\r\n
      \r\n
      --0xKhTmLbOuNdArY--\r\n
  </code></pre>
  
  <p>The problem is that in the server I'm trying to read the login and password variables from this POST request, but it's not possible since I think php thinks the POST request is <code>x-www-form-urlencoded</code>, so if I setup <code>authentication.php</code> to do:</p>
  
  <pre><code>&lt;?php
  echo("&lt;pre&gt;")
  print_r($_POST)
  echo("&lt;/pre&gt;")
  ?&gt;
  </code></pre>
  
  <p>I get this:</p>
  
  <pre><code>&lt;pre&gt;Array\n
  (\n
      [--0xKhTmLbOuNdArY\r\n
  Content-Disposition:_form-data;_name] =&gt; "login"\r\n
  \r\n
  hello@hello.com\r\n
  --0xKhTmLbOuNdArY\r\n
  Content-Disposition: form-data; name="password"\r\n
  \r\n
  somepassword\r\n
  --0xKhTmLbOuNdArY\r\n
  \r\n
  --0xKhTmLbOuNdArY--\r\n
  \n
  )\n
  &lt;/pre&gt;
  </code></pre>
  
  <p>This is clearly not good, since If I send a request using this simple html form:</p>
  
  <pre><code>&lt;FORM action="http://my.server.com/mobile/tools/authentication.php" method="post"&gt;
     &lt;P&gt;
     &lt;LABEL for="login"&gt;E-mail: &lt;/LABEL&gt;
               &lt;INPUT type="text" name="login"&gt;&lt;BR&gt;
     &lt;LABEL for="password"&gt;pass: &lt;/LABEL&gt;
               &lt;INPUT type="text" name="password"&gt;&lt;BR&gt;
     &lt;INPUT type="submit" value="Send"&gt; &lt;INPUT type="reset"&gt;
     &lt;/P&gt;
  &lt;/FORM&gt;
  </code></pre>
  
  <p>I get this Wireshark trace as expected from a form:</p>
  
  <pre><code>    Content-Type: application/x-www-form-urlencoded\r\n
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
      Accept-Encoding: gzip,deflate,sdch\r\n
      Accept-Language: en-US,en;q=0.8\r\n
      Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n
      Cookie: PHPSESSID=tpp10pbrdkkf5dg9qprlamfuu2\r\n
      \r\n
      [Full request URI: http://mymed2.sophia.inria.fr/mobile/tools/authentication.php]
  Line-based text data: application/x-www-form-urlencoded
      login=hello%40hello.com&amp;password=somepassword
  </code></pre>
  
  <p>And this text output from the <code>print_r($_POST)</code> in <code>authentication.php</code></p>
  
  <pre><code>&lt;pre&gt;Array\n
  (\n
      [login] =&gt; hello@hello.com\n
      [password] =&gt; somepassword\n
  )\n
  &lt;/pre&gt;
  </code></pre>
  
  <p>This is the way I'm crafting the POST request in Objective-C and Cocoa</p>
  
  <pre><code>- (NSMutableURLRequest *) POSTRequestWithURL:(NSURL *)url andDataDictionary:(NSDictionary *) dictionary
  {
      // Create a POST request
      NSMutableURLRequest *myMedRequest = [NSMutableURLRequest requestWithURL:url];
      [myMedRequest setHTTPMethod:@"POST"];
  
      // Add HTTP header info
      // Note: POST boundaries are described here: http://www.vivtek.com/rfc1867.html
      // and here http://www.w3.org/TR/html4/interact/forms.html
      NSString *POSTBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
      [myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@\r\n", POSTBoundary] forHTTPHeaderField:@"Content-Type"];
  
      // Add HTTP Body
      NSMutableData *POSTBody = [NSMutableData data];
      [POSTBody appendData:[[NSString stringWithFormat:@"--%@\r\n",POSTBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
  
      // Add Key/Values to the Body
      NSEnumerator *enumerator = [dictionary keyEnumerator];
      NSString *key;
  
      while ((key = [enumerator nextObject])) {
          [POSTBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
          [POSTBody appendData:[[NSString stringWithFormat:@"%@", [dictionary objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
          [POSTBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", POSTBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
      }
  
      // Add the closing -- to the POST Form
      [POSTBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", POSTBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
  
      // Add the body to the myMedRequest &amp; return
      [myMedRequest setHTTPBody:POSTBody];
      return myMedRequest;
  }
  </code></pre>
  
  <p>As you see, in the beginning I do:</p>
  
  <pre><code>    [myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@\r\n", POSTBoundary] forHTTPHeaderField:@"Content-Type"];
  </code></pre>
  
  <p>But in the previous Wireshark trace logs, the POST packet was being viewed as Content-Type: application/x-www-form-urlencoded, maybe I'm doing something else wrong ? </p>
  
  <p>Thanks :)</p>
  
  <p>EDIT: I want to avoid external frameworks like ASIHTTPRequest, by the way, ASIHTTPRequest development has been abandoned by the lead developer as stated <a href="http://allseeing-i.com/%5Brequest_release%5D;" rel="noreferrer">here</a></p>