code.gitea.io/gitea@v1.19.3/modules/lfs/endpoint.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package lfs
     5  
     6  import (
     7  	"net/url"
     8  	"os"
     9  	"path"
    10  	"path/filepath"
    11  	"strings"
    12  
    13  	"code.gitea.io/gitea/modules/log"
    14  	"code.gitea.io/gitea/modules/util"
    15  )
    16  
    17  // DetermineEndpoint determines an endpoint from the clone url or uses the specified LFS url.
    18  func DetermineEndpoint(cloneurl, lfsurl string) *url.URL {
    19  	if len(lfsurl) > 0 {
    20  		return endpointFromURL(lfsurl)
    21  	}
    22  	return endpointFromCloneURL(cloneurl)
    23  }
    24  
    25  func endpointFromCloneURL(rawurl string) *url.URL {
    26  	ep := endpointFromURL(rawurl)
    27  	if ep == nil {
    28  		return ep
    29  	}
    30  
    31  	ep.Path = strings.TrimSuffix(ep.Path, "/")
    32  
    33  	if ep.Scheme == "file" {
    34  		return ep
    35  	}
    36  
    37  	if path.Ext(ep.Path) == ".git" {
    38  		ep.Path += "/info/lfs"
    39  	} else {
    40  		ep.Path += ".git/info/lfs"
    41  	}
    42  
    43  	return ep
    44  }
    45  
    46  func endpointFromURL(rawurl string) *url.URL {
    47  	if strings.HasPrefix(rawurl, "/") {
    48  		return endpointFromLocalPath(rawurl)
    49  	}
    50  
    51  	u, err := url.Parse(rawurl)
    52  	if err != nil {
    53  		log.Error("lfs.endpointFromUrl: %v", err)
    54  		return nil
    55  	}
    56  
    57  	switch u.Scheme {
    58  	case "http", "https":
    59  		return u
    60  	case "git":
    61  		u.Scheme = "https"
    62  		return u
    63  	case "file":
    64  		return u
    65  	default:
    66  		if _, err := os.Stat(rawurl); err == nil {
    67  			return endpointFromLocalPath(rawurl)
    68  		}
    69  
    70  		log.Error("lfs.endpointFromUrl: unknown url")
    71  		return nil
    72  	}
    73  }
    74  
    75  func endpointFromLocalPath(path string) *url.URL {
    76  	var slash string
    77  	if abs, err := filepath.Abs(path); err == nil {
    78  		if !strings.HasPrefix(abs, "/") {
    79  			slash = "/"
    80  		}
    81  		path = abs
    82  	}
    83  
    84  	var gitpath string
    85  	if filepath.Base(path) == ".git" {
    86  		gitpath = path
    87  		path = filepath.Dir(path)
    88  	} else {
    89  		gitpath = filepath.Join(path, ".git")
    90  	}
    91  
    92  	if _, err := os.Stat(gitpath); err == nil {
    93  		path = gitpath
    94  	} else if _, err := os.Stat(path); err != nil {
    95  		return nil
    96  	}
    97  
    98  	path = "file://" + slash + util.PathEscapeSegments(filepath.ToSlash(path))
    99  
   100  	u, _ := url.Parse(path)
   101  
   102  	return u
   103  }