github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/client/http/upload.go (about)

     1  package http
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net/http"
     7  	"os"
     8  	"path/filepath"
     9  )
    10  
    11  // see: https://github.com/shenghui0779/gochat/blob/master/wx/http.go
    12  
    13  // UploadForm is the interface for http upload
    14  type UploadForm interface {
    15  	// FieldName returns field name for upload
    16  	FieldName() string
    17  
    18  	// FileName returns filename for upload
    19  	FileName() string
    20  
    21  	// ExtraFields returns extra fields for upload
    22  	ExtraFields() map[string]string
    23  
    24  	// Buffer returns the buffer of media
    25  	Buffer() ([]byte, error)
    26  }
    27  
    28  type httpUpload struct {
    29  	fieldName   string
    30  	filename    string
    31  	resourceURL string
    32  	extraFields map[string]string
    33  }
    34  
    35  func (u *httpUpload) FieldName() string {
    36  	return u.fieldName
    37  }
    38  
    39  func (u *httpUpload) FileName() string {
    40  	return u.filename
    41  }
    42  
    43  func (u *httpUpload) ExtraFields() map[string]string {
    44  	return u.extraFields
    45  }
    46  
    47  func (u *httpUpload) Buffer() ([]byte, error) {
    48  	if len(u.resourceURL) != 0 {
    49  		resp, err := http.Get(u.resourceURL)
    50  
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  
    55  		defer resp.Body.Close()
    56  
    57  		if resp.StatusCode != http.StatusOK {
    58  			return nil, fmt.Errorf("error http code: %d", resp.StatusCode)
    59  		}
    60  
    61  		return io.ReadAll(resp.Body)
    62  	}
    63  
    64  	path, err := filepath.Abs(u.filename)
    65  
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	return os.ReadFile(path)
    71  }
    72  
    73  // UploadOption configures how we set up the http upload from.
    74  type UploadOption func(u *httpUpload)
    75  
    76  // WithResourceURL specifies http upload by resource url.
    77  func WithResourceURL(url string) UploadOption {
    78  	return func(u *httpUpload) {
    79  		u.resourceURL = url
    80  	}
    81  }
    82  
    83  // WithExtraField specifies the extra field to http upload from.
    84  func WithExtraField(key, value string) UploadOption {
    85  	return func(u *httpUpload) {
    86  		u.extraFields[key] = value
    87  	}
    88  }
    89  
    90  // NewUploadForm returns new upload form
    91  func NewUploadForm(fieldName, filename string, options ...UploadOption) UploadForm {
    92  	form := &httpUpload{
    93  		fieldName: fieldName,
    94  		filename:  filename,
    95  	}
    96  
    97  	if len(options) != 0 {
    98  		form.extraFields = make(map[string]string)
    99  
   100  		for _, f := range options {
   101  			f(form)
   102  		}
   103  	}
   104  
   105  	return form
   106  }