Upload file to HTTP Server with HTTP client and PHP backend

You might think the de facto way to upload files to your server is through FTP protocol, but FTP has it's own problems, for example, one of the most frequently occured problem is time out, another problem is FTP is more likely disabled by a firewall. Especially when you are using a Java client. I use it from Clojure which use a Java library behind the scene. I constantly get time out error, usually something like this:

 
ConnectException Connection timed out: connect  java.net.DualStackPlainSocketImpl.connect0 (DualStackPlainSocketImpl.java:-2)
 

When your FTP server is broken, a backup HTTP based solution will save your day in case there is an emergence file uploading need.

The following Clojure function upload your file with HTTP client:

 
(defn http-upload-file[filepath]
  (let [http-client (org.apache.http.impl.client.DefaultHttpClient.)
        http-post (org.apache.http.client.methods.HttpPost. "http://makble.com/uploadapi.php")
        mpe (org.apache.http.entity.mime.MultipartEntity.)]
 
    (.setParameter (.getParams http-client)  org.apache.http.params.CoreProtocolPNames/PROTOCOL_VERSION org.apache.http.HttpVersion/HTTP_1_1)
    (.addPart mpe "uploadfile"
      (org.apache.http.entity.mime.content.FileBody. 
        (java.io.File.
          filepath)
      )
    )
    (.setEntity http-post mpe)
    (let [ret (execute-http-post http-client http-post)]
      (.shutdown (.getConnectionManager http-client))
      ret
    )
  )
)
 
(defn execute-http-post [http-client http-post]
  (let [response (.execute http-client http-post)]
    {
      :status-line (.toString (.getStatusLine response))
      :response-entity-content (org.apache.http.util.EntityUtils/toString (.getEntity response))
    }
  )
)
 

The backend PHP

 
<?php
print_r($_FILES);
 
if(is_uploaded_file($_FILES['uploadfile']['tmp_name'])) {
    echo "moving ".$_FILES['uploadfile']['tmp_name']." to '".dirname(__FILE__)."/images/".$_FILES['uploadfile']['name']."'";
    move_uploaded_file($_FILES['uploadfile']['tmp_name'],dirname(__FILE__)."/images/".$_FILES['uploadfile']['name']);
}
?>
 

Put the php file in your site root directory the file will be uploaded to images folder in root directory.

Run command in your REPL and the output

 
(print (:response-entity-content (http-upload-file "C:\\Users\\Administrator\\Documents\\oMlXZMH100.jpg")))