如何用Golang在AWS Lambda中从GitHub仓库提供镜像文件
解决方案:用GitHub REST API + go-github包实现Lambda返回GitHub仓库中的镜像文件
核心问题分析
GitHub GraphQL API对二进制文件(如图片)不会返回Text字段,仅通过IsBinary标记,这是当前返回空白页面的根本原因。改用GitHub REST v3 API可直接获取二进制文件原始内容,再通过正确编码返回给API Gateway。
实现步骤
1. 引入依赖
确保项目中引入所需包:
go get github.com/google/go-github/v50/github go get golang.org/x/oauth2
2. 修改Lambda函数代码
替换原GraphQL查询逻辑,改用REST API获取文件内容:
import ( "context" "encoding/base64" "mime" "net/url" "os" "strings" "log" "github.com/aws/aws-lambda-go/events" "github.com/google/go-github/v50/github" "golang.org/x/oauth2" ) func GetMediaFile(req *events.APIGatewayProxyRequest, ac *ActionContext) (events.APIGatewayProxyResponse, error) { res := events.APIGatewayProxyResponse{StatusCode: 500} pathPieces := strings.Split(req.Path, "/") if len(pathPieces) < 4 { res.StatusCode = 400 res.Body = "无效请求路径" return res, nil } siteName := pathPieces[1] file, err := url.QueryUnescape(pathPieces[3]) if err != nil { log.Printf("解析文件路径失败: %v", err) return res, err } log.Printf("请求的媒体站点: %s", siteName) log.Printf("请求的媒体文件: %s", file) // 处理Content-Type ext := strings.Split(pathPieces[len(pathPieces)-1], ".") contentType := mime.TypeByExtension("." + ext[len(ext)-1]) if ext[len(ext)-1] == "md" { contentType = "text/markdown" } // 处理仓库后缀 suffix := "" if os.Getenv("GITHUB_BRANCH") == "master" { suffix = "-prod" } repoName := siteName + suffix branch := os.Getenv("GITHUB_BRANCH") if branch == "" { branch = "dev" // 默认分支 } // 初始化GitHub REST客户端 ctx := context.Background() ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")}, ) tc := oauth2.NewClient(ctx, ts) client := github.NewClient(tc) // 获取文件内容(REST API自动处理二进制文件) opts := &github.RepositoryContentGetOptions{ Ref: branch, } content, _, _, err := client.Repositories.GetContents(ctx, "rollthecloudinc", repoName, "media/"+file, opts) if err != nil { log.Printf("从GitHub获取文件失败: %v", err) return res, err } // 解码base64内容 fileBytes, err := content.GetContent() if err != nil { log.Printf("解码文件内容失败: %v", err) return res, err } // 构造响应 res.StatusCode = 200 res.Headers = map[string]string{ "Content-Type": contentType, } // 二进制文件需base64编码后返回 res.Body = base64.StdEncoding.EncodeToString([]byte(fileBytes)) res.IsBase64Encoded = true return res, nil }
3. 关键配置说明
- GitHub令牌:在Lambda环境变量中设置
GITHUB_TOKEN,令牌需拥有仓库读取权限(repo范围)。 - 分支处理:通过环境变量
GITHUB_BRANCH控制读取分支,默认设为dev避免空值错误。 - 路径校验:增加路径长度校验,防止数组越界。
- 内容解码:
content.GetContent()自动处理GitHub返回的base64编码内容,直接得到原始字节数据。
调试要点
- 检查Lambda日志中的
repoName、branch、file参数是否与GitHub仓库路径一致。 - 验证
GITHUB_TOKEN权限,用该令牌调用GitHub REST API测试文件获取。 - 确认API Gateway的二进制媒体类型配置包含图片类型(如
image/png、image/jpeg),避免响应内容被篡改。
内容的提问来源于stack exchange,提问作者RTC
相关产品推荐
相关产品推荐

