Search code examples
httpclient-servermultipart

Multipart message and POST parameters on server-side


I'm trying to POST a file in a multipart message. The problem is that I need to pass two extra parameters with that file. And I want them to be accessible in POST parameters array. The question is whether is possible to add part to multipart message so that it'll be interpreted as POST parameter? Or am I wasting time?

I want that e.g:

--1BEF0A57BE110FD467A\r\n
Content-Disposition: form-data; name="name1"\r\n
\r\n
value\r\n

be accsessible with $_POST['name1']

PS: as far as I know, if one uploads file with actionscript FileReference.upload(urlRequest) and specifies post params in urlRequest then they'll be in $_POST


Solution

  • What you want to do is in fact exactly the way that multipart messages work in relation to the $_POST array.

    Consider the following HTML form:

    <form action="/somefile.php" method="post" enctype="multipart/form-data">
      <input name="text1" type="text" />
      <input name="text2" type="text" />
      <input name="text3" type="text" />
      <input name="file" type="file" />
      <input type="submit" />
    </form>
    

    Now lets say we populate the three text inputs with value1, value2 and value3, we select a file called file.txt, and press submit. This will result in a request that looks something like this:

    POST /somefile.php HTTP/1.1
    Host: somehost.com
    Accept: */*
    User-Agent: MyBrowser/1.0
    Content-Type: multipart/form-data; boundary="this-is-a-boundary-string"
    
    --this-is-a-boundary-string
    Content-Dispostion: form-data; name="text1"
    
    value1
    --this-is-a-boundary-string
    Content-Dispostion: form-data; name="text2"
    
    value2
    --this-is-a-boundary-string
    Content-Dispostion: form-data; name="text3"
    
    value3
    --this-is-a-boundary-string
    Content-Dispostion: form-data; name="file"; filename="file.txt"
    Content-Type: text/plain
    
    This is the contents of file.txt
    --this-is-a-boundary-string--
    

    When we look at it in PHP, if we print_r($_POST); we should get something like this:

    Array
    (
       [text1] => value1
       [text2] => value2
       [text3] => value3
    )
    

    ...and if we print_r($_FILES);:

    Array
    (
       [file] => Array
       (
          [name] => file.txt
          [type] => text/plain
          [size] => 32
          [tmp_name] => /tmp/dskhfwe43232.tmp
          [error] => 0
       )
    )
    

    ...so you can see, the parts of the message where the Content-Disposition: header does not contain a filename="" element are added to the $_POST array, and those with one are treated as file uploads and added to $_FILES.

    When building a multipart/form-data message to send to a server, I find it easiest to build the HTML form that you are mimicking with the request, and construct your HTTP message based on how that HTML form would behave.