【问题标题】:Uploading files (video files) to S3 server from android using signed URL’s generated from server side application使用从服务器端应用程序生成的签名 URL 从 android 将文件(视频文件)上传到 S3 服务器
【发布时间】:2015-04-21 10:06:52
【问题描述】:

我正在尝试使用从服务器端(用 python 编码)应用程序生成的签名 URL 从 Android 应用程序将视频文件上传到 S3 服务器中的存储桶。我们正在向签名的 URL 发出 PUT 请求,但我们得到了

connection reset by peer exception.

但是当我在 POSTMAN REST CLIENT 上尝试相同的 URL 时,会收到一条成功消息。 任何帮助将不胜感激。

【问题讨论】:

    标签: android file-upload amazon-s3 pre-signed-url


    【解决方案1】:

    使用Retrofit HTTP 客户端库完成此操作,它成功地将文件上传到 Amazon s3 服务器。

    代码:

     public interface UploadService {
        String BASE_URL = "https://bucket.s3.amazonaws.com/folder";
    
        /**
         * @param url :signed s3 url string after 'BASE_URL'.
         * @param file :file to upload,( usage: new TypedFile("mp4", videoFile);.
         * @param cb :callback.
         */
        @PUT("/{url}")
        void uploadFile(@Path(value = "url", encode=false) String url, @Body() TypedFile file, Callback<String> cb);
    }
    

    服务类

    public final class ServiceGenerator {
    
    private ServiceGenerator() {
    }
    
    public static <S> S createService(Class<S> serviceClass, String baseUrl) {
        return createService(serviceClass, baseUrl, null, null);
    }
    
    public static <S> S createService(Class<S> serviceClass, String baseUrl, final String accessToken, final String tokenType) {
    
        class MyErrorHandler implements ErrorHandler {
            @Override public Throwable handleError(RetrofitError cause) {
                return cause;
            }
        }
    
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .registerTypeAdapter(Date.class, new DateTypeAdapter())
                .disableHtmlEscaping()
                .create();
    
        RestAdapter.Builder builder = new RestAdapter.Builder()
                .setEndpoint(baseUrl)
                .setClient(new OkClient(new OkHttpClient()))
                .setErrorHandler(new MyErrorHandler())
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setConverter(new GsonConverter(gson));
    
        if (accessToken != null) {
            builder.setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade request) {
                    request.addHeader("Accept", "application/json;versions=1");
                    request.addHeader("Authorization", tokenType +
                            " " + accessToken);
                }
            });
        }
    
        RestAdapter adapter = builder.build();
    
        return adapter.create(serviceClass);
    }
    

    并使用:

        UploadService uploadService = ServiceGenerator.createService(UploadService.class,UploadService.BASE_URL);
    uploadService.uploadFile(remUrl,typedFile,new CallbackInstance());
    

    【讨论】:

    • 如何在此处输入 Cognito IDentity id 和访问令牌
    • 嘿@Aerrow,如果您需要 cognito,也许您不需要使用签名的 url 上传。您可以授予 cognito 用户池访问您定义的存储桶的权限。
    • 嗨@Shijil 今天刚研究这个话题。我看到您的 Retrofit 调用在请求中附加了一些标头。这些是针对您自己的安全模型的,对吗?不是 AWS 的事,对吗?
    • 以这种方式上传的图片在S3上处于损坏状态。它与任何人一起工作吗?我正在使用 Retrofit 1.8。
    【解决方案2】:

    使用动态URL而不是提供基本URL,使用@Url而不是@Path并传递一个完整的URI,默认情况下encode=false

    例如:

    @Multipart @PUT @Headers("x-amz-acl:public-read") Call<Void> uploadFile(@Url String url, @Header("Content-Type") String contentType, @Part MultipartBody.Part part);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 2019-06-24
      • 2014-10-29
      相关资源
      最近更新 更多