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 }