我认为我的文件上传连接正在关闭...为什么?

时间:2019-07-06 01:50:24

标签: http go

免责声明:我不确定标题是否是我的实际问题,但这是唯一有意义的解释。

场景

我正在将大型视频上传到我的Golang服务器。我有一个8GB的文件,在本地大约需要15分钟,并且运行良好。但是,在我的登台服务器(Google Cloud)上,此文件需要花一个多小时才能上传,这就是问题所在。

问题

我的客户端正在等待文件完成上传,以调用另一个API端点,但是只有在登台服务器上它才会失败。这样看来,当我的服务器希望编写响应时,连接将不允许它,因为客户端显示了502错误和CORS错误,我知道这是Chrome所说的“我们不愿意”不知道,请检查您的服务器”。

代码

在我的SrcHandler里面是这样:

defer func(begin time.Time) {
        pr, pw := io.Pipe()
        defer pw.Close()

        if err := r.ParseMultipartForm(32 << 20); err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            fmt.Printf("%v\n", err)
            return
        }

        srcFile, handler, err := r.FormFile("video")
        if err != nil {
            http.Error(w, "INVALID_FILE", http.StatusBadRequest)
            return
        }
        defer srcFile.Close()

        // Copy uploaded file to *PipeWriter
        go func() {
            defer srcFile.Close()
            defer pw.Close()
            io.Copy(pw, srcFile)
        }()

        // Prep fileName
        var srcFileName = strings.Replace(handler.Filename, " ", "_", -1)
        var extension = filepath.Ext(srcFileName)
        srcFileName = srcFileName[0 : len(srcFileName)-len(extension)]

        // Create temp file to write too
        f, err := ioutil.TempFile("./tmp/pending", srcFileName+"_")
        if err != nil {
            log.Fatal(err)
        }
        defer f.Close()

        // Copy *PipeReader to temp file
        io.Copy(f, pr)

        contentType, err := getFileContentType("./" + f.Name())
        if err != nil {
            fmt.Printf("Content Type Error: %v\n", err)
            return
        }

        fmt.Printf("ContentType = %v\n ", contentType)
        if contentType != "video/x-flv" && contentType != "video/mp4" &&
            contentType != "video/quicktime" && contentType != "video/x-msvideo" &&
            contentType != "video/x-ms-wmv" && contentType != "video/webm" {
            http.Error(w, "INVALID_FILE_TYPE", http.StatusBadRequest)
            os.Remove(f.Name())
            return
        }

        fmt.Printf("Upload path -> %v\n", f.Name())
        upload := UploaderResponse{srcFileName, "./" + f.Name()}

        resp, err := json.Marshal(upload)
        if err != nil {
            fmt.Printf("Error using Marshal %v\n", err)
        }

        w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusOK)

        status, err2 := w.Write(resp)
        if err2 != nil {
            fmt.Printf("Error when writing response to app %v\n", err2)
        } else {
            fmt.Printf("Status from uploading: %v\n", status)
        }

        _ = u.logger.Log("upload.Handler Duration ", time.Since(begin))

    }(time.Now())

代码下降到最后一行,u.logger.Log()实际上显示输出。因此视频已正确上传...仅响应客户端失败。有人有想法吗?

免责声明2:我刚刚发现w.Write返回错误,因此我正在等待文件完成上传,看看是否记录了错误。将以更新进行响应。

更新1

我上传了一个新文件,并且w.Write()调用成功,返回了91整数。我不确定现在可能是什么问题。可能是我不知道的地方超时了。仅供参考,我的服务器读写超时均为6小时。

如果有帮助,请参阅以下日志。在输出中跟随代码应该很容易: enter image description here

1 个答案:

答案 0 :(得分:0)

我当时在球场上提到超时,但事实证明此问题与代码无关。我偶然发现了另一个具有相同问题的SO post,但在AWS上。问题是负载均衡器超时。我使用了Google Cloud's docs中的说明,将超时从默认的30秒增加到几个小时。具体来说,超时设置是对服务器等待发送响应到客户端的等待时间的计数。