@@ -102,25 +102,77 @@ func MakeAbsoluteURL(ctx context.Context, link string) string {
102102 return GuessCurrentHostURL (ctx ) + "/" + strings .TrimPrefix (link , "/" )
103103}
104104
105- func IsCurrentGiteaSiteURL (ctx context.Context , s string ) bool {
105+ type urlType int
106+
107+ const (
108+ urlTypeGiteaAbsolute urlType = iota + 1 // "http://gitea/subpath"
109+ urlTypeGiteaPageRelative // "/subpath"
110+ urlTypeGiteaSiteRelative // "?key=val"
111+ urlTypeUnknown // "http://other"
112+ )
113+
114+ func detectURLRoutePath (ctx context.Context , s string ) (routePath string , ut urlType ) {
106115 u , err := url .Parse (s )
107116 if err != nil {
108- return false
117+ return "" , urlTypeUnknown
109118 }
119+ cleanedPath := ""
110120 if u .Path != "" {
111- cleanedPath := util .PathJoinRelX (u .Path )
112- if cleanedPath == "" || cleanedPath == "." {
113- u .Path = "/"
114- } else {
115- u .Path = "/" + cleanedPath + "/"
116- }
121+ cleanedPath = util .PathJoinRelX (u .Path )
122+ cleanedPath = util .Iif (cleanedPath == "." , "" , "/" + cleanedPath )
117123 }
118124 if urlIsRelative (s , u ) {
119- return u .Path == "" || strings .HasPrefix (strings .ToLower (u .Path ), strings .ToLower (setting .AppSubURL + "/" ))
120- }
121- if u .Path == "" {
122- u .Path = "/"
125+ if u .Path == "" {
126+ return "" , urlTypeGiteaPageRelative
127+ }
128+ if strings .HasPrefix (strings .ToLower (cleanedPath + "/" ), strings .ToLower (setting .AppSubURL + "/" )) {
129+ return cleanedPath [len (setting .AppSubURL ):], urlTypeGiteaSiteRelative
130+ }
131+ return "" , urlTypeUnknown
123132 }
133+ u .Path = cleanedPath + "/"
124134 urlLower := strings .ToLower (u .String ())
125- return strings .HasPrefix (urlLower , strings .ToLower (setting .AppURL )) || strings .HasPrefix (urlLower , strings .ToLower (GuessCurrentAppURL (ctx )))
135+ if strings .HasPrefix (urlLower , strings .ToLower (setting .AppURL )) {
136+ return cleanedPath [len (setting .AppSubURL ):], urlTypeGiteaAbsolute
137+ }
138+ guessedCurURL := GuessCurrentAppURL (ctx )
139+ if strings .HasPrefix (urlLower , strings .ToLower (guessedCurURL )) {
140+ return cleanedPath [len (setting .AppSubURL ):], urlTypeGiteaAbsolute
141+ }
142+ return "" , urlTypeUnknown
143+ }
144+
145+ func IsCurrentGiteaSiteURL (ctx context.Context , s string ) bool {
146+ _ , ut := detectURLRoutePath (ctx , s )
147+ return ut != urlTypeUnknown
148+ }
149+
150+ type GiteaSiteURL struct {
151+ RoutePath string
152+ OwnerName string
153+ RepoName string
154+ RepoSubPath string
155+ }
156+
157+ func ParseGiteaSiteURL (ctx context.Context , s string ) * GiteaSiteURL {
158+ routePath , ut := detectURLRoutePath (ctx , s )
159+ if ut == urlTypeUnknown || ut == urlTypeGiteaPageRelative {
160+ return nil
161+ }
162+ ret := & GiteaSiteURL {RoutePath : routePath }
163+ fields := strings .SplitN (strings .TrimPrefix (ret .RoutePath , "/" ), "/" , 3 )
164+
165+ // TODO: now it only does a quick check for some known reserved paths, should do more strict checks in the future
166+ if fields [0 ] == "attachments" {
167+ return ret
168+ }
169+ if len (fields ) < 2 {
170+ return ret
171+ }
172+ ret .OwnerName = fields [0 ]
173+ ret .RepoName = fields [1 ]
174+ if len (fields ) == 3 {
175+ ret .RepoSubPath = "/" + fields [2 ]
176+ }
177+ return ret
126178}
0 commit comments