github.com/google/go-safeweb@v0.0.0-20231219055052-64d8cfc90fbb/safehttp/url.go (about) 1 // Copyright 2020 Google LLC 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 // https://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 safehttp 16 17 import ( 18 "net/url" 19 ) 20 21 // URL represents a parsed URL (technically, a URI reference). 22 type URL struct { 23 url *url.URL 24 } 25 26 // Query parses the query string in the URL and returns a form 27 // containing its values. The returned error describes the first 28 // decoding error encountered, if any. 29 func (u URL) Query() (Form, error) { 30 v, err := url.ParseQuery(u.url.RawQuery) 31 if err != nil { 32 return Form{}, err 33 } 34 return Form{values: map[string][]string(v)}, nil 35 } 36 37 // String reassembles the URL into a valid URL string. 38 // 39 // The method uses the net/url.EscapedPath method to obtain the path. 40 // See the net/url.EscapedPath method for more details. 41 func (u URL) String() string { 42 // The escaping is perfomed by u.url.String() 43 return u.url.String() 44 } 45 46 // Host returns the host or the host:port of the URL. 47 func (u URL) Host() string { 48 return u.url.Host 49 } 50 51 // Hostname returns the host of the URL, stripping any valid 52 // port number if present. 53 // 54 // If the result is enclosed in square brackets, as literal IPv6 55 // addresses are, the square brackets are removed from the result. 56 func (u URL) Hostname() string { 57 return u.url.Hostname() 58 } 59 60 // Port returns the port part of the URL. If the 61 // host doesn't contain a valid port number, Port returns an 62 // empty string. 63 func (u URL) Port() string { 64 return u.url.Port() 65 } 66 67 // Path returns the path of the URL. 68 // 69 // Note that the path is stored in decoded form: /%47%6f%2f 70 // becomes /Go/. A consequence is that it is impossible to tell 71 // which slashes in the path were slashes in the rawURL and which 72 // were %2f. 73 func (u URL) Path() string { 74 return u.url.Path 75 } 76 77 // ParseURL parses a raw URL string into a URL structure. 78 // 79 // The raw URl may be relative (a path, without a host) or absolute (starting 80 // with a scheme). Trying to parse a hostname and path without a scheme is 81 // invalid but may not necessarily return an error, due to parsing ambiguities. 82 func ParseURL(rawurl string) (*URL, error) { 83 parsed, err := url.Parse(rawurl) 84 if err != nil { 85 return nil, err 86 } 87 return &URL{url: parsed}, nil 88 }