英文:
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("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
}
when i try using it, it stuck at part, err := m.CreateFormFile("file", 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("file", 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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论