Question

I'm trying to do something really simple, but so far I've been unsuccessful in trying various methods of making it happen. I've tried uploading to a URL using a simple java.io.Socket, using a java.io.HttpURLConnection, and last using a org.apache.commons.httpclient.HttpClient, but I've failed to make it happen each time.

I need to make a request like this:

PUT http://1.2.3.4:8080/upload?ticket_id=abcdef124567890 HTTP/1.1
Host: 1.2.3.4:8080
Content-Length: 339108
Content-Type: video/mp4

\0abc\32af ... etc.

I need to write the bytes of a file (presumably from a FileInputStream) to the main request body, containing the video bytes.

I basically have two requirements:

  1. I must upload the file using a PUT request to a given server.
  2. I must be able to watch the progress of the upload as it's happening.

How can I make this happen in Java?


EDIT

Here's my attempt at doing this using Apache's HttpClient:

HttpClient httpClient = new HttpClient();
PutMethod httpMethod = new PutMethod(ticket.getEndpoint());
httpMethod.setRequestHeader("Content-Type", "video/mp4");
httpMethod.setRequestHeader("Content-Length", String.valueOf(getStreamFile().length()));

final FileInputStream streamFileInputStream = new FileInputStream(getStreamFile());
final BufferedInputStream bufferedInputStream = new BufferedInputStream(streamFileInputStream);

httpMethod.setRequestEntity(new RequestEntity() {
    @Override public void writeRequest(OutputStream out) 
            throws IOException {
        byte[] fileBuffer = new byte[getBufferLength()];
        
        int bytesRead = 0;
        int totalBytesRead = 0;
        final int totalFileBytes = (int)getStreamFile().length();
        
        while ((bytesRead = bufferedInputStream.read(fileBuffer)) > 0) {
            out.write(fileBuffer, 0, bytesRead);
            totalBytesRead += bytesRead;
            
            notifyListenersOnProgress((double)totalBytesRead / (double)totalFileBytes);
        }
    }
    
    @Override public boolean isRepeatable() {
        return true;
    }
    
    @Override public String getContentType() {
        return "video/mp4";
    }
    
    @Override public long getContentLength() {
        return getStreamFile().length();
    }
});

final int responseCode = httpClient.executeMethod(httpMethod);

logger.debug("Server Response {}: {}", responseCode, 
        httpMethod.getResponseBodyAsString());

This fails with a java.net.SocketException: Broken pipe exception.

Was it helpful?

Solution

For 1 you will need to use multipart request. The referred post describes it. For 2, use some counting stream wrapper as you send data. Counting stream may need to be hooked inside HttpClient.

More details can be provided if you add more specifics on what is not working for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top