Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload a file using Java HttpClient library working with PHP

I want to write Java application that will upload a file to the Apache server with PHP. The Java code uses Jakarta HttpClient library version 4.0 beta2:

import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils;   public class PostFile {   public static void main(String[] args) throws Exception {     HttpClient httpclient = new DefaultHttpClient();     httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);      HttpPost httppost = new HttpPost("http://localhost:9002/upload.php");     File file = new File("c:/TRASH/zaba_1.jpg");      FileEntity reqEntity = new FileEntity(file, "binary/octet-stream");      httppost.setEntity(reqEntity);     reqEntity.setContentType("binary/octet-stream");     System.out.println("executing request " + httppost.getRequestLine());     HttpResponse response = httpclient.execute(httppost);     HttpEntity resEntity = response.getEntity();      System.out.println(response.getStatusLine());     if (resEntity != null) {       System.out.println(EntityUtils.toString(resEntity));     }     if (resEntity != null) {       resEntity.consumeContent();     }      httpclient.getConnectionManager().shutdown();   } } 

The PHP file upload.php is very simple:

<?php if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {   echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n";   move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']); } else {   echo "Possible file upload attack: ";   echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";   print_r($_FILES); } ?> 

Reading the response I get the following result:

executing request POST http://localhost:9002/upload.php HTTP/1.1 
 HTTP/1.1 200 OK Possible file upload attack: filename ''. Array ( ) 

So the request was successful, I was able to communicate with server, however PHP didn't notice the file - the method is_uploaded_file returned false and $_FILES variable is empty. I have no idea why this might happend. I have tracked HTTP response and request and they look ok:
request is:

 POST /upload.php HTTP/1.1 Content-Length: 13091 Content-Type: binary/octet-stream Host: localhost:9002 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.0-beta2 (java 1.5) Expect: 100-Continue  ˙Ř˙ŕ..... the rest of the binary file... 

and response:

 HTTP/1.1 100 Continue  HTTP/1.1 200 OK Date: Wed, 01 Jul 2009 06:51:57 GMT Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 mod_jk/1.2.26 X-Powered-By: PHP/5.2.5 Content-Length: 51 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html  Possible file upload attack: filename ''.Array ( ) 

I was testing this both on the local windows xp with xampp and remote Linux server. I have also tried to use previous version of HttpClient - version 3.1 - and the result was even more unclear, is_uploaded_file returned false, however $_FILES array was filled with proper data.

like image 728
Piotr Kochański Avatar asked Jul 01 '09 07:07

Piotr Kochański


People also ask

What is the use of HttpClient jar?

HttpClient seeks to fill this void by providing an efficient, up-to-date, and feature-rich package implementing the client side of the most recent HTTP standards and recommendations.


2 Answers

Ok, the Java code I used was wrong, here comes the right Java class:

import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils;   public class PostFile {   public static void main(String[] args) throws Exception {     HttpClient httpclient = new DefaultHttpClient();     httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);      HttpPost httppost = new HttpPost("http://localhost:9001/upload.php");     File file = new File("c:/TRASH/zaba_1.jpg");      MultipartEntity mpEntity = new MultipartEntity();     ContentBody cbFile = new FileBody(file, "image/jpeg");     mpEntity.addPart("userfile", cbFile);       httppost.setEntity(mpEntity);     System.out.println("executing request " + httppost.getRequestLine());     HttpResponse response = httpclient.execute(httppost);     HttpEntity resEntity = response.getEntity();      System.out.println(response.getStatusLine());     if (resEntity != null) {       System.out.println(EntityUtils.toString(resEntity));     }     if (resEntity != null) {       resEntity.consumeContent();     }      httpclient.getConnectionManager().shutdown();   } } 

note using MultipartEntity.

like image 131
Piotr Kochański Avatar answered Sep 22 '22 09:09

Piotr Kochański


An update for those trying to use MultipartEntity...

org.apache.http.entity.mime.MultipartEntity is deprecated in 4.3.1.

You can use MultipartEntityBuilder to create the HttpEntity object.

File file = new File();  HttpEntity httpEntity = MultipartEntityBuilder.create()     .addBinaryBody("file", file, ContentType.create("image/jpeg"), file.getName())     .build(); 

For Maven users the class is available in the following dependency (almost the same as fervisa's answer, just with a later version).

<dependency>   <groupId>org.apache.httpcomponents</groupId>   <artifactId>httpmime</artifactId>   <version>4.3.1</version> </dependency> 
like image 38
Brent Robinson Avatar answered Sep 23 '22 09:09

Brent Robinson