move meta imports handler into a separate file
This commit is contained in:
parent
020b523d4a
commit
0140bf1319
53
pkg/vcs/meta.go
Normal file
53
pkg/vcs/meta.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package vcs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/xml"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MetaImports resolved module import path for certain hosts using the special <meta> tag.
|
||||||
|
func MetaImports(ctx context.Context, module string) (string, error) {
|
||||||
|
if strings.HasPrefix(module, "github.com/") || strings.HasPrefix(module, "bitbucket.org/") {
|
||||||
|
return module, nil
|
||||||
|
}
|
||||||
|
// TODO: use context
|
||||||
|
res, err := http.Get("https://" + module + "?go-get=1")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
html := struct {
|
||||||
|
HTML string `xml:"html"`
|
||||||
|
Head struct {
|
||||||
|
Meta []struct {
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
Content string `xml:"content,attr"`
|
||||||
|
} `xml:"meta"`
|
||||||
|
} `xml:"head"`
|
||||||
|
}{}
|
||||||
|
dec := xml.NewDecoder(res.Body)
|
||||||
|
dec.Strict = false
|
||||||
|
dec.AutoClose = xml.HTMLAutoClose
|
||||||
|
dec.Entity = xml.HTMLEntity
|
||||||
|
if err := dec.Decode(&html); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
for _, meta := range html.Head.Meta {
|
||||||
|
if meta.Name == "go-import" {
|
||||||
|
if f := strings.Fields(meta.Content); len(f) == 3 {
|
||||||
|
if f[0] != module {
|
||||||
|
return "", errors.New("prefix does not match the module")
|
||||||
|
}
|
||||||
|
url := f[2]
|
||||||
|
if i := strings.Index(url, "://"); i >= 0 {
|
||||||
|
url = url[i+3:]
|
||||||
|
}
|
||||||
|
return url, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", errors.New("go-import meta tag not found")
|
||||||
|
}
|
@ -2,10 +2,7 @@ package vcs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/xml"
|
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -60,47 +57,3 @@ func Password(username, password string) Auth { return Auth{Username: username,
|
|||||||
|
|
||||||
// Key returns an Auth implementation that uses key file authentication mechanism.
|
// Key returns an Auth implementation that uses key file authentication mechanism.
|
||||||
func Key(key string) Auth { return Auth{Key: key} }
|
func Key(key string) Auth { return Auth{Key: key} }
|
||||||
|
|
||||||
// MetaImports resolved module import path for certain hosts using the special <meta> tag.
|
|
||||||
func MetaImports(ctx context.Context, module string) (string, error) {
|
|
||||||
if strings.HasPrefix(module, "github.com/") || strings.HasPrefix(module, "bitbucket.org/") {
|
|
||||||
return module, nil
|
|
||||||
}
|
|
||||||
// TODO: use context
|
|
||||||
res, err := http.Get("https://" + module + "?go-get=1")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
html := struct {
|
|
||||||
HTML string `xml:"html"`
|
|
||||||
Head struct {
|
|
||||||
Meta []struct {
|
|
||||||
Name string `xml:"name,attr"`
|
|
||||||
Content string `xml:"content,attr"`
|
|
||||||
} `xml:"meta"`
|
|
||||||
} `xml:"head"`
|
|
||||||
}{}
|
|
||||||
dec := xml.NewDecoder(res.Body)
|
|
||||||
dec.Strict = false
|
|
||||||
dec.AutoClose = xml.HTMLAutoClose
|
|
||||||
dec.Entity = xml.HTMLEntity
|
|
||||||
if err := dec.Decode(&html); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
for _, meta := range html.Head.Meta {
|
|
||||||
if meta.Name == "go-import" {
|
|
||||||
if f := strings.Fields(meta.Content); len(f) == 3 {
|
|
||||||
if f[0] != module {
|
|
||||||
return "", errors.New("prefix does not match the module")
|
|
||||||
}
|
|
||||||
url := f[2]
|
|
||||||
if i := strings.Index(url, "://"); i >= 0 {
|
|
||||||
url = url[i+3:]
|
|
||||||
}
|
|
||||||
return url, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", errors.New("go-import meta tag not found")
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user