Skip to content

Commit b589d0b

Browse files
committed
chore(filer): zero copy upload file
1 parent 0168972 commit b589d0b

2 files changed

Lines changed: 26 additions & 22 deletions

File tree

volumes/filer.go

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
package volumes
33

44
import (
5+
"bytes"
56
"encoding/json"
67
"fmt"
78
"io"
89
"mime/multipart"
910
"net/http"
1011
"net/url"
12+
"strings"
1113

1214
drycc "github.com/drycc/controller-sdk-go"
1315
"github.com/drycc/controller-sdk-go/api"
@@ -42,32 +44,29 @@ func GetFile(c *drycc.Client, appID, volumeID, path string) (*http.Response, err
4244
}
4345

4446
// Put file to an app's volume.
45-
func PostFile(c *drycc.Client, appID, volumeID, volumePath, name string, reader io.Reader) (*http.Response, error) {
46-
pr, pw := io.Pipe()
47-
writer := multipart.NewWriter(pw)
48-
go func() {
49-
if err := writer.WriteField("path", volumePath); err != nil {
50-
pw.CloseWithError(err)
51-
return
52-
}
53-
part, err := writer.CreateFormFile("file", name)
54-
if err != nil {
55-
pw.CloseWithError(err)
56-
return
57-
}
58-
_, err = io.Copy(part, reader)
59-
if err != nil {
60-
pw.CloseWithError(err)
61-
return
62-
}
63-
pw.CloseWithError(writer.Close())
64-
}()
47+
func PostFile(c *drycc.Client, appID, volumeID, volumePath, name string, size int64, reader io.Reader) (*http.Response, error) {
6548

49+
buffer := new(bytes.Buffer)
50+
writer := multipart.NewWriter(buffer)
51+
if err := writer.WriteField("path", volumePath); err != nil {
52+
return nil, err
53+
}
54+
if _, err := writer.CreateFormFile("file", name); err != nil {
55+
return nil, err
56+
}
57+
size += int64(buffer.Len())
58+
head := strings.NewReader(buffer.String())
59+
buffer.Reset()
60+
writer.Close()
61+
bottom := strings.NewReader(buffer.String())
62+
size += int64(buffer.Len())
6663
u := fmt.Sprintf("/v2/apps/%s/volumes/%s/client/", appID, volumeID)
67-
r, err := c.NewRequest("POST", u, pr)
64+
65+
r, err := c.NewRequest("POST", u, io.MultiReader(head, reader, bottom))
6866
if err != nil {
6967
return nil, err
7068
}
69+
r.ContentLength = size
7170
r.Header.Add("Content-Type", writer.FormDataContentType())
7271
return c.Do(r)
7372
}

volumes/filer_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,12 @@ func TestVolumesPostFile(t *testing.T) {
147147
}
148148
defer file.Close()
149149

150-
if _, err := PostFile(drycc, "example-go", "myvolume", "tmp/", file.Name(), file); err != nil {
150+
fileinfo, err := file.Stat()
151+
if err != nil {
152+
t.Fatal(err)
153+
}
154+
155+
if _, err := PostFile(drycc, "example-go", "myvolume", "tmp/", file.Name(), fileinfo.Size(), file); err != nil {
151156
t.Fatal(err)
152157
}
153158

0 commit comments

Comments
 (0)