github.com/cs3org/reva/v2@v2.27.7/pkg/mentix/utils/network/network.go (about) 1 // Copyright 2018-2021 CERN 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 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package network 20 21 import ( 22 "encoding/json" 23 "fmt" 24 "io" 25 "net" 26 "net/http" 27 "net/url" 28 p "path" 29 "strings" 30 ) 31 32 // URLParams holds Key-Value URL parameters; it is a simpler form of url.Values. 33 type URLParams map[string]string 34 35 // ResponseParams holds parameters of an HTTP response. 36 type ResponseParams map[string]interface{} 37 38 // BasicAuth holds user credentials for basic HTTP authentication. 39 type BasicAuth struct { 40 User string 41 Password string 42 } 43 44 // GenerateURL creates a URL object from a host, path and optional parameters. 45 func GenerateURL(host string, path string, params URLParams) (*url.URL, error) { 46 fullURL, err := url.Parse(host) 47 if err != nil { 48 return nil, fmt.Errorf("unable to generate URL: base=%v, path=%v, params=%v", host, path, params) 49 } 50 51 if len(fullURL.Scheme) == 0 { 52 fullURL.Scheme = "https" 53 } 54 55 fullURL.Path = p.Join(fullURL.Path, path) 56 57 if len(params) > 0 { 58 query := make(url.Values) 59 for key, value := range params { 60 query.Set(key, value) 61 } 62 fullURL.RawQuery = query.Encode() 63 } 64 65 return fullURL, nil 66 } 67 68 func queryEndpoint(method string, endpointURL *url.URL, auth *BasicAuth, checkStatus bool) ([]byte, error) { 69 // Prepare the request 70 req, err := http.NewRequest(method, endpointURL.String(), nil) 71 if err != nil { 72 return nil, fmt.Errorf("unable to create HTTP request: %v", err) 73 } 74 75 if auth != nil { 76 req.SetBasicAuth(auth.User, auth.Password) 77 } 78 79 // Fetch the data and read the body 80 resp, err := http.DefaultClient.Do(req) 81 if err != nil { 82 return nil, fmt.Errorf("unable to get data from endpoint: %v", err) 83 } 84 defer resp.Body.Close() 85 86 if checkStatus && resp.StatusCode >= 400 { 87 return nil, fmt.Errorf("invalid response received: %v", resp.Status) 88 } 89 90 body, _ := io.ReadAll(resp.Body) 91 return body, nil 92 } 93 94 // ReadEndpoint reads data from an HTTP endpoint via GET. 95 func ReadEndpoint(endpointURL *url.URL, auth *BasicAuth, checkStatus bool) ([]byte, error) { 96 return queryEndpoint(http.MethodGet, endpointURL, auth, checkStatus) 97 } 98 99 // WriteEndpoint sends data to an HTTP endpoint via POST. 100 func WriteEndpoint(endpointURL *url.URL, auth *BasicAuth, checkStatus bool) ([]byte, error) { 101 return queryEndpoint(http.MethodPost, endpointURL, auth, checkStatus) 102 } 103 104 // CreateResponse creates a generic HTTP response in JSON format. 105 func CreateResponse(msg string, params ResponseParams) []byte { 106 if params == nil { 107 params = make(map[string]interface{}) 108 } 109 params["message"] = msg 110 111 jsonData, _ := json.MarshalIndent(params, "", "\t") 112 return jsonData 113 } 114 115 // ExtractDomainFromURL extracts the domain name (domain.tld or subdomain.domain.tld) from a URL. 116 func ExtractDomainFromURL(hostURL *url.URL, keepSubdomain bool) string { 117 // Remove host port if present 118 host, _, err := net.SplitHostPort(hostURL.Host) 119 if err != nil { 120 host = hostURL.Host 121 } 122 123 if !keepSubdomain { 124 // Remove subdomain 125 if idx := strings.Index(host, "."); idx != -1 { 126 host = host[idx+1:] 127 } 128 } 129 130 return host 131 }