github.com/qiniu/go-sdk/v7@v7.27.0/internal/clientv2/client.go (about)

     1  package clientv2
     2  
     3  import (
     4  	"net/http"
     5  	"reflect"
     6  	"sort"
     7  	"sync"
     8  
     9  	clientV1 "github.com/qiniu/go-sdk/v7/client"
    10  	internal_io "github.com/qiniu/go-sdk/v7/internal/io"
    11  )
    12  
    13  type Client interface {
    14  	Do(req *http.Request) (*http.Response, error)
    15  }
    16  
    17  type Handler func(req *http.Request) (*http.Response, error)
    18  
    19  type client struct {
    20  	coreClient        Client
    21  	interceptors      interceptorList
    22  	interceptorsMutex sync.RWMutex
    23  }
    24  
    25  func NewClient(cli Client, interceptors ...Interceptor) Client {
    26  	if cli == nil {
    27  		cli = NewClientWithClientV1(&clientV1.DefaultClient)
    28  	}
    29  
    30  	var is interceptorList = interceptors
    31  	is = append(is, newDefaultHeaderInterceptor())
    32  	is = append(is, newDebugInterceptor())
    33  
    34  	if c, ok := cli.(*client); ok {
    35  		c.addInterceptors(is)
    36  		return c
    37  	}
    38  
    39  	sort.Sort(is)
    40  	return &client{
    41  		coreClient:   cli,
    42  		interceptors: is,
    43  	}
    44  }
    45  
    46  func (c *client) addInterceptors(is interceptorList) {
    47  	c.interceptorsMutex.Lock()
    48  	defer c.interceptorsMutex.Unlock()
    49  
    50  	for _, i := range is {
    51  		c.addInterceptor(i)
    52  	}
    53  	sort.Sort(c.interceptors)
    54  }
    55  
    56  func (c *client) addInterceptor(interceptor Interceptor) {
    57  	for _, i := range c.interceptors {
    58  		if reflect.TypeOf(i) == reflect.TypeOf(interceptor) {
    59  			return
    60  		}
    61  	}
    62  	c.interceptors = append(c.interceptors, interceptor)
    63  }
    64  
    65  func (c *client) mergeInterceptors(req *http.Request) interceptorList {
    66  	c.interceptorsMutex.RLock()
    67  	defer c.interceptorsMutex.RUnlock()
    68  
    69  	intercetorsFromRequest := getIntercetorsFromRequest(req)
    70  	newInterceptorList := make(interceptorList, 0, len(c.interceptors)+len(intercetorsFromRequest))
    71  	if len(intercetorsFromRequest) == 0 {
    72  		newInterceptorList = append(newInterceptorList, c.interceptors...)
    73  	} else if len(c.interceptors) == 0 {
    74  		newInterceptorList = intercetorsFromRequest
    75  	} else {
    76  		newInterceptorList = append(newInterceptorList, c.interceptors...)
    77  		newInterceptorList = append(newInterceptorList, intercetorsFromRequest...)
    78  		sort.Sort(newInterceptorList)
    79  	}
    80  	return newInterceptorList
    81  }
    82  
    83  func (c *client) Do(req *http.Request) (*http.Response, error) {
    84  	handler := func(req *http.Request) (*http.Response, error) {
    85  		return c.coreClient.Do(req)
    86  	}
    87  	newInterceptorList := c.mergeInterceptors(req)
    88  	for _, interceptor := range newInterceptorList {
    89  		h := handler
    90  		i := interceptor
    91  		handler = func(r *http.Request) (*http.Response, error) {
    92  			return i.Intercept(r, h)
    93  		}
    94  	}
    95  
    96  	return handleResponseAndError(handler(req))
    97  }
    98  
    99  func Do(c Client, options RequestParams) (*http.Response, error) {
   100  	req, err := NewRequest(options)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	return handleResponseAndError(c.Do(req))
   106  }
   107  
   108  func handleResponseAndError(resp *http.Response, err error) (*http.Response, error) {
   109  	if err != nil {
   110  		return resp, err
   111  	}
   112  
   113  	if resp == nil {
   114  		return nil, &clientV1.ErrorInfo{
   115  			Code: -999,
   116  			Err:  "unknown error, no response",
   117  		}
   118  	}
   119  
   120  	if resp.StatusCode/100 != 2 {
   121  		return resp, clientV1.ResponseError(resp)
   122  	}
   123  
   124  	return resp, nil
   125  }
   126  
   127  func DoAndDecodeJsonResponse(c Client, options RequestParams, ret interface{}) error {
   128  	resp, err := Do(c, options)
   129  	defer func() {
   130  		if resp != nil && resp.Body != nil {
   131  			_ = internal_io.SinkAll(resp.Body)
   132  			resp.Body.Close()
   133  		}
   134  	}()
   135  
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	if ret == nil || resp.ContentLength == 0 {
   141  		return nil
   142  	}
   143  
   144  	if err = clientV1.DecodeJsonFromReader(resp.Body, ret); err != nil {
   145  		return err
   146  	}
   147  
   148  	return nil
   149  }
   150  
   151  type clientV1Wrapper struct {
   152  	c *clientV1.Client
   153  }
   154  
   155  func (c *clientV1Wrapper) Do(req *http.Request) (*http.Response, error) {
   156  	return c.c.Do(req.Context(), req)
   157  }
   158  
   159  func NewClientWithClientV1(c *clientV1.Client) Client {
   160  	if c == nil {
   161  		c = &clientV1.DefaultClient
   162  	}
   163  	return &clientV1Wrapper{
   164  		c: c,
   165  	}
   166  }