上载文件时Android Android S3 HTTP / 1.1 403 Forbidden问题

时间:2014-11-28 11:10:17

标签: android sockets amazon-web-services amazon-s3 http-headers

我正在关注this教程,使用他们的REST api将图像文件上传到Amazon服务器。我正在从我们自己的服务器获取关于签名,策略等的详细信息。这是在服务器端生成的。

params.put("AWSAccessKeyId", "our-aws-access-key");
params.put("Content-Type", "image/jpeg");
params.put("policy", "some-policy-defined-by-our server");
params.put("Filename", "photo.jpg");
params.put("key", "images/photo.jpg");
params.put("acl", "private");
params.put("signature", "some-signature-defined-by-our server");
params.put("success_action_status", "201");

使用以上信息我发送了一个帖子请求:

try {
  HttpRequest.postSocket("bucketname.s3.amazonaws.com", params, context
                .getContentResolver().openInputStream(uri), file.length(), 
                this, "abc.png", "image/jpeg"); 
 } catch (Exception e) {
  return -1;
}

Class HttpRequest:

public class HttpRequest 
{

private static final String boundary = "-----------------------******";
private static final String newLine = "\r\n";    
private static final int maxBufferSize = 4096;

private static final String header = "POST / HTTP/1.1\n"
        + "Host: %s\n"
        + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.10) Gecko/20071115 Firefox/2.0.0.10\n"
        + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\n"
        + "Accept-Language: en-us,en;q=0.5\n"
        + "Accept-Encoding: gzip,deflate\n"
        + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n"
        + "Keep-Alive: 300\n" + "Connection: keep-alive\n"
        + "Content-Type: multipart/form-data; boundary=" + boundary + "\n"
        + "Content-Length: %s\n\n";


public static void postSocket(String sUrl, HashMap params, InputStream stream, long streamLength, 
      PutOrderFilesTask task, String fileName, String contentType) 
{
      OutputStream writer = null; 
      BufferedReader reader = null;
      Socket socket = null;
            try {
                int bytesAvailable;
                int bufferSize;
                int bytesRead;
                //int totalProgress = endProgress - startProgress;

                //task.myPublishProgress(new Long(startProgress));

                String openingPart = writeContent(params, fileName, contentType);
                String closingPart = newLine + "--" + boundary + "--" + newLine;
                long totalLength = openingPart.length() + closingPart.length() + streamLength;

                // strip off the leading http:// otherwise the Socket will not work
                String socketUrl = sUrl;
                if (socketUrl.startsWith("http://")) {
                 socketUrl = socketUrl.substring("http://".length());
                }

                socket = new Socket(socketUrl, 80);
                socket.setKeepAlive(true);
             writer = socket.getOutputStream();
             reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

             writer.write(String.format(header, socketUrl, Long.toString(totalLength)).getBytes());
                writer.write(openingPart.getBytes());

                bytesAvailable = stream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                byte[] buffer = new byte[bufferSize];
                bytesRead = stream.read(buffer, 0, bufferSize);
                int readSoFar = bytesRead;
                //task.myPublishProgress(new Long(startProgress + Math.round(totalProgress * readSoFar / streamLength)));
                while (bytesRead > 0) {
                    writer.write(buffer, 0, bufferSize);
                    bytesAvailable = stream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = stream.read(buffer, 0, bufferSize);
                    readSoFar += bytesRead;
                    //task.myPublishProgress(new Long(startProgress + Math.round(totalProgress * readSoFar / streamLength)));
                }
                stream.close();
                writer.write(closingPart.getBytes());
                //Log.d(Cards.LOG_TAG, closingPart);
                writer.flush();

                // read the response
                String s = reader.readLine();
                Log.e("AmazonCredentials"  + "-ResponseFileUpload", s); 

                // do something with response s
            } 
            catch (Exception e) 
            {           
                //throw new HttpRequestException(e);
            } 
            finally {
             if (writer != null) { try { writer.close(); writer = null;} catch (Exception ignore) {}}
             if (reader != null) { try { reader.close(); reader = null;} catch (Exception ignore) {}}
             if (socket != null) { try {socket.close(); socket = null;} catch (Exception ignore) {}}
            }
            //task.myPublishProgress(new Long(endProgress));
        }

 /**
     * Populate the multipart request parameters into one large stringbuffer which will later allow us to 
     * calculate the content-length header which is mandatotry when putting objects in an S3
     * bucket
     * 
     * @param params
     * @param fileName the name of the file to be uploaded
     * @param contentType the content type of the file to be uploaded
     * @return
     */
@SuppressWarnings("rawtypes")
private static String writeContent(HashMap params, String fileName,
        String contentType) {

    StringBuffer buf = new StringBuffer();

    Set keys = params.keySet(); 
    for (Object key  : keys)  
    {
        String val = (String) params.get(key);  
        buf.append("--").append(boundary).append(newLine);
        buf.append("Content-Disposition: form-data; name=\"").append(key)
                .append("\"").append(newLine).append(newLine).append(val)
                .append(newLine);
    }

    buf.append("--").append(boundary).append(newLine);
    buf.append("Content-Disposition: form-data; name=\"file\"; filename=\"")
            .append(fileName).append("\"").append(newLine);
    buf.append("Content-Type: ").append(contentType).append(newLine)
            .append(newLine);

    return buf.toString();
} 

}

但是我得到了响应HTTP / 1.1 403 Forbidden。请提出任何解决方案。

1 个答案:

答案 0 :(得分:0)

我强烈建议您查看适用于Android的SDK,这极大地简化了向S3发送请求的方法

http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/s3transfermanager.html