AWS Lambda使用SDKv3从S3获取证书密钥配置HttpsAgent报错问题
问题根因
- 你直接将
pipe()返回的写入流对象传给https.Agent的key、cert参数,这两个参数只接收字符串/Buffer类型的证书/密钥内容,不接收流对象,因此直接调用会报错。 - 先写磁盘再读失败的原因是
pipe()是异步操作,你没有等待写入完成就执行读取逻辑,此时文件还未完全写入甚至不存在,导致读取内容为空/文件不存在报错。
修复方案
方案1:直接转Buffer(推荐,无需写磁盘)
直接将S3返回的ReadableStream转为Buffer传入配置,不需要本地IO,性能更高:
const https = require('https'); const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3'); // 流转Buffer工具函数 async function streamToBuffer(stream) { const chunks = []; for await (const chunk of stream) { chunks.push(chunk); } return Buffer.concat(chunks); } async (event, context) => { let httpsAgent; try { console.log('> Getting content from S3'); const s3Client = new S3Client({ region: 'us-east-2', }); // 拉取证书并转Buffer const certRes = await s3Client.send(new GetObjectCommand({ Key: 'lib/myCert.crt', Bucket: 'mybucket', })); const cert = await streamToBuffer(certRes.Body); // 拉取密钥并转Buffer const keyRes = await s3Client.send(new GetObjectCommand({ Key: 'lib/myKey.pem', Bucket: 'mybucket', })); const key = await streamToBuffer(keyRes.Body); console.log('initializing Agent'); httpsAgent = new https.Agent({ key, cert, keepAlive: true }); // 后续业务逻辑 } catch (err) { console.error('操作失败:', err); throw err; } }
方案2:写入磁盘后读取(需等待写入完成)
如果必须要落地到本地磁盘,需要使用异步API等待写入操作完成后再读取:
const https = require('https'); const fs = require('fs'); const { pipeline } = require('stream/promises'); const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3'); async (event, context) => { let httpsAgent; try { console.log('> Getting content from S3'); const s3Client = new S3Client({ region: 'us-east-2', }); // 拉取证书并写入本地 const certRes = await s3Client.send(new GetObjectCommand({ Key: 'lib/myCert.crt', Bucket: 'mybucket', })); await pipeline(certRes.Body, fs.createWriteStream('/tmp/myCert.crt')); // 拉取密钥并写入本地 const keyRes = await s3Client.send(new GetObjectCommand({ Key: 'lib/myKey.pem', Bucket: 'mybucket', })); await pipeline(keyRes.Body, fs.createWriteStream('/tmp/myKey.pem')); console.log('initializing Agent'); httpsAgent = new https.Agent({ key: fs.readFileSync('/tmp/myKey.pem'), cert: fs.readFileSync('/tmp/myCert.crt'), keepAlive: true }); // 后续业务逻辑 } catch (err) { console.error('操作失败:', err); throw err; } }
内容的提问来源于stack exchange,提问作者jebrick
相关产品推荐
相关产品推荐

