Lambda - headObject 失败 (NotFound) 尽管 objectCreated 是事件
Lambda - headObject fails (NotFound) though objectCreated is the event
在带有事件的 lambda 函数中:s3:ObjectCreated:*
,在创建的对象上调用 head 对象 returns 一个 NotFound 错误。
module.exports.handler = async function(event, context, callback) {
try {
const Bucket = event.Records[0].s3.bucket.name;
const Key = event.Records[0].s3.object.key;
console.log('Bucket', Bucket);
console.log('Key', Key);
const objectHead = await s3.headObject({ Bucket, Key }).promise();
console.log('Alas! I will never discover that the objectHead is:', objectHead);
callback();
} catch(err) {
console.error('Error', err);
callback(err);
}
}
这是我得到的错误:
{
NotFound: null
message: null,
code: 'NotFound',
region: null,
time: 2018-02-19T11:06:35.894Z,
requestId: 'XXXXXXXXXXX',
extendedRequestId: 'XXX.....XXX',
cfId: undefined,
statusCode: 404,
retryable: false,
retryDelay: 77.24564264820208
}
我注意到错误中显示 region null
。我怀疑这无关紧要,因为我 99% 确定我设置正确:
const s3 = new AWS.S3({
region: 'us-east-1'
});
下面是 serverless.yml 函数声明,以防有人好奇:
obj_head:
handler: obj_head.handler
events:
- s3:
bucket: ${self:provider.environment.BUCKET_NAME}
event: s3:ObjectCreated:*
role: arn:aws:iam::XXXXXXXXX:role/RoleWithAllS3PermissionsEver
这里是收到事件的示例:
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "2018-02-19T11:03:46.761Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AWS:XXX"
},
"requestParameters": {
"sourceIPAddress": "X.X.X.X"
},
"responseElements": {
"x-amz-request-id": "X",
"x-amz-id-2": "X/X/X"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "14122133-28e8-4cd9-907c-af328334c56b",
"bucket": {
"name": "BUCKET_NAME",
"ownerIdentity": {
"principalId": "X"
},
"arn": "arn:aws:s3:::BUCKET_NAME"
},
"object": {
"key": "input.key",
"size": X,
"eTag": "X",
"sequencer": "X"
}
}
}
]
}
令人费解的是,虽然触发函数的事件是对象的创建,但找不到对象头。
我是不是做错了什么?
关于去哪里看有什么想法吗?
对象键名值是 URL 编码的,这是导致问题的原因。此行为记录在案 here:
The s3 key provides information about the bucket and object involved
in the event. Note that the object keyname value is URL encoded. For
example "red flower.jpg" becomes "red+flower.jpg".
处理包含 Unicode 字符的文件名时,请参阅 Alastair McCormack 的 :
You need to convert the URL encoded Unicode string to a bytes str
before un-urlparsing it and decoding as UTF-8.
在带有事件的 lambda 函数中:s3:ObjectCreated:*
,在创建的对象上调用 head 对象 returns 一个 NotFound 错误。
module.exports.handler = async function(event, context, callback) {
try {
const Bucket = event.Records[0].s3.bucket.name;
const Key = event.Records[0].s3.object.key;
console.log('Bucket', Bucket);
console.log('Key', Key);
const objectHead = await s3.headObject({ Bucket, Key }).promise();
console.log('Alas! I will never discover that the objectHead is:', objectHead);
callback();
} catch(err) {
console.error('Error', err);
callback(err);
}
}
这是我得到的错误:
{
NotFound: null
message: null,
code: 'NotFound',
region: null,
time: 2018-02-19T11:06:35.894Z,
requestId: 'XXXXXXXXXXX',
extendedRequestId: 'XXX.....XXX',
cfId: undefined,
statusCode: 404,
retryable: false,
retryDelay: 77.24564264820208
}
我注意到错误中显示 region null
。我怀疑这无关紧要,因为我 99% 确定我设置正确:
const s3 = new AWS.S3({
region: 'us-east-1'
});
下面是 serverless.yml 函数声明,以防有人好奇:
obj_head:
handler: obj_head.handler
events:
- s3:
bucket: ${self:provider.environment.BUCKET_NAME}
event: s3:ObjectCreated:*
role: arn:aws:iam::XXXXXXXXX:role/RoleWithAllS3PermissionsEver
这里是收到事件的示例:
{
"Records": [
{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "2018-02-19T11:03:46.761Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AWS:XXX"
},
"requestParameters": {
"sourceIPAddress": "X.X.X.X"
},
"responseElements": {
"x-amz-request-id": "X",
"x-amz-id-2": "X/X/X"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "14122133-28e8-4cd9-907c-af328334c56b",
"bucket": {
"name": "BUCKET_NAME",
"ownerIdentity": {
"principalId": "X"
},
"arn": "arn:aws:s3:::BUCKET_NAME"
},
"object": {
"key": "input.key",
"size": X,
"eTag": "X",
"sequencer": "X"
}
}
}
]
}
令人费解的是,虽然触发函数的事件是对象的创建,但找不到对象头。
我是不是做错了什么? 关于去哪里看有什么想法吗?
对象键名值是 URL 编码的,这是导致问题的原因。此行为记录在案 here:
The s3 key provides information about the bucket and object involved in the event. Note that the object keyname value is URL encoded. For example "red flower.jpg" becomes "red+flower.jpg".
处理包含 Unicode 字符的文件名时,请参阅 Alastair McCormack 的
You need to convert the URL encoded Unicode string to a bytes str before un-urlparsing it and decoding as UTF-8.