func genProgressBar(file *os.File, label string) (io.Reader, error) { finfo, err := file.Stat() if err != nil { return nil, err } var prefix string if label != "" { prefix = "Uploading " + label } else { prefix = "Uploading" } fmtBytesSize := 18 barSize := int64(80 - len(prefix) - fmtBytesSize) bar := ioprogress.DrawTextFormatBarForW(barSize, os.Stderr) fmtfunc := func(progress, total int64) string { // Content-Length is set to -1 when unknown. if total == -1 { return fmt.Sprintf( "%s: %v of an unknown total size", prefix, ioprogress.ByteUnitStr(progress), ) } return fmt.Sprintf( "%s: %s %s", prefix, bar(progress, total), ioprogress.DrawTextFormatBytes(progress, total), ) } return &ioprogress.Reader{ Reader: file, Size: finfo.Size(), DrawFunc: ioprogress.DrawTerminalf(os.Stderr, fmtfunc), DrawInterval: time.Second, }, nil }
func (u Uploader) performRequest(reqType string, url string, body io.Reader, draw bool, label *string) (io.ReadCloser, error) { if fbody, ok := body.(*os.File); draw && ok { finfo, err := fbody.Stat() if err != nil { return nil, err } if u.Debug { var prefix string if label != nil { prefix = "Uploading " + *label } else { prefix = "Uploading" } fmtBytesSize := 18 barSize := int64(80 - len(prefix) - fmtBytesSize) bar := ioprogress.DrawTextFormatBarForW(barSize, os.Stderr) fmtfunc := func(progress, total int64) string { // Content-Length is set to -1 when unknown. if total == -1 { return fmt.Sprintf( "%s: %v of an unknown total size", prefix, ioprogress.ByteUnitStr(progress), ) } return fmt.Sprintf( "%s: %s %s", prefix, bar(progress, total), ioprogress.DrawTextFormatBytes(progress, total), ) } body = &ioprogress.Reader{ Reader: fbody, Size: finfo.Size(), DrawFunc: ioprogress.DrawTerminalf(os.Stderr, fmtfunc), DrawInterval: time.Second, } } } req, err := http.NewRequest(reqType, url, body) if err != nil { return nil, err } transport := http.DefaultTransport if u.Insecure { transport = &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } } u.SetHTTPHeaders(req) client := &http.Client{Transport: transport} client.CheckRedirect = func(req *http.Request, via []*http.Request) error { if len(via) >= 10 { return fmt.Errorf("too many redirects") } u.SetHTTPHeaders(req) return nil } res, err := client.Do(req) if err != nil { return nil, err } switch res.StatusCode { case http.StatusOK: return res.Body, nil case http.StatusBadRequest: return res.Body, nil default: res.Body.Close() return nil, fmt.Errorf("bad HTTP status code: %d", res.StatusCode) } }