// Copyright 2019 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package util import ( "net/url" "path" "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) // PathEscapeSegments escapes segments of a path while not escaping forward slash func PathEscapeSegments(path string) string { slice := strings.Split(path, "/") for index := range slice { slice[index] = url.PathEscape(slice[index]) } escapedPath := strings.Join(slice, "/") return escapedPath } // URLJoin joins url components, like path.Join, but preserving contents func URLJoin(base string, elems ...string) string { // We do need to escape special chars here or else they can be silently discarded // in the ResolveReference call below base = PathEscapeSegments(base) if !strings.HasSuffix(base, "/") { base += "/" } baseURL, err := url.Parse(base) if err != nil { log.Error("URLJoin: Invalid base URL %s", base) return "" } joinedPath := path.Join(elems...) argURL, err := url.Parse(joinedPath) if err != nil { log.Error("URLJoin: Invalid arg %s", joinedPath) return "" } joinedURL := baseURL.ResolveReference(argURL).String() if !baseURL.IsAbs() && !strings.HasPrefix(base, "/") { return joinedURL[1:] // Removing leading '/' if needed } return joinedURL } // IsExternalURL checks if rawURL points to an external URL like http://example.com func IsExternalURL(rawURL string) bool { parsed, err := url.Parse(rawURL) if err != nil { return true } appURL, _ := url.Parse(setting.AppURL) if len(parsed.Host) != 0 && strings.Replace(parsed.Host, "www.", "", 1) != strings.Replace(appURL.Host, "www.", "", 1) { return true } return false }