Search code examples
gohttpgo-gin

How could I send files to different servers in a process when using gin?


I was trying to send files to different servers by creat a POST request and send it.In my process I tried to send 3 POST, one to the first server and rest to another.

However it works only the first POST request,the rest requests get a 200 code but the files were still empty.I am not familiar with the http connection,how could I correct my programme? I would appreciate if you could help me!

Here is the function to receive a file.

func ReceivePublicKey() *gin.Engine {
    router := gin.Default()
    router.MaxMultipartMemory = 8 << 20
    //router.Static("/", "./static")
    router.POST("/receive", func(context *gin.Context) {
        file, _ := context.FormFile("file")
        log.Println(file.Filename)
        dst := "./" + file.Filename
        context.SaveUploadedFile(file, dst)
        context.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
        context.String(200, "server: receive publicKey successfully!")
    })
    return router
}

Here is the function to create and send the request

func CreateSendFileReq(file *os.File, fileName string, url string) *http.Request {
    bodyBuf := &bytes.Buffer{}
    bodyWrite := multipart.NewWriter(bodyBuf)
    fileWrite, err := bodyWrite.CreateFormFile("file", fileName)
    _, err = io.Copy(fileWrite, file)
    if err != nil {
        log.Println("err")
    }
    bodyWrite.Close() 
    if err != nil {
        log.Println("err")
    }
    req, _ := http.NewRequest("POST", url, bodyBuf)
    req.Header.Set("Content-Type", bodyWrite.FormDataContentType())
    return req
}

func SendRequest(r *http.Request) *http.Response {
    client := &http.Client{}
    resp, err := client.Do(r)
    if err == nil {
        return resp
    } else {
        log.Fatal(err)
        return nil
    }
}

And the function that doesnot work

func IotInit() {
    privateFile, _ := os.Open("private.pem")
    publicFile, _ := os.Open("public.pem")
    userId := GenerateIotId(publicFile)
    fmt.Println(userId)
    sendPrivateToServer := Controller.CreateSendFileReq(privateFile, userId+".pem", "http://192.168.42.129:8090/receive")

    sendPublicToUser := Controller.CreateSendFileReq(publicFile, "public.pem", "http://localhost:8090/receive")

    resp := Controller.SendRequest(sendPublicToUser)
    if resp.StatusCode != 200 {
        log.Fatal(resp.StatusCode)
    }
    resp.Body.Close()

    sendPrivateToUser := Controller.CreateSendFileReq(privateFile, "private.pem", "http://localhost:8090/receive")

    resp = Controller.SendRequest(sendPrivateToServer)
    if resp.StatusCode != 200 {
        log.Fatal(resp.StatusCode)
    }
    resp.Body.Close()

    resp = Controller.SendRequest(sendPrivateToUser)
    if resp.StatusCode != 200 {
        log.Fatal(resp.StatusCode)
    }
    resp.Body.Close()

    publicFile.Close()
    privateFile.Close()
}

Solution

  • OK just now I figured out my mistake. First I didnot check the size of file that explains why I get 200 code when save a empty file. Second in the IotInit() to get the userId I have used io.Copy() and made the file pointer point to the end of file,which explains why the "public.pem" is empty, I never copy any content to the requset body.Also I use io.Copy() when I create POST requests, the "private.pem" could also be empty.