baseURL.go (2247B)
1 // Copyright 2018 The Hugo Authors. All rights reserved. 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 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package paths 15 16 import ( 17 "fmt" 18 "net/url" 19 "strings" 20 ) 21 22 // A BaseURL in Hugo is normally on the form scheme://path, but the 23 // form scheme: is also valid (mailto:hugo@rules.com). 24 type BaseURL struct { 25 url *url.URL 26 urlStr string 27 } 28 29 func (b BaseURL) String() string { 30 if b.urlStr != "" { 31 return b.urlStr 32 } 33 return b.url.String() 34 } 35 36 func (b BaseURL) Path() string { 37 return b.url.Path 38 } 39 40 // HostURL returns the URL to the host root without any path elements. 41 func (b BaseURL) HostURL() string { 42 return strings.TrimSuffix(b.String(), b.Path()) 43 } 44 45 // WithProtocol returns the BaseURL prefixed with the given protocol. 46 // The Protocol is normally of the form "scheme://", i.e. "webcal://". 47 func (b BaseURL) WithProtocol(protocol string) (string, error) { 48 u := b.URL() 49 50 scheme := protocol 51 isFullProtocol := strings.HasSuffix(scheme, "://") 52 isOpaqueProtocol := strings.HasSuffix(scheme, ":") 53 54 if isFullProtocol { 55 scheme = strings.TrimSuffix(scheme, "://") 56 } else if isOpaqueProtocol { 57 scheme = strings.TrimSuffix(scheme, ":") 58 } 59 60 u.Scheme = scheme 61 62 if isFullProtocol && u.Opaque != "" { 63 u.Opaque = "//" + u.Opaque 64 } else if isOpaqueProtocol && u.Opaque == "" { 65 return "", fmt.Errorf("cannot determine BaseURL for protocol %q", protocol) 66 } 67 68 return u.String(), nil 69 } 70 71 // URL returns a copy of the internal URL. 72 // The copy can be safely used and modified. 73 func (b BaseURL) URL() *url.URL { 74 c := *b.url 75 return &c 76 } 77 78 func newBaseURLFromString(b string) (BaseURL, error) { 79 var result BaseURL 80 81 base, err := url.Parse(b) 82 if err != nil { 83 return result, err 84 } 85 86 return BaseURL{url: base, urlStr: base.String()}, nil 87 }