title: php://stdin reading extra characters
body: <p>I am having a weird problem with a system that I am making. I am attempting to create a system to upload files to a server. I do not have direct file write privileges, and HTTP POST <code>multipart/form-data</code> file uploads do not work. I unfortunately do not have direct access to the server.</p>
  
  <p>My solution is to use jQuery's <code>$.ajax</code> function to upload the file via HTTP PUT, then read it in from STDIN in PHP on the server, and upload the contents to a different location via FTP.</p>
  
  <p>Everything appears to work, however somewhere along the line, extra bytes are being added. On the client, Windows claims that the file (I am testing with my website's <code>favicon.ico</code> file) is 7358 bytes. Once I read in the file using a standard Javascript FileReader object, it appears to be only 7311 bytes. Then, I successfully PUT it to a PHP script on the server, which claims that it read 10890 bytes, which FileZilla agrees with when I check the dump folder over FTP.</p>
  
  <p>Here is my Javascript code to upload (jQuery 1.11.3 is included, and <code>file_input</code> is <code>&lt;input type="file" id="file_input"/&gt;</code>:</p>
  
  <pre><code>function upload(){
  console.log("upload");
  var f = file_input.files[0];
  var r = new FileReader();
  r.onload = function(event){
      var d = r.result;
      console.log("data loaded");
      console.log(d.length);
      $.ajax({
          url: "upload.php?name="+encodeURIComponent(f.name)+"&amp;mime="+encodeURIComponent(f.mime),
          context: document.body,
          method: "PUT",
          contentType: "application/octet-stream",
          data: d
          }).done(function(data){
              console.log("done");
              console.log(data);
              });
  };
  r.onerror = function(event){
      alert("ERROR READING FILE!\nCode " + event.target.error.code);
  };
  r.readAsText(f);
  console.log("initiated");
  }
  </code></pre>
  
  <p>As you can see, the name and MIME type are included via the GET query string.</p>
  
  <p>Here is my PHP that accepts the upload (part of upload.php):</p>
  
  <pre><code>if(strtoupper($_SERVER['REQUEST_METHOD'])=="PUT"){
      echo "uploading\n";
      echo "connected\n";
      var_dump($_POST);
      echo "x";
      $file=fopen("php://input","r");
      var_dump($file);
      $x="";
      while($byte=fgetc($file)!==false){
          $x.=$byte;
      }
      echo strlen($x);
      echo "\n";
      $ftp=fopen('ftp://user:pass@example.com/admin/fs/upload/'.uniqid('',true),'w');
      var_dump($ftp);
      fwrite($ftp,$x);
      fclose($ftp);
      echo "done\n";
  }
  </code></pre>
  
  <p>I examined the files in notepad, and the majority of the file appeared to be unchanged (there weren't any HTTP headers or anything), however the new file refused to open in any image viewer (the original would). Based on the differences in the files - only some parts are changes, and they are changed to what appear to be random non-visual characters - I would guess that it has something to do with a character encoding discrepancy. Any ideas would be appreciated.</p>
  
  <p>Thanks,</p>
  
  <p>MagikM18</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>My server is Apache/2.4.6 and running on x86_64-redhat-linux-gnu (according to phpinfo()).</p>
  
  <p>Also, I tested it with a text-based file (a PHP script) and it worked just fine - it must be something to do with the file's binary content.</p>