multipart writer创建表单文件卡住了。

huangapple go评论85阅读模式
英文:

multipart writer CreateFormFile stuck

问题

尝试使用Go语言发布multipart/form-data图像。

图像文件从请求客户端接收并已保存为multipart.File。

以下是我的代码:

func postImage(file multipart.File, url string, filename string) (*http.Response, error) {
	r, w := io.Pipe()
	defer w.Close()
	m := multipart.NewWriter(w)
	defer m.Close()

	errchan := make(chan error)
	defer close(errchan)

	go func() {
		part, err := m.CreateFormFile("file", filename)
		log.Println(err)
		if err != nil {
			errchan <- err
			return
		}

		if _, err := io.Copy(part, file); err != nil {
			errchan <- err
			return
		}
	}()

	merr := <-errchan
	if merr != nil {
		return nil, merr
	}

	resp, err := http.Post(url, m.FormDataContentType(), r)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	return resp, err
}

当我尝试使用它时,它在part, err := m.CreateFormFile("file", filename)处停止运行,没有返回任何内容。

有什么解决办法吗?

谢谢。

英文:

trying to post multipart/form-data image using go

image file receive from request client and already saved as multipart.File

here my code

func postImage(file multipart.File, url string, filename string) (*http.Response, error) {
	r, w := io.Pipe()
	defer w.Close()
	m := multipart.NewWriter(w)
	defer m.Close()

	errchan := make(chan error)
	defer close(errchan)

	go func() {
		part, err := m.CreateFormFile(&quot;file&quot;, filename)
		log.Println(err)
		if err != nil {
			errchan &lt;- err
			return
		}

		if _, err := io.Copy(part, file); err != nil {
			errchan &lt;- err
			return
		}
	}()

	merr := &lt;-errchan
	if merr != nil {
		return nil, merr
	}

	resp, err := http.Post(url, m.FormDataContentType(), r)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	return resp, err
}

when i try using it, it stuck at part, err := m.CreateFormFile(&quot;file&quot;, filename) never return anything

any solution?

Thanks

答案1

得分: 1

使用管道错误将错误传播回主goroutine。关闭管道的写入端,以防止客户端在读取时永远阻塞。关闭管道的读取端,以确保goroutine退出。

func postImage(file multipart.File, url string, filename string) (*http.Response, error) {
    r, w := io.Pipe()

    // 关闭管道的读取端,以确保在http.Post没有读取完整个请求体的情况下,goroutine能够退出。
    defer r.Close()

    m := multipart.NewWriter(w)

    go func() {
        part, err := m.CreateFormFile("file", filename)
        if err != nil {
            // 错误是从管道的读取操作返回的。
            w.CloseWithError(err)
            return
        }
        if _, err := io.Copy(part, file); err != nil {
            // 错误是从管道的读取操作返回的。
            w.CloseWithError(err)
            return
        }
        // http.Post函数会一直读取管道,直到出现错误或EOF。关闭管道以返回EOF给http.Post。
        w.Close()
    }()

    resp, err := http.Post(url, m.FormDataContentType(), r)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    return resp, err
}
英文:

Use the pipe error to propagate the error back to the main goroutine. Close the write side of the pipe to prevent the client from blocking forever on read. Close the read side of the pipe to ensure that the goroutine exits.

func postImage(file multipart.File, url string, filename string) (*http.Response, error) {
	r, w := io.Pipe()

    // Close the read side of the pipe to ensure that
    // the goroutine exits in the case where http.Post
    // does not read all of the request body.
	defer r.Close()

	m := multipart.NewWriter(w)

	go func() {
		part, err := m.CreateFormFile(&quot;file&quot;, filename)
		if err != nil {
            // The error is returned from read on the pipe.
			w.CloseWithError(err)
			return
		}
		if _, err := io.Copy(part, file); err != nil {
            // The error is returned from read on the pipe.
			w.CloseWithError(err)
			return
		}
        // The http.Post function reads the pipe until 
        // an error or EOF. Close to return an EOF to
        // http.Post.
		w.Close()
	}()

	resp, err := http.Post(url, m.FormDataContentType(), r)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	return resp, err
}

huangapple
  • 本文由 发表于 2021年6月2日 10:56:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/67798340.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定