yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/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 GetDomain() 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 SetDomain(domain string) 46 SetContent(content []byte) 47 SetScheme(scheme string) 48 BuildUrl() string 49 BuildQueries() string 50 51 AddHeaderParam(key, value string) 52 AddQueryParam(key, value string) 53 AddFormParam(key, value string) 54 } 55 56 type SRequest struct { 57 Scheme string // HTTP、HTTPS 58 Method string // GET、PUT、DELETE、POST、PATCH 59 Domain string // myhuaweicloud.com 60 Port string // 80 61 RegionId string // cn-north-1 62 63 product string // 弹性云服务 ECS : ecs 64 version string // API版本: v2 65 projectId string // 项目ID: 43cbe5e77aaf4665bbb962062dc1fc9d.可以为空。 66 67 resourcePath string // /users/{user_id}/groups 68 QueryParams map[string]string 69 Headers map[string]string 70 FormParams map[string]string 71 Content []byte 72 73 queries string 74 75 stringToSign string 76 } 77 78 func (self *SRequest) GetProjectId() string { 79 return self.projectId 80 } 81 82 func (self *SRequest) GetScheme() string { 83 return self.Scheme 84 } 85 86 func (self *SRequest) GetMethod() string { 87 return self.Method 88 } 89 90 func (self *SRequest) GetDomain() string { 91 return self.Domain 92 } 93 94 func (self *SRequest) GetPort() string { 95 return self.Port 96 } 97 98 func (self *SRequest) GetRegionId() string { 99 return self.RegionId 100 } 101 102 func (self *SRequest) GetHeaders() map[string]string { 103 return self.Headers 104 } 105 106 func (self *SRequest) GetQueryParams() map[string]string { 107 return self.QueryParams 108 } 109 110 func (self *SRequest) GetFormParams() map[string]string { 111 return self.FormParams 112 } 113 114 func (self *SRequest) GetContent() []byte { 115 return self.Content 116 } 117 118 func (self *SRequest) GetBodyReader() io.Reader { 119 if self.FormParams != nil && len(self.FormParams) > 0 { 120 formData := GetUrlFormedMap(self.FormParams) 121 return strings.NewReader(formData) 122 } else { 123 return strings.NewReader(string(self.Content)) 124 } 125 } 126 127 func (self *SRequest) GetProduct() string { 128 return self.product 129 } 130 131 func (self *SRequest) GetVersion() string { 132 return self.version 133 } 134 135 func (self *SRequest) SetStringToSign(stringToSign string) { 136 self.stringToSign = stringToSign 137 } 138 139 func (self *SRequest) GetStringToSign() string { 140 return self.stringToSign 141 } 142 143 func (self *SRequest) SetDomain(domain string) { 144 self.Domain = domain 145 } 146 147 func (self *SRequest) SetContent(content []byte) { 148 self.Content = content 149 } 150 151 func (self *SRequest) SetScheme(scheme string) { 152 self.Scheme = scheme 153 } 154 155 func (self *SRequest) BuildUrl() string { 156 scheme := strings.ToLower(self.Scheme) 157 baseUrl := fmt.Sprintf("%s://%s", scheme, self.GetHost()) 158 queries := self.BuildQueries() 159 if len(queries) > 0 { 160 return baseUrl + self.GetURI() + "?" + queries 161 } else { 162 return baseUrl + self.GetURI() 163 } 164 } 165 166 func (self *SRequest) GetHost() string { 167 scheme := strings.ToLower(self.Scheme) 168 host := self.getEndpoint() 169 if len(self.Port) > 0 { 170 if (scheme == "http" && self.Port == "80") || (scheme == "https" && self.Port == "443") { 171 host = fmt.Sprintf("%s:%s", host, self.Port) 172 } 173 } 174 175 return host 176 } 177 178 func (self *SRequest) GetURI() string { 179 // URI 180 uri := "" 181 for _, m := range []string{self.version, self.projectId} { 182 if len(m) > 0 { 183 uri += fmt.Sprintf("/%s", m) 184 } 185 } 186 187 if len(self.resourcePath) > 0 { 188 s := "" 189 if !strings.HasPrefix(self.resourcePath, "/") { 190 s = "/" 191 } 192 193 if strings.HasSuffix(self.resourcePath, "/") { 194 strings.TrimSuffix(s, "/") 195 } 196 197 uri = uri + s + self.resourcePath 198 } 199 200 return uri 201 } 202 203 func (self *SRequest) getEndpoint() string { 204 // ecs.cn-north-1.myhuaweicloud.com 205 items := []string{} 206 for _, item := range []string{self.product, self.RegionId, self.Domain} { 207 if len(item) > 0 { 208 items = append(items, item) 209 } 210 } 211 212 return strings.Join(items, ".") 213 } 214 215 func (self *SRequest) BuildQueries() string { 216 self.queries = GetUrlFormedMap(self.QueryParams) 217 return self.queries 218 } 219 220 func (self *SRequest) AddHeaderParam(key, value string) { 221 self.Headers[key] = value 222 } 223 224 func (self *SRequest) AddQueryParam(key, value string) { 225 self.QueryParams[key] = value 226 } 227 228 func (self *SRequest) AddFormParam(key, value string) { 229 self.FormParams[key] = value 230 } 231 232 func GetUrlFormedMap(source map[string]string) string { 233 // 按key排序后编译 234 keys := make([]string, 0) 235 for k := range source { 236 keys = append(keys, k) 237 } 238 239 sort.Slice(keys, func(i, j int) bool { 240 return strings.ToLower(keys[i]) < strings.ToLower(keys[j]) 241 }) 242 243 urlEncoder := url.Values{} 244 for _, k := range keys { 245 urlEncoder.Add(k, source[k]) 246 } 247 248 return urlEncoder.Encode() 249 } 250 251 func defaultRequest() (request *SRequest) { 252 request = &SRequest{ 253 Scheme: "HTTPS", 254 Method: "GET", 255 QueryParams: make(map[string]string), 256 Headers: map[string]string{}, 257 FormParams: make(map[string]string), 258 } 259 return 260 } 261 262 func NewResourceRequest(domain, method, product, version, region, project, resourcePath string) *SRequest { 263 return &SRequest{ 264 Scheme: "HTTPS", 265 Method: method, 266 Domain: domain, 267 product: product, 268 RegionId: region, 269 version: version, 270 projectId: project, 271 resourcePath: resourcePath, 272 QueryParams: make(map[string]string), 273 Headers: map[string]string{}, 274 FormParams: make(map[string]string), 275 } 276 }