You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:06:21