diff --git a/speedtest/data_manager.go b/speedtest/data_manager.go index 7ae2a48..21a3982 100644 --- a/speedtest/data_manager.go +++ b/speedtest/data_manager.go @@ -464,41 +464,20 @@ func (dc *DataChunk) GetParent() Manager { return dc.manager } -// WriteTo Used to hook all traffic. -func (dc *DataChunk) WriteTo(w io.Writer) (written int64, err error) { - nw := 0 - nr := readChunkSize - for { - dc.manager.runningRW.RLock() - running := dc.manager.running - dc.manager.runningRW.RUnlock() - if !running || dc.remainOrDiscardSize <= 0 { +func (dc *DataChunk) Read(b []byte) (n int, err error) { + if dc.remainOrDiscardSize < readChunkSize { + if dc.remainOrDiscardSize <= 0 { dc.endTime = time.Now() - return written, io.EOF - } - if dc.remainOrDiscardSize < readChunkSize { - nr = int(dc.remainOrDiscardSize) - nw, err = w.Write((*dc.manager.repeatByte)[:nr]) - } else { - nw, err = w.Write(*dc.manager.repeatByte) - } - if err != nil { - return - } - n64 := int64(nw) - written += n64 - dc.remainOrDiscardSize -= n64 - dc.manager.AddTotalUpload(n64) - if nr != nw { - return written, io.ErrShortWrite + return n, io.EOF } + n = copy(b, (*dc.manager.repeatByte)[:dc.remainOrDiscardSize]) + } else { + n = copy(b, *dc.manager.repeatByte) } -} - -// Please don't call it, only used to wrapped by [io.NopCloser] -// We use [DataChunk.WriteTo] that implements [io.WriterTo] to bypass this function. -func (dc *DataChunk) Read(b []byte) (n int, err error) { - panic("unexpected call: only used to implement the io.Reader") + n64 := int64(n) + dc.remainOrDiscardSize -= n64 + dc.manager.AddTotalUpload(n64) + return } // calcMAFilter Median-Averaging Filter diff --git a/speedtest/request.go b/speedtest/request.go index f188d56..3b7d6d1 100644 --- a/speedtest/request.go +++ b/speedtest/request.go @@ -185,17 +185,20 @@ func downloadRequest(ctx context.Context, s *Server, w int) error { func uploadRequest(ctx context.Context, s *Server, w int) error { size := ulSizes[w] - dc := s.Context.NewChunk().UploadHandler(int64(size*100-51) * 10) + chunkSize := int64(size*100-51) * 10 + dc := s.Context.NewChunk().UploadHandler(chunkSize) req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.URL, io.NopCloser(dc)) if err != nil { return err } + req.ContentLength = chunkSize dbg.Printf("Len=%d, XulURL: %s\n", req.ContentLength, s.URL) req.Header.Set("Content-Type", "application/octet-stream") resp, err := s.Context.doer.Do(req) if err != nil { return err } + _, _ = io.Copy(io.Discard, resp.Body) defer resp.Body.Close() return err }