yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcso/client/requests/requests.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package requests
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"net/url"
    21  	"sort"
    22  	"strings"
    23  )
    24  
    25  type IRequest interface {
    26  	GetScheme() string
    27  	GetMethod() string
    28  	GetEndpoint() string
    29  	GetPort() string
    30  	GetRegionId() string
    31  	GetProjectId() string
    32  	GetHost() string
    33  	GetURI() string
    34  	GetHeaders() map[string]string
    35  	GetQueryParams() map[string]string
    36  	GetFormParams() map[string]string
    37  	GetContent() []byte
    38  	GetBodyReader() io.Reader
    39  	GetProduct() string
    40  	GetVersion() string
    41  
    42  	SetStringToSign(stringToSign string)
    43  	GetStringToSign() string
    44  
    45  	SetContent(content []byte)
    46  	SetScheme(scheme string)
    47  	BuildUrl() string
    48  	BuildQueries() string
    49  
    50  	AddHeaderParam(key, value string)
    51  	AddQueryParam(key, value string)
    52  	AddFormParam(key, value string)
    53  }
    54  
    55  type SRequest struct {
    56  	Scheme   string // HTTP、HTTPS
    57  	Method   string // GET、PUT、DELETE、POST、PATCH
    58  	Endpoint string // ecs.cn-north-1.myhuaweicloud.com
    59  	Port     string // 80
    60  	RegionId string // cn-north-1
    61  
    62  	product   string // 弹性云服务 ECS : ecs
    63  	version   string // API版本: v2
    64  	projectId string // 项目ID: 43cbe5e77aaf4665bbb962062dc1fc9d.可以为空。
    65  
    66  	resourcePath string // /users/{user_id}/groups
    67  	QueryParams  map[string]string
    68  	Headers      map[string]string
    69  	FormParams   map[string]string
    70  	Content      []byte
    71  
    72  	queries string
    73  
    74  	stringToSign string
    75  }
    76  
    77  func (self *SRequest) GetProjectId() string {
    78  	return self.projectId
    79  }
    80  
    81  func (self *SRequest) GetScheme() string {
    82  	return self.Scheme
    83  }
    84  
    85  func (self *SRequest) GetMethod() string {
    86  	return self.Method
    87  }
    88  
    89  func (self *SRequest) GetEndpoint() string {
    90  	return self.Endpoint
    91  }
    92  
    93  func (self *SRequest) GetRegionId() string {
    94  	return self.RegionId
    95  }
    96  
    97  func (self *SRequest) GetPort() string {
    98  	return self.Port
    99  }
   100  
   101  func (self *SRequest) GetHeaders() map[string]string {
   102  	return self.Headers
   103  }
   104  
   105  func (self *SRequest) GetQueryParams() map[string]string {
   106  	return self.QueryParams
   107  }
   108  
   109  func (self *SRequest) GetFormParams() map[string]string {
   110  	return self.FormParams
   111  }
   112  
   113  func (self *SRequest) GetContent() []byte {
   114  	return self.Content
   115  }
   116  
   117  func (self *SRequest) GetBodyReader() io.Reader {
   118  	if self.FormParams != nil && len(self.FormParams) > 0 {
   119  		formData := GetUrlFormedMap(self.FormParams)
   120  		return strings.NewReader(formData)
   121  	} else {
   122  		return strings.NewReader(string(self.Content))
   123  	}
   124  }
   125  
   126  func (self *SRequest) GetProduct() string {
   127  	return self.product
   128  }
   129  
   130  func (self *SRequest) GetVersion() string {
   131  	return self.version
   132  }
   133  
   134  func (self *SRequest) SetStringToSign(stringToSign string) {
   135  	self.stringToSign = stringToSign
   136  }
   137  
   138  func (self *SRequest) GetStringToSign() string {
   139  	return self.stringToSign
   140  }
   141  
   142  func (self *SRequest) SetContent(content []byte) {
   143  	self.Content = content
   144  }
   145  
   146  func (self *SRequest) SetScheme(scheme string) {
   147  	self.Scheme = scheme
   148  }
   149  
   150  func (self *SRequest) BuildUrl() string {
   151  	scheme := strings.ToLower(self.Scheme)
   152  	baseUrl := fmt.Sprintf("%s://%s", scheme, self.GetHost())
   153  	queries := self.BuildQueries()
   154  	if len(queries) > 0 {
   155  		return baseUrl + self.GetURI() + "?" + queries
   156  	} else {
   157  		return baseUrl + self.GetURI()
   158  	}
   159  }
   160  
   161  func (self *SRequest) GetHost() string {
   162  	scheme := strings.ToLower(self.Scheme)
   163  	host := self.GetEndpoint()
   164  	if len(self.Port) > 0 {
   165  		if (scheme == "http" && self.Port == "80") || (scheme == "https" && self.Port == "443") {
   166  			host = fmt.Sprintf("%s:%s", host, self.Port)
   167  		}
   168  	}
   169  
   170  	return host
   171  }
   172  
   173  func (self *SRequest) GetURI() string {
   174  	// URI
   175  	uri := ""
   176  	for _, m := range []string{self.version, self.projectId} {
   177  		if len(m) > 0 {
   178  			uri += fmt.Sprintf("/%s", m)
   179  		}
   180  	}
   181  
   182  	if len(self.resourcePath) > 0 {
   183  		s := ""
   184  		if !strings.HasPrefix(self.resourcePath, "/") {
   185  			s = "/"
   186  		}
   187  
   188  		if strings.HasSuffix(self.resourcePath, "/") {
   189  			strings.TrimSuffix(s, "/")
   190  		}
   191  
   192  		uri = uri + s + self.resourcePath
   193  	}
   194  
   195  	return uri
   196  }
   197  
   198  func (self *SRequest) BuildQueries() string {
   199  	self.queries = GetUrlFormedMap(self.QueryParams)
   200  	return self.queries
   201  }
   202  
   203  func (self *SRequest) AddHeaderParam(key, value string) {
   204  	self.Headers[key] = value
   205  }
   206  
   207  func (self *SRequest) AddQueryParam(key, value string) {
   208  	self.QueryParams[key] = value
   209  }
   210  
   211  func (self *SRequest) AddFormParam(key, value string) {
   212  	self.FormParams[key] = value
   213  }
   214  
   215  func GetUrlFormedMap(source map[string]string) string {
   216  	// 按key排序后编译
   217  	keys := make([]string, 0)
   218  	for k := range source {
   219  		keys = append(keys, k)
   220  	}
   221  
   222  	sort.Slice(keys, func(i, j int) bool {
   223  		return strings.ToLower(keys[i]) < strings.ToLower(keys[j])
   224  	})
   225  
   226  	urlEncoder := url.Values{}
   227  	for _, k := range keys {
   228  		urlEncoder.Add(k, source[k])
   229  	}
   230  
   231  	return urlEncoder.Encode()
   232  }
   233  
   234  func defaultRequest() (request *SRequest) {
   235  	request = &SRequest{
   236  		Scheme:      "HTTPS",
   237  		Method:      "GET",
   238  		QueryParams: make(map[string]string),
   239  		Headers:     map[string]string{},
   240  		FormParams:  make(map[string]string),
   241  	}
   242  	return
   243  }
   244  
   245  func NewResourceRequest(endpoint, method, product, version, region, project, resourcePath string) *SRequest {
   246  	return &SRequest{
   247  		Scheme:       "HTTPS",
   248  		Method:       method,
   249  		Endpoint:     endpoint,
   250  		product:      product,
   251  		RegionId:     region,
   252  		version:      version,
   253  		projectId:    project,
   254  		resourcePath: resourcePath,
   255  		QueryParams:  make(map[string]string),
   256  		Headers:      map[string]string{},
   257  		FormParams:   make(map[string]string),
   258  	}
   259  }