func TestProgressReader(t *testing.T) { filename := "progress_test.go" f, err := os.Open(filename) defer f.Close() if err != nil { log.Fatalln(err) } fs, err := os.Stat(filename) if err != nil { log.Fatalln(err) } p := New() p.Total = fs.Size() p.Progress = func(current, total, expected int64) { log.Println("Reading", current, total, expected) assert.Equal(t, true, current <= total) } b := new(bytes.Buffer) r := syncreader.New(f, p) _, err = b.ReadFrom(r) if err != nil { log.Fatalln(err) } assert.Equal(t, fs.Size(), int64(b.Len())) }
func (r *Requester) Do() (*bytes.Buffer, error) { // lazy create request r.req = &http.Request{ Method: r.Method, URL: r.Url, Header: r.Header, } // uploading before if r.IsUpload { fields, _ := r.rawBody.(map[string]string) r.Form(r.files, fields) } if len(r.cookies) > 0 { for _, c := range r.cookies { r.req.AddCookie(c) } } // pack body r.packBody() // uploading after if r.IsUpload && r.pg != nil { r.pg.Total = r.Length r.Body = ioutil.NopCloser(syncreader.New(r.Body, r.pg)) } if r.Body != nil { if r.Header.Get("Content-Type") == "" { r.Header.Set("Content-Type", "application/x-www-form-urlencoded") } r.req.Body = r.Body if r.Length > 0 { r.req.ContentLength = r.Length } } var ( res *http.Response err error ) switch r.Url.Scheme { case "http", "https": r.transport = new(http.Transport) if r.tlsconfig != nil { r.transport.TLSClientConfig = r.tlsconfig } r.client = &http.Client{Transport: r.transport, Timeout: r.timeout} res, err = r.client.Do(r.req) if err != nil { return nil, err } break default: // TODO @fundon, customzie conn, err := net.Dial(r.Url.Scheme, r.Url.Host) if err != nil { return nil, err } r.clientConn = httputil.NewClientConn(conn, nil) res, err = r.clientConn.Do(r.req) if err != nil { return nil, err } } defer res.Body.Close() r.res = res r.StatusCode = res.StatusCode // hack, return response header r.Header = res.Header r.Buffer = new(bytes.Buffer) dw := io.MultiWriter(r.Buffer) // downloading if r.IsDownload { var fw io.Writer switch t := r.destination.(type) { case string: p, err := filepath.Abs(t) if err != nil { return nil, err } f, err := os.Create(p) defer f.Close() if err != nil { return nil, err } fw = f break default: fw, _ = t.(io.Writer) } if r.pg != nil { r.pg.Total = res.ContentLength } dw = io.MultiWriter(dw, r.pg, fw) if err != nil { return nil, err } } _, err = io.Copy(dw, res.Body) if err != nil { return nil, err } return r.Buffer, nil }