【问题标题】:AWS Android SDK not able to access s3 in "sub-directory"AWS Android SDK 无法访问“子目录”中的 s3
【发布时间】:2017-12-06 00:24:20
【问题描述】:

我正在使用 AWS API Gateway 生成的 android sdk 来获取 s3 中对象的预签名 URL(API 网关后面的 lambda)。

我的 s3 存储桶如下所示:

* module_a
|\
| * file_a
| * subdir_a
|  \
|   * file_sa
* module_b

这对于 file_a 非常有效,但对于 file_sa 则不然。至少当我使用 android SDK 时,我得到一个 URL,其中斜杠被替换为 %25252F。 但是,当我在控制台中测试 api 时,我得到了正确的 URL。

我可以用 SDK 做些什么来解决这个问题?

更新

这是涉及到这个问题的代码链sn-ps。

Android 代码下载文件(最后一行发生异常)

fileName = "css/style.css"; // file in s3
moduleName = "main"; // folder in s3
[...]
ApiClientFactory factory = new ApiClientFactory().credentialsProvider(
    aws.credentialsProvider);
apiClient = factory.build(myAPIClient.class);
apiClient.modulesModuleFileGet(fileName.replace("/", "%2F"), moduleName);
URL url = new URL(url_path.getUrl());
URLConnection connection = url.openConnection();
connection.connect();
InputStream in = new BufferedInputStream(connection.getInputStream());

API 网关

上面使用的api端点配置了两个路径参数(模块名和文件名)。调用 lambda 的主体映射模板如下所示:

#set($inputRoot = $input.path('$'))
{
  "module" : "$input.params('module')",
  "file": "$input.params('file')"
}

拉姆达

from __future__ import print_function

import json
import urllib
import boto3

s3 = boto3.client('s3')

def lambda_handler(event, context):
        key = event['module'] + "/" + event['file'].replace("%2F", "/")
        url = s3.generate_presigned_url(
                "get_object",
                Params={'Bucket':"mybucket",
                        'Key': key},
                ExpiresIn=60)
        return {"url": url}

【问题讨论】:

  • 您能否发布一个生成错误 URL 的代码示例?
  • @Unsigned,jsut添加了更多代码,希望不要太多。我试图只显示重要的东西。
  • 为什么要使用 replace() 进行转义?如果你需要 url 编码,你应该使用 URLEncoder.encodeurllib.parse.unquote 之类的东西来正确处理。
  • 这是三个 (!) 级别冗余(至少 2 个不正确)的结果 url-escaping ("percent-encoding"): /%2F%252F%25252F.

标签: android amazon-web-services amazon-s3 aws-sdk


【解决方案1】:

在跟随 cmets 之后,我已经开始工作了。但是我仍然以某种方式得到双引号斜杠。这是工作代码

安卓

public Url modulesModuleFileGet(String fileName, String moduleName) {
    try {
        String fileNameEnc = URLEncoder.encode(fileName, "UTF-8");
        Url ret = getApiClient().modulesModuleFileGet(fileNameEnc, moduleName);
        return ret;
    } catch (UnsupportedEncodingException e){
        Log.e(TAG, "> modulesModuleFileGet(", e);
        return null;
    }
}

拉姆达

def lambda_handler(event, context):
        key = event['module'] + "/" + urllib.unquote_plus(urllib.unquote_plus(event['file']))
        url = s3.generate_presigned_url(
                "get_object",
                Params={'Bucket':"my",
                        'Key': key},
                ExpiresIn=60)
        return {"url": url}

我仍然欢迎有关如何改进此功能的进一步建议,但目前它正在发挥作用。感谢 cmets 为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    相关资源
    最近更新 更多