I am trying to post a video file to AWS using Android, using HttpUrlConnection. I am formatting the header and body per the instructions here http://ift.tt/1mEUcKx and here http://ift.tt/1ovO0oO
I seem to be able to write the request body and file data to the connection output stream, in the sense that it lets me finish the writing block (when I had some errors in my header before, this did not happen). Nonetheless, when I check to see if the file is on AWS, it is not.
The response stream seems to be the best way to figure out why. However, when I attempt to open and input stream on the connection to get the response, this results in the "broken pipe error."
So, here is the code:
URL url = new URL(action);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Host",bucket);
conn.setRequestProperty("User-Agent","Java/1.7.0_60");
conn.setRequestProperty("Accept","text/html,application/xhtml+xml, application/xml,application/json;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Acccept-Language", "en-US,en;q=0.5");
conn.setRequestProperty("Accept-Encoding","gzip, deflate");
conn.setRequestProperty("Accept-Charset","UTF-8");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
File fileObj = new File(file);
String closingString = crlf+twohyphens + boundary + twohyphens + crlf;
//get content length and set
int totalLength = body.getBytes().length + (int)fileObj.length() + closingString.getBytes().length;
conn.setRequestProperty("Content-Length",Integer.toString(totalLength));
//set body content fields
DataOutputStream request = new DataOutputStream(conn.getOutputStream());
request.writeBytes(body);
//get mp4 data and write to request:
InputStream input = new BufferedInputStream(new FileInputStream(file));
int data = input.read();
while(data != -1) {
//TODO loading animation
request.write(data);
data = input.read();
}
input.close();
Log.d("Writing","of file to output stream complete.");
request.writeBytes(closingString);
request.flush();
request.close();
Log.d("Writing","closing string to output stream complete. Closed stream");
//Response
/******** it seems to break on the following line: *************/
InputStream responseStream = new BufferedInputStream(conn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
{
stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
String responseString = stringBuilder.toString();
Log.d("server response",responseString);
Response response = new Response(0,"test");
conn.disconnect();
Note: the "body" string includes everything in the post body content (ie the required form fields, formatted as in the example links), except the actual file content, which must go last.
Here are the logs:
D/Writing: of file to output stream complete
D/Writing: closing string to output stream complete. Closed stream
W/System.err﹕ java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err﹕ at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:546)
W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:515)
W/System.err﹕ at java.net.PlainSocketImpl.write(PlainSocketImpl.java:504)
W/System.err﹕ at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
W/System.err﹕ at com.android.okio.Okio$1.write(Okio.java:73)
W/System.err﹕ at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
W/System.err﹕ at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)
W/System.err﹕ at com.android.okhttp.internal.http.RetryableSink.writeToSocket(RetryableSink.java:77)
W/System.err﹕ at com.android.okhttp.internal.http.HttpConnection.writeRequestBody(HttpConnection.java:259)
W/System.err﹕ at com.android.okhttp.internal.http.HttpTransport.writeRequestBody(HttpTransport.java:84)
W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:771)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:379)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:190)
W/System.err﹕ at android.synq.fm.connectivity.WebService.post(WebService.java:244)
W/System.err﹕ at android.synq.fm.connectivity.AwsPoster.doInBackground(AwsPoster.java:36)
W/System.err﹕ at android.synq.fm.connectivity.AwsPoster.doInBackground(AwsPoster.java:14)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
W/System.err﹕ Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
W/System.err﹕ at libcore.io.Posix.sendtoBytes(Native Method)
W/System.err﹕ at libcore.io.Posix.sendto(Posix.java:176)
W/System.err﹕ at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:513)
Please note that the log line: W/System.err﹕ at android.synq.fm.connectivity.WebService.post(WebService.java:244)
corresponds to the following line in the code: InputStream responseStream = new BufferedInputStream(conn.getInputStream());
So, my question is two-fold. Why does this not seem to successfully upload the file, even though it lets it be written to the connection output stream? And why does my attempt to get the request response "break the pipe"? Is there a special way to get POST responses from AWS that is not covered in the docs or that I somehow missed? (Please note this is my first time working with POST requests and AWS.)
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire