转到版本:1.6.3 macos
我正在尝试编写一个api来将apk文件(大多数情况下为几MB)上传到服务器。这是客户端代码:
func syncApk(apkFile *os.File) {
defer apkFile.Close()
var buffer bytes.Buffer
writer := multipart.NewWriter(&buffer)
defer writer.Close()
part, err := writer.CreateFormFile("apk", filepath.Base(apkFile.Name()))
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating form file: %v\n", err)
return
}
size, err := io.Copy(part, apkFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error copying apk file data: %v\n", err)
return
}
fmt.Fprintf(os.Stdout, "Copied %v bytes for uploading...\n", size)
response, err := http.Post("http://localhost:8080/upload", writer.FormDataContentType(), &buffer)
if err != nil {
fmt.Fprintf(os.Stderr, "Error making POST request to sync apk: %v\n", err)
return
}
fmt.Fprintf(os.Stdout, "Successfully uploaded apk file: %v\n", response.StatusCode)
}
服务器代码:
func main() {
server := http.Server{
Addr: ":8080",
}
http.HandleFunc("/upload", doApkUpload)
server.ListenAndServe()
}
func doApkUpload(w http.ResponseWriter, r *http.Request) {
file, _, err := r.FormFile("apk")
if err != nil {
fmt.Fprintf(os.Stderr, "Error retrieving apk file: %v\n", err)
return
}
data, err := ioutil.ReadAll(file)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading apk file content: %v", err)
return
}
fmt.Fprintf(os.Stdout, string(data))
}
在localhost上运行服务器后,运行客户端代码,我得到:
Copied 1448401 bytes for uploading...
Successfully uploaded apk file: 200
看起来多部分文件写得正确。但是我在服务器端看到了这个错误:
Error retrieving apk file: unexpected EOF
知道问题出在哪里?谢谢!
答案 0 :(得分:2)
错误表示读者在请求正文结束后需要更多数据。缺少的数据是multipart Close方法写入的尾随边界结束行。
在写完所有部分之后和发布表单之前调用Close方法。
func syncApk(apkFile *os.File) {
defer apkFile.Close()
var buffer bytes.Buffer
writer := multipart.NewWriter(&buffer)
part, err := writer.CreateFormFile("apk", filepath.Base(apkFile.Name()))
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating form file: %v\n", err)
return
}
size, err := io.Copy(part, apkFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error copying apk file data: %v\n", err)
return
}
fmt.Fprintf(os.Stdout, "Copied %v bytes for uploading...\n", size)
writer.Close()
response, err := http.Post("http://localhost:8080/upload", writer.FormDataContentType(), &buffer)
if err != nil {
fmt.Fprintf(os.Stderr, "Error making POST request to sync apk: %v\n", err)
return
}
defer response.Body.Clse()
fmt.Fprintf(os.Stdout, "Successfully uploaded apk file: %v\n", response.StatusCode)
}