为了账号安全,请及时绑定邮箱和手机立即绑定

lambda 多部分/文件上传

lambda 多部分/文件上传

Go
SMILET 2022-09-12 21:18:55
我需要对使用 Go 通过 AWS Lambda 上传的上传文件的内容进行一些简单的操作,但不确定如何解析接收内容,因为我是 Go 的新手。到目前为止,我发现的解决方案与http包和多部分表单功能有关。type Request events.APIGatewayProxyRequestfunc Handler(ctx context.Context, req Request) (Response, error) {fmt.Println(req.Body)....}这就是我的请求正文的样子------WebKitFormBoundaryx0SVDelfa90Fi5UoContent-Disposition: form-data; name="file"; filename="upload.txt"Content-Type: text/plainthis is content------WebKitFormBoundaryx0SVDelfa90Fi5Uo--我的请求是 的实例。APIGatewayProxyRequest我想知道是否有可能获得一个自定义结构,从中我可以访问f.e.等数据。customStruct.content => "this is content"customStruct.fileName => upload.txtcustomStruct.fileExtension => txt
查看完整描述

2 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

这有3个部分:

  1. 创建一个从multipart.Readerevents.APIGatewayProxyRequest

  2. 获取哑剧部分

  3. 提取哑剧部件值

步骤 1:创建multipart.Reader

取一个 和 字符串,如签名所示:multipart.NewReaderio.Readerboundary

func NewReader(r io.Reader, boundary string) *Reader

为此,您需要从 HTTP 请求标头中提取边界字符串,这可以使用 来完成。Content-Typemime.ParseMediaType

执行此操作的一种简单方法是从具有以下签名的 go-awslambda 包中调用:NewReaderMultipart

func NewReaderMultipart(req events.APIGatewayProxyRequest) (*multipart.Reader, error)

步骤 2:获取 MIME 部件

获得 后,导航 MIME 消息,直到找到所需的 MIME 部分。mime.Reader

在这里的示例中,只有一个部分,因此您可以简单地调用:

part, err := reader.NextPart()

步骤 3:提取 MIME 部件值

获得 MIME 部件后,可以提取所需的值。

步骤 3.1:内容

content, err := io.ReadAll(part)

步骤 3.2:文件名

从 MIME 部件获取文件名,如下所示:

filename := part.FileName()

步骤 3.3: 文件扩展名

叫。这将在扩展中添加前导句点,但这可以很容易地删除。path/filepath.Ext.

ext := filepath.Ext(part.FileName())

总结

您可以按如下方式进行组合:

import (

    "context"

    "encoding/json"

    "io"


    "github.com/aws/aws-lambda-go/events"

    "github.com/grokify/go-awslambda"

)


type customStruct struct {

    Content       string

    FileName      string

    FileExtension string

}


func handleRequest(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {

    res := events.APIGatewayProxyResponse{}

    r, err := awslambda.NewReaderMultipart(req)

    if err != nil {

        return res, err

    }

    part, err := r.NextPart()

    if err != nil {

        return res, err

    }

    content, err := io.ReadAll(part)

    if err != nil {

        return res, err

    }

    custom := customStruct{

        Content:       string(content),

        FileName:      part.FileName(),

        FileExtension: filepath.Ext(part.FileName())}


    customBytes, err := json.Marshal(custom)

    if err != nil {

        return res, err

    }


    res = events.APIGatewayProxyResponse{

        StatusCode: 200,

        Headers: map[string]string{

            "Content-Type": "application/json"},

        Body: string(customBytes)}

    return res, nil

}


查看完整回答
反对 回复 2022-09-12
?
UYOU

TA贡献1878条经验 获得超4个赞

上面的答案看起来是正确的方法,但是如果你很懒惰(正如我:p),你可以创建一个HTTP请求,让本机lib为你工作:


httpReq, err := http.NewRequestWithContext(ctx, req.HTTPMethod, reqURL.String(), strings.NewReader(req.Body))

if err != nil {

    return nil, errors.New("failed to convert a lambda req into a http req")

}


// some headers may be important, let get all of them, just in case

for name, value := range req.Headers {

    httpReq.Header.Add(name, value)

}



// from here you can use httpReq.FormFile() to read the file


查看完整回答
反对 回复 2022-09-12
  • 2 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信