对AWS发布请求的响应“打破了管道”,无法读取

时间:2015-05-24 07:18:06

标签: http post amazon-web-services amazon-s3

我正在尝试使用Android将视频文件发布到AWS,使用HttpUrlConnection。我按照http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.htmlhttp://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html

的说明格式化标题和正文

我似乎能够将请求正文和文件数据写入连接输出流,从某种意义上说它可以让我完成写入块(当我之前在我的标题中有一些错误时,这没有发生)。但是,当我检查文件是否在AWS上时,它不是。

响应流似乎是找出原因的最佳方法。但是,当我尝试在连接上打开并输入流以获取响应时,这会导致“管道错误。”

所以,这是代码:

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();

注意:“body”字符串包含帖子正文内容中的所有内容(即所需的表单字段,格式如示例链接中所示),但实际文件内容除外,它必须最后一次。

以下是日志:

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)

请注意日志行:     W / System.err:在android.synq.fm.connectivity.WebService.post(WebService.java:244)

对应于代码中的以下行:     InputStream responseStream = new BufferedInputStream(conn.getInputStream());

所以,我的问题是双重的。为什么这似乎不能成功上传文件,即使它可以写入连接输出流?为什么我试图获得请求响应“打破管道”?是否有一种特殊的方式来获取AWS的POST响应,这些响应未包含在文档中或我错过了什么? (请注意,这是我第一次使用POST请求和AWS。)

提前致谢。

0 个答案:

没有答案