」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在 Go 中建立文件上傳服務

在 Go 中建立文件上傳服務

發佈於2024-11-07
瀏覽:345

Building a File Upload Service in Go

我们来谈谈文件上传。无论您是构建下一代 Instagram、CMS 还是任何涉及用户生成内容的应用程序,您都需要处理文件。今天,我们将深入探讨 Go 的文件上传的世界。我们将设置一个简单的文件上传服务,可以在本地存储文件,为了增加一点额外的风味,我们甚至会将其连接到 Amazon S3,以便您可以进入完整的云模式。 ️

这是游戏计划:

  1. 设置简单的文件上传端点。
  2. 处理文件,将其存储在本地,并确保一切正常。
  3. 添加一些基本验证以确保安全。
  4. 然后,我们通过 S3 存储将其提升了一个档次。

拿起你的咖啡,我们走吧! ☕


第 1 步:构建文件上传端点

首先,让我们设置一个带有 /upload 端点的基本 HTTP 服务器。为此,我们坚持使用 Go 的内置 net/http 包,因为它简单且易于使用。

服务器设置

弹出您最喜欢的编辑器,创建一个 main.go 文件,并设置一个基本服务器:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/upload", fileUploadHandler)

    fmt.Println("Server running on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

创建上传处理程序

现在让我们开始有趣的部分:处理文件上传!我们将创建一个 fileUploadHandler 函数来处理传入的文件并将它们存储在本地目录中。

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // Limit file size to 10MB. This line saves you from those accidental 100MB uploads!
    r.ParseMultipartForm(10 



以下是真相:

  • 我们使用 r.FormFile("myFile").
  • 从表单中获取文件
  • 获取文件后,我们将打开(或创建)本地文件并复制内容。
  • 此设置非常适合本地存储、快速原型或尚未准备好云存储的项目。

将文件保存到本地

让我们创建辅助函数 createFile 来处理文件的去向:

import (
    "os"
    "path/filepath"
)

func createFile(filename string) (*os.File, error) {
    // Create an uploads directory if it doesn’t exist
    if _, err := os.Stat("uploads"); os.IsNotExist(err) {
        os.Mkdir("uploads", 0755)
    }

    // Build the file path and create it
    dst, err := os.Create(filepath.Join("uploads", filename))
    if err != nil {
        return nil, err
    }

    return dst, nil
}

第 2 步:验证并保护您的文件?️

安全是关键!让我们添加一些验证,以便只有批准的文件类型才能通过。

验证 MIME 类型

想要保证它的安全吗?让我们限制上传图像。方法如下:

import (
    "io/ioutil"
    "strings"
)

func isValidFileType(file []byte) bool {
    fileType := http.DetectContentType(file)
    return strings.HasPrefix(fileType, "image/") // Only allow images
}

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // [Existing code here]

    // Read the file into a byte slice to validate its type
    fileBytes, err := ioutil.ReadAll(file)
    if err != nil {
        http.Error(w, "Invalid file", http.StatusBadRequest)
        return
    }

    if !isValidFileType(fileBytes) {
        http.Error(w, "Invalid file type", http.StatusUnsupportedMediaType)
        return
    }

    // Proceed with saving the file
    if _, err := dst.Write(fileBytes); err != nil {
        http.Error(w, "Error saving the file", http.StatusInternalServerError)
    }
}

第 3 步:使用 S3 将其带到云端☁️

本地存储很好,但如果您想扩展,S3 就是最好的选择!让我们将您的文件上传服务连接到 Amazon S3,以便您可以将文件存储在云中。

安装 AWS 开发工具包

要使用 S3,您需要 AWS SDK:

go get -u github.com/aws/aws-sdk-go/aws
go get -u github.com/aws/aws-sdk-go/service/s3

配置S3客户端

让我们设置一个函数来连接到您的 S3 存储桶:

import (
    "bytes"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func uploadToS3(file []byte, filename string) error {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-west-1"), // Your AWS region
    })
    if err != nil {
        return err
    }

    s3Client := s3.New(sess)
    _, err = s3Client.PutObject(&s3.PutObjectInput{
        Bucket: aws.String("your-bucket-name"),
        Key:    aws.String(filename),
        Body:   bytes.NewReader(file),
        ACL:    aws.String("public-read"),
    })
    return err
}

将“your-bucket-name”替换为您的实际 S3 存储桶名称。现在,让我们调整上传处理程序以使用此函数。

修改上传处理程序

更新 fileUploadHandler,以便我们将文件存储在 S3 中而不是本地:

func fileUploadHandler(w http.ResponseWriter, r *http.Request) {
    // [Existing code here]

    if err := uploadToS3(fileBytes, handler.Filename); err != nil {
        http.Error(w, "Error uploading to S3", http.StatusInternalServerError)
        return
    }
    fmt.Fprintf(w, "File successfully uploaded to S3!")
}

就是这样!您现在已经有了一个文件上传服务,它支持本地存储和通过 Amazon S3 进行的云存储。 ?


测试一下?

要测试上传服务,可以使用curl:

curl -X POST http://localhost:8080/upload -F "myFile=@path/to/your/file.jpg"

或者,如果您更喜欢图形界面,请创建一个快速 HTML 表单:

上传文件,您应该会看到它保存在本地或 S3 存储桶中。


总结

构建文件上传服务是添加功能和了解文件处理、验证甚至云存储的好方法。现在您已经掌握了基础知识,请考虑下一步 - 无论是图像大小调整、视频处理还是处理更大的文件类型,一切皆有可能!

您以前构建过文件上传服务吗? 请在下面发表评论并提供您的提示,或者让我知道您接下来想看到什么。快乐编码!

版本聲明 本文轉載於:https://dev.to/neelp03/building-a-file-upload-service-in-go-34fj?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3