使用go - azure上传blob

dphi5xsq  于 2023-04-22  发布在  Go
关注(0)|答案(1)|浏览(172)

我正在构建一个用go和gin编写的API,它将blob上传到Azure存储。下面是代码:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "net/url"

    "github.com/Azure/azure-storage-blob-go/azblob"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()

    router.POST("/upload", func(c *gin.Context) {
        accountName := "blablabla"
        accountKey := "mykey"
        containerName := "testblabla"
        blobName := c.PostForm("blobName")

        credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
        if err != nil {
            log.Fatal("Erro ao realizar nova conexão com azure", err)
            return
        } else {
            fmt.Println("Sucesso ao se conectar com o azure")
        }

        u, err := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s", accountName, containerName, blobName))
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{
                "Erro ao ler URL do container": err,
            })
            log.Fatal("Erro ao ler URL do container", err)
            return
        } else {
            fmt.Println("Sucesso ao ler URL do container, eu passei por aqui")
            c.JSON(200, gin.H{
                "Sucesso ao ler URL do container": "Eu passei por aqui",
            })
        }
        blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))
        c.JSON(200, gin.H{
            "Sucesso ao ler URL do container": "Próximo passo",
        })
        log.Println("Sucesso ao ler URL do container")

        form, err := c.MultipartForm()
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{
                "Erro ao ler arquivo": err.Error(),
            })
            log.Println("Erro ao ler arquivo", err)
            return
        }

        files := form.File["upload"]
        if len(files) == 0 {
            c.JSON(http.StatusBadRequest, gin.H{
                "Erro ao enviar arquivo para container": "Nenhum arquivo enviado",
            })
            log.Println("Nenhum arquivo enviado", err)
            return
        }

        file := files[0]

        fmt.Println("eu passei por files", file)

        log.Println(file.Filename)

        src, err := file.Open()
        if err != nil {
            c.JSON(500, gin.H{
                "Erro ao abrir arquivo": err,
            })
            log.Fatal("Erro ao abrir arquivo", err)
            return
        } else {
            fmt.Println("Sucesso ao abrir arquivo")
            c.JSON(200, gin.H{
                "Sucesso ao abrir arquivo": "Proximo passo",
            })
        }

        options := azblob.UploadStreamToBlockBlobOptions{
            MaxBuffers: 3,
        }
        _, err = azblob.UploadStreamToBlockBlob(context.Background(), src, blobURL, options)

        if err != nil {
            fmt.Println("deu erro, mas passei por aqui")
            c.JSON(http.StatusInternalServerError, "Deu erro, mas passei aqui")
            c.JSON(http.StatusInternalServerError, gin.H{
                "Erro ao enviar arquivo para container": err.Error(),
            })
            log.Println("Erro ao enviar arquivo para container", err)
            return
        } else {
            c.JSON(http.StatusOK, gin.H{
                "message": "Arquivo enviado com sucesso!",
            })
            fmt.Println("Sucesso ao enviar arquivo")

        }
    })
    router.Run(":8080")
}

以下是使用Postman测试此API的步骤:
1.方法选择POST
1.输入API的URL
1.在body页签下选择form-data
1.在key列中输入blob的名称,选择类型file,然后选择我的文件
1.发送请求
我得到了这个错误:

Erro ao enviar arquivo para container write error: -> github.com/Azure/azure-storage-blob-go/azblob.newStorageError, C:/Users/rodri/go/pkg/mod/github.com/!azure/azure-storage-blob-go@v0.15.0/azblob/zc_storage_error.go:42
===== RESPONSE ERROR (ServiceCode=InvalidUri) =====
Description=The requested URI does not represent any resource on the server.
RequestId:a31b34a1-401e-000c-3aa8-6fb698000000
Time:2023-04-15T14:43:41.9699330Z, Details:
   Code: InvalidUri
   UriPath: https://blablabla.blob.core.windows.net/teste/?blockid=mLa1s8Y9Tu6Tqw0umZ2kiwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==&comp=block&timeout=61        
   PUT https://blablabla.blob.core.windows.net/teste/?blockid=mLa1s8Y9Tu6Tqw0umZ2kiwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%3D&comp=block&timeout=61
   Authorization: REDACTED
   Content-Length: [5]
   User-Agent: [Azure-Storage/0.15 (go1.20; Windows_NT)]
   X-Ms-Client-Request-Id: [5e531a97-f854-476c-49f7-407a29468e89]
   X-Ms-Date: [Sat, 15 Apr 2023 14:43:41 GMT]
   X-Ms-Version: [2020-10-02]
   --------------------------------------------------------------------------------
   RESPONSE Status: 400 The requested URI does not represent any resource on the server.      
   Content-Length: [438]
   Content-Type: [application/xml]
   Date: [Sat, 15 Apr 2023 14:43:41 GMT]
   Server: [Microsoft-HTTPAPI/2.0]
   X-Ms-Error-Code: [InvalidUri]
   X-Ms-Request-Id: [a31b34a1-401e-000c-3aa8-6fb698000000]

为什么?

bq3bfh9z

bq3bfh9z1#

怎么了?

请求中没有名为blobName的表单字段。

blobName := c.PostForm("blobName")

证据

错误消息对此很清楚:

Code: InvalidUri
UriPath: https://blablabla.blob.core.windows.net/teste/?blockid=mLa1s8Y9Tu6Tqw0umZ2kiwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==&comp=block&timeout=61
                                                      ^^^

相比于

fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s", accountName, containerName, blobName)
                                                 ^^^

显然blobName是空的。

说明

Postman 的请求

看起来像一个原始的HTTP请求:

POST /anything HTTP/1.1
Host: httpbin.org
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryeobf4rJjB8V8AYfS
 
----WebKitFormBoundaryeobf4rJjB8V8AYfS
Content-Disposition: form-data; name="upload"; filename="sample.pdf"

<content omitted>
----WebKitFormBoundaryeobf4rJjB8V8AYfS
Content-Disposition: form-data; name="blobName"
myBlobName
----WebKitFormBoundaryeobf4rJjB8V8AYfS

如果这样的请求由您的处理程序处理,

  • blobName := c.PostForm("blobName")将是myBlobName
  • files := form.File["upload"]; file := files[0]获取描述上传文件的文件头
  • file.Filename将是sample.pdf

相关问题