From cd3438d6ae5dfb822d22d72dac632744de246367 Mon Sep 17 00:00:00 2001 From: r3inbowari Date: Sat, 10 Dec 2022 05:30:13 +0800 Subject: [PATCH 1/4] change: use a custom reader to allocate less memory when uploading --- speedtest/request.go | 7 +++---- speedtest/utils.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 speedtest/utils.go diff --git a/speedtest/request.go b/speedtest/request.go index dc3fa15..08d5f34 100644 --- a/speedtest/request.go +++ b/speedtest/request.go @@ -4,7 +4,6 @@ import ( "context" "io" "net/http" - "net/url" "strconv" "strings" "time" @@ -217,10 +216,10 @@ func downloadRequest(ctx context.Context, doer *http.Client, dlURL string, w int func uploadRequest(ctx context.Context, doer *http.Client, ulURL string, w int) error { size := ulSizes[w] - v := url.Values{} - v.Add("content", strings.Repeat("0123456789", size*100-51)) - req, err := http.NewRequestWithContext(ctx, http.MethodPost, ulURL, strings.NewReader(v.Encode())) + reader := NewRepeatReader(size*100*10 - 51) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, ulURL, reader) + req.ContentLength = reader.ContentLength if err != nil { return err } diff --git a/speedtest/utils.go b/speedtest/utils.go new file mode 100644 index 0000000..a05ab89 --- /dev/null +++ b/speedtest/utils.go @@ -0,0 +1,35 @@ +package speedtest + +import ( + "bytes" + "io" +) + +const readChunkSize = 1024 * 32 // 32 KBytes + +type RepeatReader struct { + ContentLength int64 + rs []byte + n int +} + +func NewRepeatReader(size int) *RepeatReader { + if size <= 0 { + panic("the size of repeated bytes should be > 0") + } + seqChunk := bytes.Repeat([]byte{0xAA}, readChunkSize) // uniformly distributed sequence of bits + return &RepeatReader{rs: seqChunk, ContentLength: int64(size), n: size} +} + +func (r *RepeatReader) Read(b []byte) (n int, err error) { + if r.n <= 0 { + return 0, io.EOF + } + if r.n < readChunkSize { + n = copy(b, r.rs[:r.n]) + } else { + n = copy(b, r.rs) + } + r.n -= n + return +} From a77ce7abad162a48f79bbcf99c3756506bb02ee6 Mon Sep 17 00:00:00 2001 From: r3inbowari Date: Sat, 10 Dec 2022 06:02:02 +0800 Subject: [PATCH 2/4] fix: wrong upload value --- speedtest/request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/speedtest/request.go b/speedtest/request.go index 08d5f34..64c1dff 100644 --- a/speedtest/request.go +++ b/speedtest/request.go @@ -217,7 +217,7 @@ func downloadRequest(ctx context.Context, doer *http.Client, dlURL string, w int func uploadRequest(ctx context.Context, doer *http.Client, ulURL string, w int) error { size := ulSizes[w] - reader := NewRepeatReader(size*100*10 - 51) + reader := NewRepeatReader((size*100 - 51) * 10) req, err := http.NewRequestWithContext(ctx, http.MethodPost, ulURL, reader) req.ContentLength = reader.ContentLength if err != nil { From 84745b8a405489a04dbce2568c3aad1b045e1f8f Mon Sep 17 00:00:00 2001 From: r3inbowari Date: Sat, 10 Dec 2022 07:20:39 +0800 Subject: [PATCH 3/4] fix: use the correct upload content-type --- speedtest/request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/speedtest/request.go b/speedtest/request.go index 64c1dff..024d1a9 100644 --- a/speedtest/request.go +++ b/speedtest/request.go @@ -224,7 +224,7 @@ func uploadRequest(ctx context.Context, doer *http.Client, ulURL string, w int) return err } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Content-Type", "application/octet-stream") resp, err := doer.Do(req) if err != nil { return err From 8e6841d51ec00df35be42c7a50681875968f527e Mon Sep 17 00:00:00 2001 From: r3inbowari Date: Tue, 13 Dec 2022 13:39:16 +0800 Subject: [PATCH 4/4] fix: remove unneeded condition --- speedtest/utils.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/speedtest/utils.go b/speedtest/utils.go index a05ab89..ffbfd2a 100644 --- a/speedtest/utils.go +++ b/speedtest/utils.go @@ -22,10 +22,10 @@ func NewRepeatReader(size int) *RepeatReader { } func (r *RepeatReader) Read(b []byte) (n int, err error) { - if r.n <= 0 { - return 0, io.EOF - } if r.n < readChunkSize { + if r.n <= 0 { + return n, io.EOF + } n = copy(b, r.rs[:r.n]) } else { n = copy(b, r.rs)